From 61d5961b36cc6b3406afbd27c69da384bd56a1f6 Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sat, 13 Sep 2025 12:21:05 -0700 Subject: [PATCH 01/52] Leonardo AI components --- components/leonardo_ai/README.md | 113 +++++++++++++++++ .../actions/generate-image/generate-image.mjs | 116 ++++++++++++++++++ .../generate-motion/generate-motion.mjs | 76 ++++++++++++ .../actions/leonardo_ai_actions.mdc | 26 ++++ .../actions/unzoom-image/unzoom-image.mjs | 55 +++++++++ .../actions/upload-image/upload-image.mjs | 70 +++++++++++ .../actions/upscale-image/upscale-image.mjs | 33 +++++ components/leonardo_ai/leonardo_ai.app.mjs | 103 +++++++++++++++- components/leonardo_ai/package.json | 18 ++- 9 files changed, 605 insertions(+), 5 deletions(-) create mode 100644 components/leonardo_ai/README.md create mode 100644 components/leonardo_ai/actions/generate-image/generate-image.mjs create mode 100644 components/leonardo_ai/actions/generate-motion/generate-motion.mjs create mode 100644 components/leonardo_ai/actions/leonardo_ai_actions.mdc create mode 100644 components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs create mode 100644 components/leonardo_ai/actions/upload-image/upload-image.mjs create mode 100644 components/leonardo_ai/actions/upscale-image/upscale-image.mjs diff --git a/components/leonardo_ai/README.md b/components/leonardo_ai/README.md new file mode 100644 index 0000000000000..5443cf5ff1a06 --- /dev/null +++ b/components/leonardo_ai/README.md @@ -0,0 +1,113 @@ +# Leonardo AI + +[Leonardo AI](https://leonardo.ai) is an AI-powered image generation platform that allows you to create stunning images, videos, and 3D models using advanced machine learning models. + +## Authentication + +To use this component, you'll need to: + +1. Sign up for a Leonardo AI account at [leonardo.ai](https://leonardo.ai) +2. Navigate to the API section in your account settings +3. Create an API key +4. Use this API key when connecting the Leonardo AI app in Pipedream + +## Actions + +### Generate Image +Creates new images from text prompts using Leonardo AI's image generation models. + +**Key Features:** +- Customizable image dimensions (256x256 to 1024x1024) +- Multiple model support +- Adjustable guidance scale and inference steps +- Batch generation (1-4 images) +- Seed support for reproducible results + +### Generate Motion +Creates motion videos from static images using Leonardo AI's SVD Motion Generation. + +**Key Features:** +- Converts static images to motion videos +- Adjustable motion strength +- Seed support for reproducible results + +### Unzoom Image +Creates unzoom variations of existing images, expanding the scene beyond the original frame. + +**Key Features:** +- Zoom out effect on existing images +- Adjustable zoom level +- Works with generated or uploaded images + +### Upload Image +Uploads images to Leonardo AI for use in generations and variations. + +**Key Features:** +- Support for image URLs +- Optional image naming +- Integration with other Leonardo AI actions + +### Upscale Image +Increases the resolution of images using Leonardo AI's Universal Upscaler. + +**Key Features:** +- Multiple upscaling modes (Universal Upscaler, Real-ESRGAN) +- 2x and 4x scale factors +- High-quality image enhancement + +## Usage Examples + +### Basic Image Generation +```javascript +// Generate a simple image +{ + "prompt": "A beautiful sunset over mountains", + "width": 512, + "height": 512, + "numImages": 1 +} +``` + +### Advanced Image Generation +```javascript +// Generate with specific model and settings +{ + "prompt": "A cyberpunk cityscape at night", + "modelId": "6bef9f1b-29cb-40c7-b9df-32b51c1f67d3", + "width": 1024, + "height": 1024, + "numImages": 2, + "guidanceScale": "10", + "numInferenceSteps": 30, + "seed": 12345 +} +``` + +### Motion Generation +```javascript +// Create motion from an image +{ + "imageId": "generated-image-id-here", + "motionStrength": "0.7", + "seed": 54321 +} +``` + +## API Reference + +For detailed information about Leonardo AI's API, visit the [official documentation](https://docs.leonardo.ai/reference). + +## Rate Limits + +Leonardo AI has the following rate limits: +- Total requests: 1,000 per minute +- Image generation requests: 100 per minute +- Concurrent image generation jobs: 10 +- Concurrent model training jobs: 5 + +## Support + +For support with this component or Leonardo AI's API, please refer to: +- [Leonardo AI Documentation](https://docs.leonardo.ai) +- [Leonardo AI Community](https://community.leonardo.ai) +- [Pipedream Support](https://pipedream.com/support) diff --git a/components/leonardo_ai/actions/generate-image/generate-image.mjs b/components/leonardo_ai/actions/generate-image/generate-image.mjs new file mode 100644 index 0000000000000..4e4ab640eecf6 --- /dev/null +++ b/components/leonardo_ai/actions/generate-image/generate-image.mjs @@ -0,0 +1,116 @@ +import app from "../../leonardo_ai.app.mjs"; + +export default { + key: "leonardo_ai-generate-image", + name: "Generate Image", + description: "Generates new images using Leonardo AI's image generation API.", + version: "0.0.5", + type: "action", + props: { + app, + prompt: { + type: "string", + label: "Prompt", + description: "The text prompt describing the image you want to generate.", + }, + modelId: { + type: "string", + label: "Model", + description: "The model to use for generation. Leave empty to use the default model.", + async options() { + const models = await this.app.getPlatformModels({}); + return models.map((model) => ({ + label: model.name || model.id, + value: model.id, + })); + }, + optional: true, + }, + width: { + type: "integer", + label: "Width", + description: "Width of the generated image in pixels.", + default: 512, + min: 256, + max: 1024, + }, + height: { + type: "integer", + label: "Height", + description: "Height of the generated image in pixels.", + default: 512, + min: 256, + max: 1024, + }, + numImages: { + type: "integer", + label: "Number of Images", + description: "Number of images to generate (1-4).", + default: 1, + min: 1, + max: 4, + }, + guidanceScale: { + type: "string", + label: "Guidance Scale", + description: "How closely the model should follow the prompt. Must be between 1 and 20. Higher values = more adherence to prompt.", + optional: true, + }, + numInferenceSteps: { + type: "integer", + label: "Inference Steps", + description: "Number of denoising steps. More steps = higher quality but slower generation.", + default: 20, + min: 10, + max: 50, + optional: true, + }, + seed: { + type: "integer", + label: "Seed", + description: "Random seed for reproducible generation. Leave empty for random generation.", + optional: true, + }, + }, + async run({ $ }) { + const { + prompt, + modelId, + width, + height, + numImages, + guidanceScale, + numInferenceSteps, + seed, + } = this; + + const data = { + prompt, + width, + height, + num_images: numImages, + }; + + if (modelId) { + data.modelId = modelId; + } + if (guidanceScale) { + data.guidance_scale = parseFloat(guidanceScale); + } + if (numInferenceSteps) { + data.num_inference_steps = numInferenceSteps; + } + if (seed) { + data.seed = seed; + } + + const response = await this.app.post({ + $, + path: "/generations", + data, + }); + + $.export("$summary", `Successfully generated ${numImages} image(s) with prompt: "${prompt}"`); + return response; + }, +}; diff --git a/components/leonardo_ai/actions/generate-motion/generate-motion.mjs b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs new file mode 100644 index 0000000000000..c3bc27dbf0085 --- /dev/null +++ b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs @@ -0,0 +1,76 @@ +import app from "../../leonardo_ai.app.mjs"; + +export default { + key: "leonardo_ai-generate-motion", + name: "Generate Motion", + description: "Generates a motion (video) from the provided image using Leonardo AI's SVD Motion Generation API.", + version: "0.0.4", + type: "action", + props: { + app, + imageId: { + type: "string", + label: "Image ID", + description: "The ID of the image to generate motion from. This should be a previously generated or uploaded image ID.", + }, + motionStrength: { + type: "integer", + label: "Motion Strength", + description: "The motion strength for the video generation.", + optional: true, + }, + isPublic: { + type: "boolean", + label: "Is Public", + description: "Whether the generation is public or not.", + optional: true, + }, + isInitImage: { + type: "boolean", + label: "Is Init Image", + description: "If it is an init image uploaded by the user.", + optional: true, + }, + isVariation: { + type: "boolean", + label: "Is Variation", + description: "If it is a variation image.", + optional: true, + }, + }, + async run({ $ }) { + const { + imageId, + motionStrength, + isPublic, + isInitImage, + isVariation, + } = this; + + const data = { + imageId, + }; + + if (motionStrength !== undefined) { + data.motionStrength = motionStrength; + } + if (isPublic !== undefined) { + data.isPublic = isPublic; + } + if (isInitImage !== undefined) { + data.isInitImage = isInitImage; + } + if (isVariation !== undefined) { + data.isVariation = isVariation; + } + + const response = await this.app.post({ + $, + path: "/generations-motion-svd", + data, + }); + + $.export("$summary", `Successfully generated motion from image ID: ${imageId}`); + return response; + }, +}; diff --git a/components/leonardo_ai/actions/leonardo_ai_actions.mdc b/components/leonardo_ai/actions/leonardo_ai_actions.mdc new file mode 100644 index 0000000000000..bc133ed4f4f49 --- /dev/null +++ b/components/leonardo_ai/actions/leonardo_ai_actions.mdc @@ -0,0 +1,26 @@ +--- +alwaysApply: true +--- +leonardo-ai +URLs +https://docs.leonardo.ai/reference +Actions +generate-motion +Prompt +Generates a motion (video) from the provided image (any type). + +generate-image +Prompt +Generates new images. + +unzoom-image +Prompt +Creates an unzoom variation for a generated or variation image. + +upload-image +Prompt +Uploads a new image. + +upscale-image +Prompt +Creates a high-resolution upscale (Universal Upscaler) of the provided image (any type). \ No newline at end of file diff --git a/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs b/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs new file mode 100644 index 0000000000000..57a8c86609c99 --- /dev/null +++ b/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs @@ -0,0 +1,55 @@ +import app from "../../leonardo_ai.app.mjs"; + +export default { + key: "leonardo_ai-unzoom-image", + name: "Unzoom Image", + description: "Creates an unzoom variation for a generated or variation image using Leonardo AI's unzoom API.", + version: "0.0.1", + type: "action", + props: { + app, + imageId: { + type: "string", + label: "Image ID", + description: "The ID of the image to create an unzoom variation for. This should be a previously generated or variation image ID.", + }, + zoom: { + type: "string", + label: "Zoom Level", + description: "Zoom level for the unzoom effect. Must be between 0.0 and 1.0. Higher values create more zoom out effect.", + default: "0.5", + optional: true, + }, + seed: { + type: "integer", + label: "Seed", + description: "Random seed for reproducible generation. Leave empty for random generation.", + optional: true, + }, + }, + async run({ $ }) { + const { + imageId, + zoom, + seed, + } = this; + + const data = { + imageId, + zoom: zoom ? parseFloat(zoom) : 0.5, + }; + + if (seed) { + data.seed = seed; + } + + const response = await this.app.post({ + $, + path: "/variations/unzoom", + data, + }); + + $.export("$summary", `Successfully created unzoom variation for image ID: ${imageId}`); + return response; + }, +}; diff --git a/components/leonardo_ai/actions/upload-image/upload-image.mjs b/components/leonardo_ai/actions/upload-image/upload-image.mjs new file mode 100644 index 0000000000000..ad87016d4b28a --- /dev/null +++ b/components/leonardo_ai/actions/upload-image/upload-image.mjs @@ -0,0 +1,70 @@ +import app from "../../leonardo_ai.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "leonardo_ai-upload-image", + name: "Upload Image", + description: "Uploads a new image to Leonardo AI for use in generations and variations.", + version: "0.0.7", + type: "action", + props: { + app, + extension: { + type: "string", + label: "File Extension", + description: "The file extension of the image to upload.", + options: [ + { label: "PNG", value: "png" }, + { label: "JPG", value: "jpg" }, + { label: "JPEG", value: "jpeg" }, + { label: "WebP", value: "webp" }, + ], + }, + file: { + type: "string", + label: "File", + description: "The base64 encoded image file to upload.", + }, + }, + async run({ $ }) { + const { + extension, + file, + } = this; + console.log(extension); + // Convert base64 string to Buffer + const base64Data = file.replace(/^data:image\/[a-z]+;base64,/, ''); + const buffer = Buffer.from(base64Data, 'base64'); + + // Create a File-like object from the buffer + const fileObject = { + buffer: buffer, + name: `image.${extension}`, + type: `image/${extension === 'jpg' ? 'jpeg' : extension}`, + }; + + // Step 1: Get the presigned URL and upload fields + const uploadResponse = await this.app.getUploadInitImage({ + $, + extension, + }); + + const { uploadInitImage } = uploadResponse; + const fields = JSON.parse(uploadInitImage.fields); + const uploadUrl = uploadInitImage.url; + + // Step 2: Upload the file to the presigned URL + const uploadResult = await this.app.uploadFileToPresignedUrl({ + $, + url: uploadUrl, + fields, + file: fileObject, + }); + + $.export("$summary", `Successfully uploaded image with extension: ${extension}`); + return { + uploadInitImage, + uploadResult, + }; + }, +}; diff --git a/components/leonardo_ai/actions/upscale-image/upscale-image.mjs b/components/leonardo_ai/actions/upscale-image/upscale-image.mjs new file mode 100644 index 0000000000000..b83f10e62ba55 --- /dev/null +++ b/components/leonardo_ai/actions/upscale-image/upscale-image.mjs @@ -0,0 +1,33 @@ +import app from "../../leonardo_ai.app.mjs"; + +export default { + key: "leonardo_ai-upscale-image", + name: "Upscale Image", + description: "Creates a high-resolution upscale of the provided image using Leonardo AI's upscale API.", + version: "0.0.2", + type: "action", + props: { + app, + imageId: { + type: "string", + label: "Image ID", + description: "The ID of the image to upscale. This should be a previously generated or uploaded image ID.", + }, + }, + async run({ $ }) { + const { imageId } = this; + + const data = { + id: imageId, + }; + + const response = await this.app.post({ + $, + path: "/variations/upscale", + data, + }); + + $.export("$summary", `Successfully upscaled image ID: ${imageId}`); + return response; + }, +}; diff --git a/components/leonardo_ai/leonardo_ai.app.mjs b/components/leonardo_ai/leonardo_ai.app.mjs index 526c1b8b0d642..e2b2429fba2f0 100644 --- a/components/leonardo_ai/leonardo_ai.app.mjs +++ b/components/leonardo_ai/leonardo_ai.app.mjs @@ -1,11 +1,108 @@ +import { axios } from "@pipedream/platform"; +import FormData from "form-data" + export default { type: "app", app: "leonardo_ai", propDefinitions: {}, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://cloud.leonardo.ai/api/rest/v1"; + }, + _getHeaders() { + return { + "Content-Type": "application/json", + "Authorization": `Bearer ${this.$auth.api_key}`, + "Accept": "application/json", + }; + }, + async _makeRequest({ + $ = this, path, ...opts + }) { + return axios($, { + ...opts, + url: `${this._baseUrl()}${path}`, + headers: this._getHeaders(), + }); + }, + async post({ + $ = this, path, data, ...opts + }) { + return this._makeRequest({ + $, + path, + method: "POST", + data, + ...opts, + }); + }, + async get({ + $ = this, path, ...opts + }) { + return this._makeRequest({ + $, + path, + method: "GET", + ...opts, + }); + }, + async delete({ + $ = this, path, ...opts + }) { + return this._makeRequest({ + $, + path, + method: "DELETE", + ...opts, + }); + }, + async getPlatformModels({ $ }) { + const data = await this.get({ + $, + path: "/platformModels", + }); + return data.custom_models || []; + }, + async getUploadInitImage({ $, extension }) { + const data = await this.post({ + $, + path: "/init-image", + data: { + extension, + }, + }); + return data; + }, + async uploadFileToPresignedUrl({ $, url, fields, file }) { + const formData = new FormData(); + + // Add all the fields from the presigned URL response + Object.entries(fields).forEach(([key, value]) => { + formData.append(key, value); + }); + + // Add the file - handle both File objects and File-like objects + if (file.buffer) { + // File-like object with buffer + formData.append('file', file.buffer, { + filename: file.name, + contentType: file.type, + }); + } else { + // Regular File object + formData.append('file', file); + } + + const response = await axios($, { + url, + method: "POST", + data: formData, + headers: { + ...formData.getHeaders(), + }, + }); + + return response; }, }, }; diff --git a/components/leonardo_ai/package.json b/components/leonardo_ai/package.json index 01a75f55d3cda..ddd6ec4532780 100644 --- a/components/leonardo_ai/package.json +++ b/components/leonardo_ai/package.json @@ -1,15 +1,29 @@ { "name": "@pipedream/leonardo_ai", "version": "0.0.1", - "description": "Pipedream Leonardo AI Components", + "description": "Pipedream Leonardo AI Components - Generate images, videos, and 3D models with AI", "main": "leonardo_ai.app.mjs", "keywords": [ "pipedream", - "leonardo_ai" + "leonardo_ai", + "ai", + "image-generation", + "video-generation", + "upscaling", + "machine-learning" ], "homepage": "https://pipedream.com/apps/leonardo_ai", "author": "Pipedream (https://pipedream.com/)", + "license": "MIT", "publishConfig": { "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/PipedreamHQ/pipedream.git", + "directory": "components/leonardo_ai" + }, + "bugs": { + "url": "https://github.com/PipedreamHQ/pipedream/issues" } } \ No newline at end of file From 1f0e5b4ce16910685be9695d8065315f83a9ae02 Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sat, 13 Sep 2025 12:57:17 -0700 Subject: [PATCH 02/52] added unzoom image action --- .../actions/unzoom-image/unzoom-image.mjs | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs b/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs index 57a8c86609c99..e15588b1a223f 100644 --- a/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs +++ b/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs @@ -4,7 +4,7 @@ export default { key: "leonardo_ai-unzoom-image", name: "Unzoom Image", description: "Creates an unzoom variation for a generated or variation image using Leonardo AI's unzoom API.", - version: "0.0.1", + version: "0.0.2", type: "action", props: { app, @@ -13,36 +13,24 @@ export default { label: "Image ID", description: "The ID of the image to create an unzoom variation for. This should be a previously generated or variation image ID.", }, - zoom: { - type: "string", - label: "Zoom Level", - description: "Zoom level for the unzoom effect. Must be between 0.0 and 1.0. Higher values create more zoom out effect.", - default: "0.5", - optional: true, - }, - seed: { - type: "integer", - label: "Seed", - description: "Random seed for reproducible generation. Leave empty for random generation.", - optional: true, + isVariation: { + type: "boolean", + label: "Is Variation", + description: "Whether the image is a variation image.", + default: false, }, }, async run({ $ }) { const { imageId, - zoom, - seed, + isVariation, } = this; const data = { - imageId, - zoom: zoom ? parseFloat(zoom) : 0.5, + id: imageId, + isVariation, }; - if (seed) { - data.seed = seed; - } - const response = await this.app.post({ $, path: "/variations/unzoom", From 43c264526f2f83017a9e4ff2f3c080ef7766b914 Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sat, 13 Sep 2025 13:38:55 -0700 Subject: [PATCH 03/52] fixing link errors --- .../actions/generate-image/generate-image.mjs | 2 +- .../actions/upload-image/upload-image.mjs | 27 ++++++++++++++----- components/leonardo_ai/leonardo_ai.app.mjs | 19 ++++++++----- components/leonardo_ai/package.json | 4 +-- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/components/leonardo_ai/actions/generate-image/generate-image.mjs b/components/leonardo_ai/actions/generate-image/generate-image.mjs index 4e4ab640eecf6..91688c714c45c 100644 --- a/components/leonardo_ai/actions/generate-image/generate-image.mjs +++ b/components/leonardo_ai/actions/generate-image/generate-image.mjs @@ -36,7 +36,7 @@ export default { }, height: { type: "integer", - label: "Height", + label: "Height", description: "Height of the generated image in pixels.", default: 512, min: 256, diff --git a/components/leonardo_ai/actions/upload-image/upload-image.mjs b/components/leonardo_ai/actions/upload-image/upload-image.mjs index ad87016d4b28a..a720ced335a74 100644 --- a/components/leonardo_ai/actions/upload-image/upload-image.mjs +++ b/components/leonardo_ai/actions/upload-image/upload-image.mjs @@ -5,7 +5,7 @@ export default { key: "leonardo_ai-upload-image", name: "Upload Image", description: "Uploads a new image to Leonardo AI for use in generations and variations.", - version: "0.0.7", + version: "0.0.8", type: "action", props: { app, @@ -14,10 +14,22 @@ export default { label: "File Extension", description: "The file extension of the image to upload.", options: [ - { label: "PNG", value: "png" }, - { label: "JPG", value: "jpg" }, - { label: "JPEG", value: "jpeg" }, - { label: "WebP", value: "webp" }, + { + label: "PNG", + value: "png" + }, + { + label: "JPG", + value: "jpg" + }, + { + label: "JPEG", + value: "jpeg" + }, + { + label: "WebP", + value: "webp" + }, ], }, file: { @@ -40,7 +52,10 @@ export default { const fileObject = { buffer: buffer, name: `image.${extension}`, - type: `image/${extension === 'jpg' ? 'jpeg' : extension}`, + type: `image/${ + extension === "jpg" ? + "jpeg" : extension + }`, }; // Step 1: Get the presigned URL and upload fields diff --git a/components/leonardo_ai/leonardo_ai.app.mjs b/components/leonardo_ai/leonardo_ai.app.mjs index e2b2429fba2f0..a95f917d5a18f 100644 --- a/components/leonardo_ai/leonardo_ai.app.mjs +++ b/components/leonardo_ai/leonardo_ai.app.mjs @@ -1,5 +1,5 @@ import { axios } from "@pipedream/platform"; -import FormData from "form-data" +import FormData from "form-data"; export default { type: "app", @@ -63,7 +63,9 @@ export default { }); return data.custom_models || []; }, - async getUploadInitImage({ $, extension }) { + async getUploadInitImage({ + $, extension + }) { const data = await this.post({ $, path: "/init-image", @@ -73,24 +75,29 @@ export default { }); return data; }, - async uploadFileToPresignedUrl({ $, url, fields, file }) { + async uploadFileToPresignedUrl({ + $, url, fields, file + }) { const formData = new FormData(); // Add all the fields from the presigned URL response - Object.entries(fields).forEach(([key, value]) => { + Object.entries(fields).forEach(([ + key, + value + ]) => { formData.append(key, value); }); // Add the file - handle both File objects and File-like objects if (file.buffer) { // File-like object with buffer - formData.append('file', file.buffer, { + formData.append("file", file.buffer, { filename: file.name, contentType: file.type, }); } else { // Regular File object - formData.append('file', file); + formData.append("file", file); } const response = await axios($, { diff --git a/components/leonardo_ai/package.json b/components/leonardo_ai/package.json index ddd6ec4532780..98a8f1f402537 100644 --- a/components/leonardo_ai/package.json +++ b/components/leonardo_ai/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/leonardo_ai", - "version": "0.0.1", + "version": "0.0.2", "description": "Pipedream Leonardo AI Components - Generate images, videos, and 3D models with AI", "main": "leonardo_ai.app.mjs", "keywords": [ @@ -26,4 +26,4 @@ "bugs": { "url": "https://github.com/PipedreamHQ/pipedream/issues" } -} \ No newline at end of file +} From 185b2cd23e410dd71a97c19ca527ed9cd19cdb4f Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sat, 13 Sep 2025 13:53:28 -0700 Subject: [PATCH 04/52] more lint fixes --- .../actions/upload-image/upload-image.mjs | 20 +++++++++---------- components/leonardo_ai/leonardo_ai.app.mjs | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/components/leonardo_ai/actions/upload-image/upload-image.mjs b/components/leonardo_ai/actions/upload-image/upload-image.mjs index a720ced335a74..6edc7e98db2a9 100644 --- a/components/leonardo_ai/actions/upload-image/upload-image.mjs +++ b/components/leonardo_ai/actions/upload-image/upload-image.mjs @@ -1,11 +1,10 @@ import app from "../../leonardo_ai.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "leonardo_ai-upload-image", name: "Upload Image", description: "Uploads a new image to Leonardo AI for use in generations and variations.", - version: "0.0.8", + version: "0.0.9", type: "action", props: { app, @@ -16,19 +15,19 @@ export default { options: [ { label: "PNG", - value: "png" + value: "png", }, { label: "JPG", - value: "jpg" + value: "jpg", }, { label: "JPEG", - value: "jpeg" + value: "jpeg", }, { label: "WebP", - value: "webp" + value: "webp", }, ], }, @@ -45,16 +44,17 @@ export default { } = this; console.log(extension); // Convert base64 string to Buffer - const base64Data = file.replace(/^data:image\/[a-z]+;base64,/, ''); - const buffer = Buffer.from(base64Data, 'base64'); + const base64Data = file.replace(/^data:image\/[a-z]+;base64,/, ""); + const buffer = Buffer.from(base64Data, "base64"); // Create a File-like object from the buffer const fileObject = { buffer: buffer, name: `image.${extension}`, type: `image/${ - extension === "jpg" ? - "jpeg" : extension + extension === "jpg" ? + "jpeg" + : extension }`, }; diff --git a/components/leonardo_ai/leonardo_ai.app.mjs b/components/leonardo_ai/leonardo_ai.app.mjs index a95f917d5a18f..39f03a7eb45e8 100644 --- a/components/leonardo_ai/leonardo_ai.app.mjs +++ b/components/leonardo_ai/leonardo_ai.app.mjs @@ -64,7 +64,7 @@ export default { return data.custom_models || []; }, async getUploadInitImage({ - $, extension + $, extension, }) { const data = await this.post({ $, @@ -76,14 +76,14 @@ export default { return data; }, async uploadFileToPresignedUrl({ - $, url, fields, file + $, url, fields, file, }) { const formData = new FormData(); // Add all the fields from the presigned URL response Object.entries(fields).forEach(([ key, - value + value, ]) => { formData.append(key, value); }); From b52e6afe0a04fc371d2f5dd2314e8454f622b745 Mon Sep 17 00:00:00 2001 From: jocarino <45713006+jocarino@users.noreply.github.com> Date: Sun, 14 Sep 2025 15:02:09 +0100 Subject: [PATCH 05/52] Merging pull request #18359 * fix: pagination prop and params struct * fix: no need for paginate here * chore: update version * chore: cleanup * chore: update package * feat: allow raw response * chore: bump package * fix: buffer response instead * Update components/google_drive/actions/download-file/download-file.mjs Co-authored-by: Jorge Cortes * versions * pnpm-lock.yaml * pnpm-lock.yaml * pnpm-lock.yaml * feat: add content selector * chore: bump package * fix: comments * chore: bump versions * chore: fix versions * fixes: QA fixes * feat: add cursor to req * package.json --------- Co-authored-by: joao Co-authored-by: joaocoform Co-authored-by: Jorge Cortes Co-authored-by: Michelle Bergeron Co-authored-by: Luan Cazarine --- components/gong/actions/list-calls/list-calls.mjs | 14 ++++++++++++-- components/gong/package.json | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/components/gong/actions/list-calls/list-calls.mjs b/components/gong/actions/list-calls/list-calls.mjs index 544547add7ab4..d72b67a8f2dfa 100644 --- a/components/gong/actions/list-calls/list-calls.mjs +++ b/components/gong/actions/list-calls/list-calls.mjs @@ -5,7 +5,7 @@ export default { name: "List calls", description: "List calls. [See the documentation](https://us-66463.app.gong.io/settings/api/documentation#get-/v2/calls)", type: "action", - version: "0.0.3", + version: "0.0.4", props: { app, fromDateTime: { @@ -22,16 +22,26 @@ export default { "toDateTime", ], }, + cursor: { + optional: true, + type: "string", + label: "Cursor", + description: "The cursor to start from. This is returned by the previous step", + }, }, run({ $: step }) { const { app, + cursor, ...params } = this; return app.listCalls({ step, - params, + params: { + ...params, + cursor, + }, summary: (response) => `Successfully listed calls with request ID \`${response.requestId}\``, }); }, diff --git a/components/gong/package.json b/components/gong/package.json index 1c039a6a039ef..e35e1d3e7b62d 100644 --- a/components/gong/package.json +++ b/components/gong/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/gong", - "version": "0.3.0", + "version": "0.3.1", "description": "Pipedream Gong Components", "main": "gong.app.mjs", "keywords": [ From 768d13e227d60d27d95f8d3a3c1d5cb91f7ca1d8 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Sun, 14 Sep 2025 10:40:42 -0400 Subject: [PATCH 06/52] Merging pull request #18361 * update siteId prop * pnpm-lock.yaml * package.json version --- components/sharepoint/actions/create-item/create-item.mjs | 2 +- components/sharepoint/actions/create-list/create-list.mjs | 2 +- .../sharepoint/actions/download-file/download-file.mjs | 2 +- components/sharepoint/actions/update-item/update-item.mjs | 2 +- components/sharepoint/package.json | 4 ++-- components/sharepoint/sharepoint.app.mjs | 8 +++++++- .../sharepoint/sources/new-list-item/new-list-item.mjs | 2 +- .../sources/updated-list-item/updated-list-item.mjs | 2 +- pnpm-lock.yaml | 7 +++---- 9 files changed, 18 insertions(+), 13 deletions(-) diff --git a/components/sharepoint/actions/create-item/create-item.mjs b/components/sharepoint/actions/create-item/create-item.mjs index 84147ada0fd93..21eededd8e4d4 100644 --- a/components/sharepoint/actions/create-item/create-item.mjs +++ b/components/sharepoint/actions/create-item/create-item.mjs @@ -4,7 +4,7 @@ export default { key: "sharepoint-create-item", name: "Create Item", description: "Create a new item in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/listitem-create?view=graph-rest-1.0&tabs=http)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { sharepoint, diff --git a/components/sharepoint/actions/create-list/create-list.mjs b/components/sharepoint/actions/create-list/create-list.mjs index 942af88c4109a..e3e7f150ed835 100644 --- a/components/sharepoint/actions/create-list/create-list.mjs +++ b/components/sharepoint/actions/create-list/create-list.mjs @@ -4,7 +4,7 @@ export default { key: "sharepoint-create-list", name: "Create List", description: "Create a new list in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/list-create?view=graph-rest-1.0&tabs=http)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { sharepoint, diff --git a/components/sharepoint/actions/download-file/download-file.mjs b/components/sharepoint/actions/download-file/download-file.mjs index 2b67bc6d9524b..b7f5dddb3ac9b 100644 --- a/components/sharepoint/actions/download-file/download-file.mjs +++ b/components/sharepoint/actions/download-file/download-file.mjs @@ -5,7 +5,7 @@ export default { key: "sharepoint-download-file", name: "Download File", description: "Download a Microsoft Sharepoint file to the /tmp directory. [See the documentation](https://learn.microsoft.com/en-us/graph/api/driveitem-get-content?view=graph-rest-1.0&tabs=http)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { sharepoint, diff --git a/components/sharepoint/actions/update-item/update-item.mjs b/components/sharepoint/actions/update-item/update-item.mjs index cecf4f5760e97..b8f9fec433274 100644 --- a/components/sharepoint/actions/update-item/update-item.mjs +++ b/components/sharepoint/actions/update-item/update-item.mjs @@ -5,7 +5,7 @@ export default { key: "sharepoint-update-item", name: "Update Item", description: "Updates an existing item in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/listitem-update?view=graph-rest-1.0&tabs=http)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { sharepoint, diff --git a/components/sharepoint/package.json b/components/sharepoint/package.json index 39a90da29e345..cee3c0e76b0ee 100644 --- a/components/sharepoint/package.json +++ b/components/sharepoint/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/sharepoint", - "version": "0.3.2", + "version": "0.3.3", "description": "Pipedream Microsoft Sharepoint Online Components", "main": "sharepoint.app.mjs", "keywords": [ @@ -13,6 +13,6 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^3.0.3" + "@pipedream/platform": "^3.1.0" } } diff --git a/components/sharepoint/sharepoint.app.mjs b/components/sharepoint/sharepoint.app.mjs index ee21c3dbea21b..5c32d3d2963ac 100644 --- a/components/sharepoint/sharepoint.app.mjs +++ b/components/sharepoint/sharepoint.app.mjs @@ -14,7 +14,7 @@ export default { url: prevContext.nextLink, } : {}; - const response = await this.listSites(args); + const response = await this.listAllSites(args); const options = response.value?.map(({ id: value, displayName: label, }) => ({ @@ -205,6 +205,12 @@ export default { ...args, }); }, + listAllSites(args = {}) { + return this._makeRequest({ + path: "/sites?search=*", + ...args, + }); + }, listLists({ siteId, ...args }) { diff --git a/components/sharepoint/sources/new-list-item/new-list-item.mjs b/components/sharepoint/sources/new-list-item/new-list-item.mjs index 4e7a2b57a3175..08ed675b2f542 100644 --- a/components/sharepoint/sources/new-list-item/new-list-item.mjs +++ b/components/sharepoint/sources/new-list-item/new-list-item.mjs @@ -5,7 +5,7 @@ export default { key: "sharepoint-new-list-item", name: "New List Item", description: "Emit new event when a new list is created in Microsoft Sharepoint.", - version: "0.0.4", + version: "0.0.5", type: "source", dedupe: "unique", props: { diff --git a/components/sharepoint/sources/updated-list-item/updated-list-item.mjs b/components/sharepoint/sources/updated-list-item/updated-list-item.mjs index 9fd8d17b9a2f4..fb98c624e5549 100644 --- a/components/sharepoint/sources/updated-list-item/updated-list-item.mjs +++ b/components/sharepoint/sources/updated-list-item/updated-list-item.mjs @@ -5,7 +5,7 @@ export default { key: "sharepoint-updated-list-item", name: "Updated List Item", description: "Emit new event when a list is updated in Microsoft Sharepoint.", - version: "0.0.4", + version: "0.0.5", type: "source", dedupe: "unique", props: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 382c2f2009775..5c0819068c83d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12880,8 +12880,8 @@ importers: components/sharepoint: dependencies: '@pipedream/platform': - specifier: ^3.0.3 - version: 3.0.3 + specifier: ^3.1.0 + version: 3.1.0 components/sharpspring: dependencies: @@ -14480,8 +14480,7 @@ importers: components/timely_time_tracking: {} - components/timescaledb: - specifiers: {} + components/timescaledb: {} components/timetonic: dependencies: From cab79a5e7e76142b077b689de49b8c0633776b78 Mon Sep 17 00:00:00 2001 From: Andrew Chuang Date: Mon, 15 Sep 2025 12:09:50 -0400 Subject: [PATCH 07/52] Google Sheets - update row refresh fields (#18369) * change prop order and refresh fields * bump package.json --- .../actions/update-row/update-row.mjs | 14 ++++++++++---- components/google_sheets/package.json | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/components/google_sheets/actions/update-row/update-row.mjs b/components/google_sheets/actions/update-row/update-row.mjs index 492bd3b9844e6..36330cccc3f9d 100644 --- a/components/google_sheets/actions/update-row/update-row.mjs +++ b/components/google_sheets/actions/update-row/update-row.mjs @@ -10,7 +10,7 @@ export default { key: "google_sheets-update-row", name: "Update Row", description: "Update a row in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update)", - version: "0.1.13", + version: "0.1.14", type: "action", props: { googleSheets, @@ -55,13 +55,15 @@ export default { }, reloadProps: true, }, + hasHeaders: common.props.hasHeaders, row: { propDefinition: [ googleSheets, "row", ], + min: 1, + reloadProps: true, }, - hasHeaders: common.props.hasHeaders, }, async additionalProps() { const { @@ -83,7 +85,7 @@ export default { } const props = {}; - if (hasHeaders && row) { + if (hasHeaders) { try { const worksheet = await this.getWorksheetById(sheetId, worksheetId); const { values } = await this.googleSheets.getSpreadsheetValues(sheetId, `${worksheet?.properties?.title}!1:1`); @@ -92,7 +94,7 @@ export default { throw new ConfigurationError("Could not find a header row. Please either add headers and click \"Refresh fields\" or set 'Does the first row of the sheet have headers?' to false."); } - const { values: rowValues } = !isNaN(row) + const { values: rowValues } = (!isNaN(row) && row > 0) ? await this.googleSheets.getSpreadsheetValues(sheetId, `${worksheet?.properties?.title}!${row}:${row}`) : {}; @@ -162,6 +164,10 @@ export default { cells = this.googleSheets.sanitizedArray(this.myColumnData); } + if (isNaN(row) || row < 1) { + throw new ConfigurationError("Please enter a valid row number in `Row Number`."); + } + // validate input if (!cells || !cells.length) { throw new ConfigurationError("Please enter an array of elements in `Row Values`."); diff --git a/components/google_sheets/package.json b/components/google_sheets/package.json index d19b2c8738d93..6ea2b0e9f3d36 100644 --- a/components/google_sheets/package.json +++ b/components/google_sheets/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/google_sheets", - "version": "0.8.9", + "version": "0.8.10", "description": "Pipedream Google_sheets Components", "main": "google_sheets.app.mjs", "keywords": [ From ab578e6f757532121e186de331bcc8ed47a54ccd Mon Sep 17 00:00:00 2001 From: Andrew Chuang Date: Mon, 15 Sep 2025 15:12:33 -0400 Subject: [PATCH 08/52] Pipedrive - fix app name (#18370) * use pipedriveApp instead of app * bump package.json --- .../pipedrive/actions/add-deal/add-deal.mjs | 54 +++++++++---------- components/pipedrive/package.json | 2 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/components/pipedrive/actions/add-deal/add-deal.mjs b/components/pipedrive/actions/add-deal/add-deal.mjs index 744ec15550bd0..ef9b645ff8147 100644 --- a/components/pipedrive/actions/add-deal/add-deal.mjs +++ b/components/pipedrive/actions/add-deal/add-deal.mjs @@ -1,139 +1,139 @@ import { ConfigurationError } from "@pipedream/platform"; -import app from "../../pipedrive.app.mjs"; +import pipedriveApp from "../../pipedrive.app.mjs"; import { parseObject } from "../../common/utils.mjs"; export default { key: "pipedrive-add-deal", name: "Add Deal", description: "Adds a new deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#addDeal)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { - app, + pipedriveApp, title: { propDefinition: [ - app, + pipedriveApp, "dealTitle", ], }, ownerId: { propDefinition: [ - app, + pipedriveApp, "userId", ], }, personId: { propDefinition: [ - app, + pipedriveApp, "personId", ], }, orgId: { propDefinition: [ - app, + pipedriveApp, "organizationId", ], }, pipelineId: { propDefinition: [ - app, + pipedriveApp, "pipelineId", ], optional: true, }, stageId: { propDefinition: [ - app, + pipedriveApp, "stageId", ], }, value: { propDefinition: [ - app, + pipedriveApp, "dealValue", ], }, currency: { propDefinition: [ - app, + pipedriveApp, "dealCurrency", ], }, status: { propDefinition: [ - app, + pipedriveApp, "status", ], }, probability: { propDefinition: [ - app, + pipedriveApp, "probability", ], }, lostReason: { propDefinition: [ - app, + pipedriveApp, "lostReason", ], }, visibleTo: { propDefinition: [ - app, + pipedriveApp, "visibleTo", ], }, isDeleted: { propDefinition: [ - app, + pipedriveApp, "isDeleted", ], }, isArchived: { propDefinition: [ - app, + pipedriveApp, "isArchived", ], }, archiveTime: { propDefinition: [ - app, + pipedriveApp, "archiveTime", ], }, closeTime: { propDefinition: [ - app, + pipedriveApp, "closeTime", ], }, wonTime: { propDefinition: [ - app, + pipedriveApp, "wonTime", ], }, lostTime: { propDefinition: [ - app, + pipedriveApp, "lostTime", ], }, expectedCloseDate: { propDefinition: [ - app, + pipedriveApp, "expectedCloseDate", ], }, labelIds: { propDefinition: [ - app, + pipedriveApp, "labelIds", ], }, customFields: { propDefinition: [ - app, + pipedriveApp, "customFields", ], }, @@ -146,7 +146,7 @@ export default { }, async run({ $ }) { const { - app, + pipedriveApp, title, ownerId, personId, @@ -172,7 +172,7 @@ export default { } = this; try { - const resp = await app.addDeal({ + const resp = await pipedriveApp.addDeal({ title, owner_id: ownerId, person_id: personId, @@ -197,7 +197,7 @@ export default { }); if (note) { - await app.addNote({ + await pipedriveApp.addNote({ content: note, deal_id: resp.data?.id, }); diff --git a/components/pipedrive/package.json b/components/pipedrive/package.json index 968bdf3e3e773..6c639e4971ade 100644 --- a/components/pipedrive/package.json +++ b/components/pipedrive/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/pipedrive", - "version": "0.10.1", + "version": "0.10.2", "description": "Pipedream Pipedrive Components", "main": "pipedrive.app.mjs", "keywords": [ From 47cc79a80f2a35f656c679a6edc642c14e4d7b00 Mon Sep 17 00:00:00 2001 From: Andrew Chuang Date: Mon, 15 Sep 2025 16:48:52 -0400 Subject: [PATCH 09/52] Pipedrive - pipelineId integer (#18372) * pipelineId - integer * bump versions --- components/pipedrive/actions/add-activity/add-activity.mjs | 2 +- components/pipedrive/actions/add-deal/add-deal.mjs | 2 +- components/pipedrive/actions/add-lead/add-lead.mjs | 2 +- components/pipedrive/actions/add-note/add-note.mjs | 2 +- .../pipedrive/actions/add-organization/add-organization.mjs | 2 +- components/pipedrive/actions/add-person/add-person.mjs | 2 +- components/pipedrive/actions/get-lead-by-id/get-lead-by-id.mjs | 2 +- .../pipedrive/actions/get-person-details/get-person-details.mjs | 2 +- components/pipedrive/actions/merge-deals/merge-deals.mjs | 2 +- components/pipedrive/actions/merge-persons/merge-persons.mjs | 2 +- .../actions/remove-duplicate-notes/remove-duplicate-notes.mjs | 2 +- components/pipedrive/actions/search-leads/search-leads.mjs | 2 +- components/pipedrive/actions/search-notes/search-notes.mjs | 2 +- components/pipedrive/actions/search-persons/search-persons.mjs | 2 +- components/pipedrive/actions/update-deal/update-deal.mjs | 2 +- components/pipedrive/actions/update-person/update-person.mjs | 2 +- components/pipedrive/package.json | 2 +- components/pipedrive/pipedrive.app.mjs | 2 +- .../pipedrive/sources/new-deal-instant/new-deal-instant.mjs | 2 +- .../pipedrive/sources/new-event-instant/new-event-instant.mjs | 2 +- .../pipedrive/sources/new-person-instant/new-person-instant.mjs | 2 +- .../sources/updated-deal-instant/updated-deal-instant.mjs | 2 +- .../sources/updated-lead-instant/updated-lead-instant.mjs | 2 +- .../sources/updated-person-instant/updated-person-instant.mjs | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/components/pipedrive/actions/add-activity/add-activity.mjs b/components/pipedrive/actions/add-activity/add-activity.mjs index 1ee9eaffa214a..e612857112cb4 100644 --- a/components/pipedrive/actions/add-activity/add-activity.mjs +++ b/components/pipedrive/actions/add-activity/add-activity.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-add-activity", name: "Add Activity", description: "Adds a new activity. Includes `more_activities_scheduled_in_context` property in response's `additional_data` which indicates whether there are more undone activities scheduled with the same deal, person or organization (depending on the supplied data). See the Pipedrive API docs for Activities [here](https://developers.pipedrive.com/docs/api/v1/#!/Activities). For info on [adding an activity in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Activities#addActivity)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-deal/add-deal.mjs b/components/pipedrive/actions/add-deal/add-deal.mjs index ef9b645ff8147..999ec55c94c9c 100644 --- a/components/pipedrive/actions/add-deal/add-deal.mjs +++ b/components/pipedrive/actions/add-deal/add-deal.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-add-deal", name: "Add Deal", description: "Adds a new deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#addDeal)", - version: "0.1.15", + version: "0.1.16", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-lead/add-lead.mjs b/components/pipedrive/actions/add-lead/add-lead.mjs index d0f9348cb1f30..535e658673ed9 100644 --- a/components/pipedrive/actions/add-lead/add-lead.mjs +++ b/components/pipedrive/actions/add-lead/add-lead.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-add-lead", name: "Add Lead", description: "Create a new lead in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Leads#addLead)", - version: "0.0.8", + version: "0.0.9", type: "action", props: { pipedrive, diff --git a/components/pipedrive/actions/add-note/add-note.mjs b/components/pipedrive/actions/add-note/add-note.mjs index d5bb93ab938b4..e79af3c4e07c7 100644 --- a/components/pipedrive/actions/add-note/add-note.mjs +++ b/components/pipedrive/actions/add-note/add-note.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-note", name: "Add Note", description: "Adds a new note. For info on [adding an note in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Notes#addNote)", - version: "0.0.12", + version: "0.0.13", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-organization/add-organization.mjs b/components/pipedrive/actions/add-organization/add-organization.mjs index 8e0091b23e1bc..471793318563c 100644 --- a/components/pipedrive/actions/add-organization/add-organization.mjs +++ b/components/pipedrive/actions/add-organization/add-organization.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-organization", name: "Add Organization", description: "Adds a new organization. See the Pipedrive API docs for Organizations [here](https://developers.pipedrive.com/docs/api/v1/Organizations#addOrganization)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-person/add-person.mjs b/components/pipedrive/actions/add-person/add-person.mjs index 3685d6df1d7e1..ed8101ab8fb31 100644 --- a/components/pipedrive/actions/add-person/add-person.mjs +++ b/components/pipedrive/actions/add-person/add-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-add-person", name: "Add Person", description: "Adds a new person. See the Pipedrive API docs for People [here](https://developers.pipedrive.com/docs/api/v1/Persons#addPerson)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/get-lead-by-id/get-lead-by-id.mjs b/components/pipedrive/actions/get-lead-by-id/get-lead-by-id.mjs index e6b0b72aa2b90..a80d8b39dff54 100644 --- a/components/pipedrive/actions/get-lead-by-id/get-lead-by-id.mjs +++ b/components/pipedrive/actions/get-lead-by-id/get-lead-by-id.mjs @@ -4,7 +4,7 @@ export default { key: "pipedrive-get-lead-by-id", name: "Get Lead by ID", description: "Get a lead by its ID. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Leads#getLead)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/get-person-details/get-person-details.mjs b/components/pipedrive/actions/get-person-details/get-person-details.mjs index 3c8ce0fdc824e..fe18598cb42ef 100644 --- a/components/pipedrive/actions/get-person-details/get-person-details.mjs +++ b/components/pipedrive/actions/get-person-details/get-person-details.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-get-person-details", name: "Get person details", description: "Get details of a person by their ID. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Persons#getPerson)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/merge-deals/merge-deals.mjs b/components/pipedrive/actions/merge-deals/merge-deals.mjs index 48cea5a78183b..5723fe590e2dc 100644 --- a/components/pipedrive/actions/merge-deals/merge-deals.mjs +++ b/components/pipedrive/actions/merge-deals/merge-deals.mjs @@ -4,7 +4,7 @@ export default { key: "pipedrive-merge-deals", name: "Merge Deals", description: "Merge two deals in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Deals#mergeDeals)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/merge-persons/merge-persons.mjs b/components/pipedrive/actions/merge-persons/merge-persons.mjs index 4f88364b97b9d..daa6b89616117 100644 --- a/components/pipedrive/actions/merge-persons/merge-persons.mjs +++ b/components/pipedrive/actions/merge-persons/merge-persons.mjs @@ -4,7 +4,7 @@ export default { key: "pipedrive-merge-persons", name: "Merge Persons", description: "Merge two persons in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Persons#mergePersons)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs index deaae5d765252..c886c6afb6a6e 100644 --- a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-remove-duplicate-notes", name: "Remove Duplicate Notes", description: "Remove duplicate notes from an object in Pipedrive. See the documentation for [getting notes](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes) and [deleting notes](https://developers.pipedrive.com/docs/api/v1/Notes#deleteNote)", - version: "0.0.5", + version: "0.0.6", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/search-leads/search-leads.mjs b/components/pipedrive/actions/search-leads/search-leads.mjs index bd8c477a80249..2c2685506c688 100644 --- a/components/pipedrive/actions/search-leads/search-leads.mjs +++ b/components/pipedrive/actions/search-leads/search-leads.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-search-leads", name: "Search Leads", description: "Search for leads by name or email. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Leads#searchLeads)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/search-notes/search-notes.mjs b/components/pipedrive/actions/search-notes/search-notes.mjs index 7499eded06d11..4998cfb85c719 100644 --- a/components/pipedrive/actions/search-notes/search-notes.mjs +++ b/components/pipedrive/actions/search-notes/search-notes.mjs @@ -4,7 +4,7 @@ export default { key: "pipedrive-search-notes", name: "Search Notes", description: "Search for notes in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes)", - version: "0.0.5", + version: "0.0.6", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/search-persons/search-persons.mjs b/components/pipedrive/actions/search-persons/search-persons.mjs index beaf0a68e426f..88fb9989b7835 100644 --- a/components/pipedrive/actions/search-persons/search-persons.mjs +++ b/components/pipedrive/actions/search-persons/search-persons.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-search-persons", name: "Search persons", description: "Searches all Persons by `name`, `email`, `phone`, `notes` and/or custom fields. This endpoint is a wrapper of `/v1/itemSearch` with a narrower OAuth scope. Found Persons can be filtered by Organization ID. See the Pipedrive API docs [here](https://developers.pipedrive.com/docs/api/v1/Persons#searchPersons)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-deal/update-deal.mjs b/components/pipedrive/actions/update-deal/update-deal.mjs index ce579d5bbf1ba..807fb354f34d8 100644 --- a/components/pipedrive/actions/update-deal/update-deal.mjs +++ b/components/pipedrive/actions/update-deal/update-deal.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-update-deal", name: "Update Deal", description: "Updates the properties of a deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#updateDeal)", - version: "0.1.16", + version: "0.1.17", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-person/update-person.mjs b/components/pipedrive/actions/update-person/update-person.mjs index 20cdf28213169..9e0fa7102b2ce 100644 --- a/components/pipedrive/actions/update-person/update-person.mjs +++ b/components/pipedrive/actions/update-person/update-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-update-person", name: "Update Person", description: "Updates an existing person in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Persons#updatePerson)", - version: "0.0.6", + version: "0.0.7", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/package.json b/components/pipedrive/package.json index 6c639e4971ade..f564d08b23cc2 100644 --- a/components/pipedrive/package.json +++ b/components/pipedrive/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/pipedrive", - "version": "0.10.2", + "version": "0.10.3", "description": "Pipedream Pipedrive Components", "main": "pipedrive.app.mjs", "keywords": [ diff --git a/components/pipedrive/pipedrive.app.mjs b/components/pipedrive/pipedrive.app.mjs index a1c32ef01eb52..622a4ef38e537 100644 --- a/components/pipedrive/pipedrive.app.mjs +++ b/components/pipedrive/pipedrive.app.mjs @@ -189,7 +189,7 @@ export default { }, }, pipelineId: { - type: "string", + type: "integer", label: "Pipeline ID", description: "ID of the pipeline this activity will be associated with", optional: true, diff --git a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs index 0579b0a287716..dfc87a1d2a3ab 100644 --- a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs +++ b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-deal-instant", name: "New Deal (Instant)", description: "Emit new event when a new deal is created.", - version: "0.0.11", + version: "0.0.12", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/new-event-instant/new-event-instant.mjs b/components/pipedrive/sources/new-event-instant/new-event-instant.mjs index 524e3aea4aa4d..cf85df502e321 100644 --- a/components/pipedrive/sources/new-event-instant/new-event-instant.mjs +++ b/components/pipedrive/sources/new-event-instant/new-event-instant.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-new-event-instant", name: "New Event (Instant)", description: "Emit new event when a new webhook event is received. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Webhooks#addWebhook)", - version: "0.0.2", + version: "0.0.3", type: "source", dedupe: "unique", props: { diff --git a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs index 884570662d55a..33f4d0713d0cb 100644 --- a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs +++ b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-person-instant", name: "New Person (Instant)", description: "Emit new event when a new person is created.", - version: "0.0.11", + version: "0.0.12", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs index 07a7972a7598a..9e394366f74e0 100644 --- a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs +++ b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-updated-deal-instant", name: "Deal Updated (Instant)", description: "Emit new event when a deal is updated.", - version: "0.1.4", + version: "0.1.5", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs b/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs index 4d3a7b83836f4..5a83bf19aafdb 100644 --- a/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs +++ b/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-updated-lead-instant", name: "Lead Updated (Instant)", description: "Emit new event when a lead is updated.", - version: "0.1.4", + version: "0.1.5", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs index 9347d83289136..a22c4cb4923fb 100644 --- a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs +++ b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-updated-person-instant", name: "Person Updated (Instant)", description: "Emit new event when a person is updated.", - version: "0.1.4", + version: "0.1.5", type: "source", dedupe: "unique", methods: { From 39af3b6a60f1bd3c376644dd32e7a3f9a04db688 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:33:09 -0700 Subject: [PATCH 10/52] Adding app scaffolding for lightspeed_ecom_c_series --- .../lightspeed_ecom_c_series.app.mjs | 11 +++++++++++ components/lightspeed_ecom_c_series/package.json | 15 +++++++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs create mode 100644 components/lightspeed_ecom_c_series/package.json diff --git a/components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs b/components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs new file mode 100644 index 0000000000000..741ab63c52762 --- /dev/null +++ b/components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "lightspeed_ecom_c_series", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/components/lightspeed_ecom_c_series/package.json b/components/lightspeed_ecom_c_series/package.json new file mode 100644 index 0000000000000..135da331e376f --- /dev/null +++ b/components/lightspeed_ecom_c_series/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/lightspeed_ecom_c_series", + "version": "0.0.1", + "description": "Pipedream Lightspeed eCom (C-Series) Components", + "main": "lightspeed_ecom_c_series.app.mjs", + "keywords": [ + "pipedream", + "lightspeed_ecom_c_series" + ], + "homepage": "https://pipedream.com/apps/lightspeed_ecom_c_series", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c0819068c83d..71c7066ef7ec6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7911,6 +7911,9 @@ importers: components/lightpanda: {} + components/lightspeed_ecom_c_series: + specifiers: {} + components/lightspeed_retail_pos: dependencies: '@pipedream/platform': From 53176bc863fd453364b17260281af4cf9c5927ae Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:33:11 -0700 Subject: [PATCH 11/52] Adding app scaffolding for financial_data --- components/financial_data/financial_data.app.mjs | 11 +++++++++++ components/financial_data/package.json | 15 +++++++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/financial_data/financial_data.app.mjs create mode 100644 components/financial_data/package.json diff --git a/components/financial_data/financial_data.app.mjs b/components/financial_data/financial_data.app.mjs new file mode 100644 index 0000000000000..2ebd5e4c145d8 --- /dev/null +++ b/components/financial_data/financial_data.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "financial_data", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/components/financial_data/package.json b/components/financial_data/package.json new file mode 100644 index 0000000000000..b64ce7970379f --- /dev/null +++ b/components/financial_data/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/financial_data", + "version": "0.0.1", + "description": "Pipedream Financial Data Components", + "main": "financial_data.app.mjs", + "keywords": [ + "pipedream", + "financial_data" + ], + "homepage": "https://pipedream.com/apps/financial_data", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 71c7066ef7ec6..dd4ed58444fdf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4939,6 +4939,9 @@ importers: specifier: ^3.1.0 version: 3.1.0 + components/financial_data: + specifiers: {} + components/findymail: dependencies: '@pipedream/platform': From 48338b723c27090ffc2b3a295e4a44d8bfc1fd49 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Mon, 15 Sep 2025 17:33:08 -0700 Subject: [PATCH 12/52] Adding app scaffolding for microsoft_authenticator --- .../microsoft_authenticator.app.mjs | 11 +++++++++++ components/microsoft_authenticator/package.json | 15 +++++++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/microsoft_authenticator/microsoft_authenticator.app.mjs create mode 100644 components/microsoft_authenticator/package.json diff --git a/components/microsoft_authenticator/microsoft_authenticator.app.mjs b/components/microsoft_authenticator/microsoft_authenticator.app.mjs new file mode 100644 index 0000000000000..3911b9e7409f3 --- /dev/null +++ b/components/microsoft_authenticator/microsoft_authenticator.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "microsoft_authenticator", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/components/microsoft_authenticator/package.json b/components/microsoft_authenticator/package.json new file mode 100644 index 0000000000000..73b8689b4a597 --- /dev/null +++ b/components/microsoft_authenticator/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/microsoft_authenticator", + "version": "0.0.1", + "description": "Pipedream Microsoft Authenticator Components", + "main": "microsoft_authenticator.app.mjs", + "keywords": [ + "pipedream", + "microsoft_authenticator" + ], + "homepage": "https://pipedream.com/apps/microsoft_authenticator", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dd4ed58444fdf..d17fc49d907df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8759,6 +8759,9 @@ importers: components/microsoft_advertising: {} + components/microsoft_authenticator: + specifiers: {} + components/microsoft_azure_ai_translator: dependencies: '@pipedream/platform': From cdbc17be0bef03f45550bc578956f1ccf09f11f6 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Mon, 15 Sep 2025 21:42:46 -0400 Subject: [PATCH 13/52] Merging pull request #18345 * updates * versions * versions --- components/hubspot/package.json | 2 +- components/hubspot/sources/common/common.mjs | 2 +- .../delete-blog-article/delete-blog-article.mjs | 2 +- .../new-company-property-change.mjs | 2 +- .../new-contact-added-to-list.mjs | 2 +- .../new-contact-property-change.mjs | 17 ++++++++++------- .../new-custom-object-property-change.mjs | 17 ++++++++++------- .../new-deal-in-stage/new-deal-in-stage.mjs | 2 +- .../new-deal-property-change.mjs | 17 ++++++++++------- .../sources/new-email-event/new-email-event.mjs | 2 +- .../new-email-subscriptions-timeline.mjs | 2 +- .../sources/new-engagement/new-engagement.mjs | 2 +- .../hubspot/sources/new-event/new-event.mjs | 2 +- .../new-form-submission/new-form-submission.mjs | 2 +- .../hubspot/sources/new-note/new-note.mjs | 2 +- .../new-or-updated-blog-article.mjs | 2 +- .../new-or-updated-company.mjs | 2 +- .../new-or-updated-contact.mjs | 2 +- .../new-or-updated-crm-object.mjs | 2 +- .../new-or-updated-custom-object.mjs | 2 +- .../new-or-updated-deal/new-or-updated-deal.mjs | 2 +- .../new-or-updated-line-item.mjs | 2 +- .../new-or-updated-product.mjs | 2 +- .../new-social-media-message.mjs | 2 +- .../hubspot/sources/new-task/new-task.mjs | 2 +- .../new-ticket-property-change.mjs | 17 ++++++++++------- .../hubspot/sources/new-ticket/new-ticket.mjs | 2 +- 27 files changed, 63 insertions(+), 51 deletions(-) diff --git a/components/hubspot/package.json b/components/hubspot/package.json index d48ffa29dac04..f8fcd6358459d 100644 --- a/components/hubspot/package.json +++ b/components/hubspot/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/hubspot", - "version": "1.7.3", + "version": "1.7.4", "description": "Pipedream Hubspot Components", "main": "hubspot.app.mjs", "keywords": [ diff --git a/components/hubspot/sources/common/common.mjs b/components/hubspot/sources/common/common.mjs index 57ae01b64c8ef..54136ed079537 100644 --- a/components/hubspot/sources/common/common.mjs +++ b/components/hubspot/sources/common/common.mjs @@ -52,7 +52,7 @@ export default { return results.flat(); }, async processEvents(resources, after) { - let maxTs = after; + let maxTs = after || 0; for (const result of resources) { if (await this.isRelevant(result, after)) { this.emitEvent(result); diff --git a/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs b/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs index 96662f3330fcc..48ccc0c1db985 100644 --- a/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs +++ b/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs @@ -6,7 +6,7 @@ export default { key: "hubspot-delete-blog-article", name: "Deleted Blog Posts", description: "Emit new event for each deleted blog post.", - version: "0.0.31", + version: "0.0.32", dedupe: "unique", type: "source", methods: { diff --git a/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs b/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs index a9821b8e6e23d..70fb11014298b 100644 --- a/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs +++ b/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-company-property-change", name: "New Company Property Change", description: "Emit new event when a specified property is provided or updated on a company. [See the documentation](https://developers.hubspot.com/docs/api/crm/companies)", - version: "0.0.24", + version: "0.0.25", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs b/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs index c0ce9be904253..a874851adaf6d 100644 --- a/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs +++ b/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs @@ -12,7 +12,7 @@ export default { name: "New Contact Added to List", description: "Emit new event when a contact is added to a HubSpot list. [See the documentation](https://developers.hubspot.com/docs/reference/api/crm/lists#get-%2Fcrm%2Fv3%2Flists%2F%7Blistid%7D%2Fmemberships%2Fjoin-order)", - version: "0.0.3", + version: "0.0.4", type: "source", dedupe: "unique", props: { diff --git a/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs b/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs index e33181d864626..f225bf151ee11 100644 --- a/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs +++ b/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-contact-property-change", name: "New Contact Property Change", description: "Emit new event when a specified property is provided or updated on a contact. [See the documentation](https://developers.hubspot.com/docs/api/crm/contacts)", - version: "0.0.26", + version: "0.0.27", dedupe: "unique", type: "source", props: { @@ -46,7 +46,7 @@ export default { return !updatedAfter || this.getTs(contact) > updatedAfter; }, getParams(after) { - return { + const params = { object: "contacts", data: { limit: DEFAULT_LIMIT, @@ -66,16 +66,19 @@ export default { propertyName: this.property, operator: "HAS_PROPERTY", }, - { - propertyName: "lastmodifieddate", - operator: "GTE", - value: after, - }, ], }, ], }, }; + if (after) { + params.data.filterGroups[0].filters.push({ + propertyName: "lastmodifieddate", + operator: "GTE", + value: after, + }); + } + return params; }, batchGetContacts(inputs) { return this.hubspot.batchGetObjects({ diff --git a/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs b/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs index b77e72356d6e5..aa7f7986f3903 100644 --- a/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs +++ b/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs @@ -7,7 +7,7 @@ export default { name: "New Custom Object Property Change", description: "Emit new event when a specified property is provided or updated on a custom object.", - version: "0.0.16", + version: "0.0.17", dedupe: "unique", type: "source", props: { @@ -52,7 +52,7 @@ export default { return !updatedAfter || this.getTs(object) > updatedAfter; }, getParams(after) { - return { + const params = { object: this.objectSchema, data: { limit: DEFAULT_LIMIT, @@ -72,16 +72,19 @@ export default { propertyName: this.property, operator: "HAS_PROPERTY", }, - { - propertyName: "hs_lastmodifieddate", - operator: "GTE", - value: after, - }, ], }, ], }, }; + if (after) { + params.data.filterGroups[0].filters.push({ + propertyName: "hs_lastmodifieddate", + operator: "GTE", + value: after, + }); + } + return params; }, batchGetCustomObjects(inputs) { return this.hubspot.batchGetObjects({ diff --git a/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs b/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs index 276172657d396..be8bfad6873c7 100644 --- a/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs +++ b/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs @@ -11,7 +11,7 @@ export default { key: "hubspot-new-deal-in-stage", name: "New Deal In Stage", description: "Emit new event for each new deal in a stage.", - version: "0.0.37", + version: "0.0.38", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs b/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs index 678a83a798e6c..2801324f0e3ed 100644 --- a/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs +++ b/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-deal-property-change", name: "New Deal Property Change", description: "Emit new event when a specified property is provided or updated on a deal. [See the documentation](https://developers.hubspot.com/docs/api/crm/deals)", - version: "0.0.25", + version: "0.0.26", dedupe: "unique", type: "source", props: { @@ -44,7 +44,7 @@ export default { return !updatedAfter || this.getTs(deal) > updatedAfter; }, getParams(after) { - return { + const params = { object: "deals", data: { limit: DEFAULT_LIMIT, @@ -64,16 +64,19 @@ export default { propertyName: this.property, operator: "HAS_PROPERTY", }, - { - propertyName: "hs_lastmodifieddate", - operator: "GTE", - value: after, - }, ], }, ], }, }; + if (after) { + params.data.filterGroups[0].filters.push({ + propertyName: "hs_lastmodifieddate", + operator: "GTE", + value: after, + }); + } + return params; }, batchGetDeals(inputs) { return this.hubspot.batchGetObjects({ diff --git a/components/hubspot/sources/new-email-event/new-email-event.mjs b/components/hubspot/sources/new-email-event/new-email-event.mjs index 38fd9acc1d684..19b73dc3a36eb 100644 --- a/components/hubspot/sources/new-email-event/new-email-event.mjs +++ b/components/hubspot/sources/new-email-event/new-email-event.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-email-event", name: "New Email Event", description: "Emit new event for each new Hubspot email event.", - version: "0.0.34", + version: "0.0.35", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs b/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs index 6bad1f0fbb0e9..f2592e70dd788 100644 --- a/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs +++ b/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs @@ -6,7 +6,7 @@ export default { key: "hubspot-new-email-subscriptions-timeline", name: "New Email Subscriptions Timeline", description: "Emit new event when a new email timeline subscription is added for the portal.", - version: "0.0.31", + version: "0.0.32", dedupe: "unique", type: "source", methods: { diff --git a/components/hubspot/sources/new-engagement/new-engagement.mjs b/components/hubspot/sources/new-engagement/new-engagement.mjs index 13ae395bb4035..806286bb36296 100644 --- a/components/hubspot/sources/new-engagement/new-engagement.mjs +++ b/components/hubspot/sources/new-engagement/new-engagement.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-engagement", name: "New Engagement", description: "Emit new event for each new engagement created. This action returns a maximum of 5000 records at a time, make sure you set a correct time range so you don't miss any events", - version: "0.0.36", + version: "0.0.37", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-event/new-event.mjs b/components/hubspot/sources/new-event/new-event.mjs index 5a842d4b20456..ac746ed42c069 100644 --- a/components/hubspot/sources/new-event/new-event.mjs +++ b/components/hubspot/sources/new-event/new-event.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-event", name: "New Events", description: "Emit new event for each new Hubspot event. Note: Only available for Marketing Hub Enterprise, Sales Hub Enterprise, Service Hub Enterprise, or CMS Hub Enterprise accounts", - version: "0.0.35", + version: "0.0.36", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-form-submission/new-form-submission.mjs b/components/hubspot/sources/new-form-submission/new-form-submission.mjs index 74258487ca3ca..bad33385f2683 100644 --- a/components/hubspot/sources/new-form-submission/new-form-submission.mjs +++ b/components/hubspot/sources/new-form-submission/new-form-submission.mjs @@ -6,7 +6,7 @@ export default { key: "hubspot-new-form-submission", name: "New Form Submission", description: "Emit new event for each new submission of a form.", - version: "0.0.36", + version: "0.0.37", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-note/new-note.mjs b/components/hubspot/sources/new-note/new-note.mjs index fe022c38c0b85..3e40904c1d473 100644 --- a/components/hubspot/sources/new-note/new-note.mjs +++ b/components/hubspot/sources/new-note/new-note.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-note", name: "New Note Created", description: "Emit new event for each new note created. [See the documentation](https://developers.hubspot.com/docs/reference/api/crm/engagements/notes#get-%2Fcrm%2Fv3%2Fobjects%2Fnotes)", - version: "1.0.12", + version: "1.0.13", type: "source", dedupe: "unique", methods: { diff --git a/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs b/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs index 398b58348d268..b149d10e99c2d 100644 --- a/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs +++ b/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-or-updated-blog-article", name: "New or Updated Blog Post", description: "Emit new event for each new or updated blog post in Hubspot.", - version: "0.0.18", + version: "0.0.19", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs b/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs index 9f35ccf875930..c3267b264a40c 100644 --- a/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs +++ b/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-company", name: "New or Updated Company", description: "Emit new event for each new or updated company in Hubspot.", - version: "0.0.18", + version: "0.0.19", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs b/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs index 02a7b864267c4..48951286d95f8 100644 --- a/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs +++ b/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-contact", name: "New or Updated Contact", description: "Emit new event for each new or updated contact in Hubspot.", - version: "0.0.19", + version: "0.0.20", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs b/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs index af790e96a6b8a..d66f56d5987f2 100644 --- a/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs +++ b/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-or-updated-crm-object", name: "New or Updated CRM Object", description: "Emit new event each time a CRM Object of the specified object type is updated.", - version: "0.0.31", + version: "0.0.32", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs b/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs index 36270b6ecfaa7..2f55c41b5b929 100644 --- a/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs +++ b/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-or-updated-custom-object", name: "New or Updated Custom Object", description: "Emit new event each time a Custom Object of the specified schema is updated.", - version: "0.0.20", + version: "0.0.21", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs b/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs index 547cf1e42f576..934bbacaae581 100644 --- a/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs +++ b/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-deal", name: "New or Updated Deal", description: "Emit new event for each new or updated deal in Hubspot", - version: "0.0.18", + version: "0.0.19", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs b/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs index dbf83a424ba90..b80c4fc070532 100644 --- a/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs +++ b/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-line-item", name: "New or Updated Line Item", description: "Emit new event for each new line item added or updated in Hubspot.", - version: "0.0.18", + version: "0.0.19", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs b/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs index 765df936d7001..ff29b1b9c307e 100644 --- a/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs +++ b/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-product", name: "New or Updated Product", description: "Emit new event for each new or updated product in Hubspot.", - version: "0.0.18", + version: "0.0.19", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs b/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs index 5bd50a3ca239d..e06559327c640 100644 --- a/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs +++ b/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs @@ -7,7 +7,7 @@ export default { name: "New Social Media Message", description: "Emit new event when a message is posted from HubSpot to the specified social media channel. Note: Only available for Marketing Hub Enterprise accounts", - version: "0.0.31", + version: "0.0.32", type: "source", dedupe: "unique", props: { diff --git a/components/hubspot/sources/new-task/new-task.mjs b/components/hubspot/sources/new-task/new-task.mjs index 71dff7d356d1e..d938018a75fa4 100644 --- a/components/hubspot/sources/new-task/new-task.mjs +++ b/components/hubspot/sources/new-task/new-task.mjs @@ -9,7 +9,7 @@ export default { name: "New Task Created", description: "Emit new event for each new task created. [See the documentation](https://developers.hubspot.com/docs/reference/api/crm/engagements/tasks#get-%2Fcrm%2Fv3%2Fobjects%2Ftasks)", - version: "1.0.12", + version: "1.0.13", type: "source", dedupe: "unique", methods: { diff --git a/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs b/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs index 517ccfcdb5904..b38d27db8ae0e 100644 --- a/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs +++ b/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs @@ -8,7 +8,7 @@ export default { name: "New Ticket Property Change", description: "Emit new event when a specified property is provided or updated on a ticket. [See the documentation](https://developers.hubspot.com/docs/api/crm/tickets)", - version: "0.0.25", + version: "0.0.26", dedupe: "unique", type: "source", props: { @@ -47,7 +47,7 @@ export default { return !updatedAfter || this.getTs(ticket) > updatedAfter; }, getParams(after) { - return { + const params = { object: "tickets", data: { limit: DEFAULT_LIMIT, @@ -67,16 +67,19 @@ export default { propertyName: this.property, operator: "HAS_PROPERTY", }, - { - propertyName: "hs_lastmodifieddate", - operator: "GTE", - value: after, - }, ], }, ], }, }; + if (after) { + params.data.filterGroups[0].filters.push({ + propertyName: "hs_lastmodifieddate", + operator: "GTE", + value: after, + }); + } + return params; }, batchGetTickets(inputs) { return this.hubspot.batchGetObjects({ diff --git a/components/hubspot/sources/new-ticket/new-ticket.mjs b/components/hubspot/sources/new-ticket/new-ticket.mjs index 09da36ffcfd68..2a51e25a0f857 100644 --- a/components/hubspot/sources/new-ticket/new-ticket.mjs +++ b/components/hubspot/sources/new-ticket/new-ticket.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-ticket", name: "New Ticket", description: "Emit new event for each new ticket created.", - version: "0.0.31", + version: "0.0.32", dedupe: "unique", type: "source", props: { From 4ea8c2e04668e5d3855983f9fa8ad4613315a5df Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 16 Sep 2025 05:26:53 -0400 Subject: [PATCH 14/52] Merging pull request #18368 * updates * remove console.log * versions --- components/notion/actions/append-block/append-block.mjs | 2 +- components/notion/actions/common/base-page-builder.mjs | 7 ++++++- .../actions/complete-file-upload/complete-file-upload.mjs | 2 +- .../notion/actions/create-database/create-database.mjs | 2 +- .../actions/create-file-upload/create-file-upload.mjs | 2 +- .../create-page-from-database.mjs | 5 ++++- components/notion/actions/create-page/create-page.mjs | 2 +- components/notion/actions/delete-block/delete-block.mjs | 2 +- .../notion/actions/duplicate-page/duplicate-page.mjs | 2 +- .../notion/actions/list-file-uploads/list-file-uploads.mjs | 2 +- .../actions/retrieve-file-upload/retrieve-file-upload.mjs | 2 +- .../notion/actions/send-file-upload/send-file-upload.mjs | 2 +- components/notion/actions/update-block/update-block.mjs | 2 +- .../notion/actions/update-database/update-database.mjs | 2 +- components/notion/actions/update-page/update-page.mjs | 2 +- components/notion/package.json | 2 +- 16 files changed, 24 insertions(+), 16 deletions(-) diff --git a/components/notion/actions/append-block/append-block.mjs b/components/notion/actions/append-block/append-block.mjs index ef74394108aa8..98491e5140c67 100644 --- a/components/notion/actions/append-block/append-block.mjs +++ b/components/notion/actions/append-block/append-block.mjs @@ -7,7 +7,7 @@ export default { name: "Append Block to Parent", description: "Append new and/or existing blocks to the specified parent. [See the documentation](https://developers.notion.com/reference/patch-block-children)", - version: "0.3.8", + version: "0.3.9", type: "action", props: { notion, diff --git a/components/notion/actions/common/base-page-builder.mjs b/components/notion/actions/common/base-page-builder.mjs index 2bb116155e2c5..2345e63759f15 100644 --- a/components/notion/actions/common/base-page-builder.mjs +++ b/components/notion/actions/common/base-page-builder.mjs @@ -5,6 +5,7 @@ import { } from "../../common/notion-meta-properties.mjs"; import NOTION_META from "../../common/notion-meta-selection.mjs"; import NOTION_PAGE_PROPERTIES from "../../common/notion-page-properties.mjs"; +import { ConfigurationError } from "@pipedream/platform"; export default { methods: { @@ -103,7 +104,11 @@ export default { } else { // Otherwise, convert using the appropriate converter const notionProperty = NOTION_CONVERTER[property.type]; - notionProperties[property.label] = notionProperty?.convertToNotion(property); + try { + notionProperties[property.label] = notionProperty?.convertToNotion(property); + } catch { + throw new ConfigurationError(`Error converting property with label \`${property.label}\` to Notion format. Must be of type \`${NOTION_CONVERTER[property.type]?.type}\`.`); + } } } return notionProperties; diff --git a/components/notion/actions/complete-file-upload/complete-file-upload.mjs b/components/notion/actions/complete-file-upload/complete-file-upload.mjs index 108cd25aeae97..e34426e8e0999 100644 --- a/components/notion/actions/complete-file-upload/complete-file-upload.mjs +++ b/components/notion/actions/complete-file-upload/complete-file-upload.mjs @@ -6,7 +6,7 @@ export default { key: "notion-complete-file-upload", name: "Complete File Upload", description: "Use this action to finalize a `mode=multi_part` file upload after all of the parts have been sent successfully. [See the documentation](https://developers.notion.com/reference/complete-a-file-upload)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { notion, diff --git a/components/notion/actions/create-database/create-database.mjs b/components/notion/actions/create-database/create-database.mjs index 8b46e52e8661b..cf75b649ac8db 100644 --- a/components/notion/actions/create-database/create-database.mjs +++ b/components/notion/actions/create-database/create-database.mjs @@ -7,7 +7,7 @@ export default { key: "notion-create-database", name: "Create Database", description: "Create a database and its initial data source. [See the documentation](https://developers.notion.com/reference/database-create)", - version: "0.1.0", + version: "0.1.1", type: "action", props: { notion, diff --git a/components/notion/actions/create-file-upload/create-file-upload.mjs b/components/notion/actions/create-file-upload/create-file-upload.mjs index 68bf8591c5c18..ab0b03e21b23f 100644 --- a/components/notion/actions/create-file-upload/create-file-upload.mjs +++ b/components/notion/actions/create-file-upload/create-file-upload.mjs @@ -6,7 +6,7 @@ export default { key: "notion-create-file-upload", name: "Create File Upload", description: "Create a file upload. [See the documentation](https://developers.notion.com/reference/create-a-file-upload)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { notion, diff --git a/components/notion/actions/create-page-from-database/create-page-from-database.mjs b/components/notion/actions/create-page-from-database/create-page-from-database.mjs index 31990728a340d..afa080bc6473b 100644 --- a/components/notion/actions/create-page-from-database/create-page-from-database.mjs +++ b/components/notion/actions/create-page-from-database/create-page-from-database.mjs @@ -8,7 +8,7 @@ export default { key: "notion-create-page-from-database", name: "Create Page from Data Source", description: "Create a page from a data source. [See the documentation](https://developers.notion.com/reference/post-page)", - version: "1.0.0", + version: "1.0.1", type: "action", props: { notion, @@ -85,6 +85,9 @@ export default { const response = await this.notion.createPage({ ...page, children: children.slice(0, MAX_BLOCKS), + parent: { + data_source_id: this.parentDataSource, + }, }); let remainingBlocks = children.slice(MAX_BLOCKS); while (remainingBlocks.length > 0) { diff --git a/components/notion/actions/create-page/create-page.mjs b/components/notion/actions/create-page/create-page.mjs index 164b747ff15e6..032fe7977eb0c 100644 --- a/components/notion/actions/create-page/create-page.mjs +++ b/components/notion/actions/create-page/create-page.mjs @@ -7,7 +7,7 @@ export default { key: "notion-create-page", name: "Create Page", description: "Create a page from a parent page. [See the documentation](https://developers.notion.com/reference/post-page)", - version: "0.2.21", + version: "0.2.22", type: "action", props: { notion, diff --git a/components/notion/actions/delete-block/delete-block.mjs b/components/notion/actions/delete-block/delete-block.mjs index a98f6083e12dd..791c085f350e5 100644 --- a/components/notion/actions/delete-block/delete-block.mjs +++ b/components/notion/actions/delete-block/delete-block.mjs @@ -6,7 +6,7 @@ export default { key: "notion-delete-block", name: "Delete Block", description: "Sets a Block object, including page blocks, to archived: true using the ID specified. [See the documentation](https://developers.notion.com/reference/delete-a-block)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { notion, diff --git a/components/notion/actions/duplicate-page/duplicate-page.mjs b/components/notion/actions/duplicate-page/duplicate-page.mjs index 8a1c6e4a1a864..ede033c683b67 100644 --- a/components/notion/actions/duplicate-page/duplicate-page.mjs +++ b/components/notion/actions/duplicate-page/duplicate-page.mjs @@ -7,7 +7,7 @@ export default { key: "notion-duplicate-page", name: "Duplicate Page", description: "Create a new page copied from an existing page block. [See the documentation](https://developers.notion.com/reference/post-page)", - version: "0.0.18", + version: "0.0.19", type: "action", props: { notion, diff --git a/components/notion/actions/list-file-uploads/list-file-uploads.mjs b/components/notion/actions/list-file-uploads/list-file-uploads.mjs index 0ed02d25c15b0..770c7fbfe35b4 100644 --- a/components/notion/actions/list-file-uploads/list-file-uploads.mjs +++ b/components/notion/actions/list-file-uploads/list-file-uploads.mjs @@ -6,7 +6,7 @@ export default { key: "notion-list-file-uploads", name: "List File Uploads", description: "Use this action to list file uploads. [See the documentation](https://developers.notion.com/reference/list-file-uploads)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { notion, diff --git a/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs b/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs index 059e9858ec2c5..1308069faf600 100644 --- a/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs +++ b/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs @@ -6,7 +6,7 @@ export default { key: "notion-retrieve-file-upload", name: "Retrieve File Upload", description: "Use this action to retrieve a file upload. [See the documentation](https://developers.notion.com/reference/retrieve-a-file-upload)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { notion, diff --git a/components/notion/actions/send-file-upload/send-file-upload.mjs b/components/notion/actions/send-file-upload/send-file-upload.mjs index 9141bfe8bfc38..6d9747b689090 100644 --- a/components/notion/actions/send-file-upload/send-file-upload.mjs +++ b/components/notion/actions/send-file-upload/send-file-upload.mjs @@ -8,7 +8,7 @@ export default { key: "notion-send-file-upload", name: "Send File Upload", description: "Send a file upload. [See the documentation](https://developers.notion.com/reference/send-a-file-upload)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { notion, diff --git a/components/notion/actions/update-block/update-block.mjs b/components/notion/actions/update-block/update-block.mjs index b82a2a1ae5b8a..89cddd64c9b11 100644 --- a/components/notion/actions/update-block/update-block.mjs +++ b/components/notion/actions/update-block/update-block.mjs @@ -7,7 +7,7 @@ export default { key: "notion-update-block", name: "Update Child Block", description: "Updates a child block object. [See the documentation](https://developers.notion.com/reference/update-a-block)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { notion, diff --git a/components/notion/actions/update-database/update-database.mjs b/components/notion/actions/update-database/update-database.mjs index 333783c1d5de1..d00b0cf03f562 100644 --- a/components/notion/actions/update-database/update-database.mjs +++ b/components/notion/actions/update-database/update-database.mjs @@ -7,7 +7,7 @@ export default { key: "notion-update-database", name: "Update Data Source", description: "Update a data source. [See the documentation](https://developers.notion.com/reference/update-a-data-source)", - version: "1.0.0", + version: "1.0.1", type: "action", props: { notion, diff --git a/components/notion/actions/update-page/update-page.mjs b/components/notion/actions/update-page/update-page.mjs index 09468438e14f6..6f31a04b750ce 100644 --- a/components/notion/actions/update-page/update-page.mjs +++ b/components/notion/actions/update-page/update-page.mjs @@ -7,7 +7,7 @@ export default { key: "notion-update-page", name: "Update Page", description: "Update a page's property values. To append page content, use the *Append Block* action instead. [See the documentation](https://developers.notion.com/reference/patch-page)", - version: "2.0.0", + version: "2.0.1", type: "action", props: { notion, diff --git a/components/notion/package.json b/components/notion/package.json index 15d66ac78804b..ba167d9dafbee 100644 --- a/components/notion/package.json +++ b/components/notion/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/notion", - "version": "1.0.0", + "version": "1.0.1", "description": "Pipedream Notion Components", "main": "notion.app.mjs", "keywords": [ From 0c0e1834e0796fdcbe102158292d4149a61360f8 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 16 Sep 2025 10:38:26 -0400 Subject: [PATCH 15/52] Coinbase Developer Platform - New Wallet Event (#18342) * new component * pnpm-lock.yaml * updates * updates --- .../coinbase_developer_platform.app.mjs | 42 +- .../coinbase_developer_platform/package.json | 8 +- .../sources/common/base.mjs | 29 ++ .../new-wallet-event/new-wallet-event.mjs | 70 ++++ .../sources/new-wallet-event/test-event.mjs | 15 + components/timescaledb/timescaledb.app.mjs | 2 +- pnpm-lock.yaml | 386 +++++++++++++++++- 7 files changed, 543 insertions(+), 9 deletions(-) create mode 100644 components/coinbase_developer_platform/sources/common/base.mjs create mode 100644 components/coinbase_developer_platform/sources/new-wallet-event/new-wallet-event.mjs create mode 100644 components/coinbase_developer_platform/sources/new-wallet-event/test-event.mjs diff --git a/components/coinbase_developer_platform/coinbase_developer_platform.app.mjs b/components/coinbase_developer_platform/coinbase_developer_platform.app.mjs index bbab8c8af2737..444db7055a977 100644 --- a/components/coinbase_developer_platform/coinbase_developer_platform.app.mjs +++ b/components/coinbase_developer_platform/coinbase_developer_platform.app.mjs @@ -1,11 +1,43 @@ +import { + Coinbase, Webhook, +} from "@coinbase/coinbase-sdk"; + export default { type: "app", app: "coinbase_developer_platform", - propDefinitions: {}, + propDefinitions: { + walletAddress: { + type: "string", + label: "Address", + description: "The address of the wallet to monitor. Example: `0x8fddcc0c5c993a1968b46787919cc34577d6dc5c`", + }, + networkId: { + type: "string", + label: "Network ID", + description: "The network ID of the wallet to monitor. Example: `base-mainnet`", + async options() { + const networks = Coinbase.networks; + return Object.values(networks); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + configure() { + const apiKeyName = this.$auth.api_key_id; + const privateKey = this.$auth.secret_key; + Coinbase.configure({ + apiKeyName, + privateKey, + }); + }, + listWebhooks() { + return Webhook.list(); + }, + createWebhook(opts) { + return Webhook.create(opts); + }, + deleteWebhook(webhook) { + return webhook.delete(); }, }, -}; \ No newline at end of file +}; diff --git a/components/coinbase_developer_platform/package.json b/components/coinbase_developer_platform/package.json index a079e1a021054..92b0e6590e153 100644 --- a/components/coinbase_developer_platform/package.json +++ b/components/coinbase_developer_platform/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/coinbase_developer_platform", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Coinbase Developer Platform Components", "main": "coinbase_developer_platform.app.mjs", "keywords": [ @@ -11,5 +11,9 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@coinbase/coinbase-sdk": "^0.25.0", + "@pipedream/platform": "^3.1.0" } -} \ No newline at end of file +} diff --git a/components/coinbase_developer_platform/sources/common/base.mjs b/components/coinbase_developer_platform/sources/common/base.mjs new file mode 100644 index 0000000000000..592ab709e8e09 --- /dev/null +++ b/components/coinbase_developer_platform/sources/common/base.mjs @@ -0,0 +1,29 @@ +import coinbase from "../../coinbase_developer_platform.app.mjs"; +import { ConfigurationError } from "@pipedream/platform"; + +export default { + props: { + coinbase, + db: "$.service.db", + http: "$.interface.http", + }, + methods: { + _getWebhookId() { + return this.db.get("webhookId"); + }, + _setWebhookId(webhookId) { + this.db.set("webhookId", webhookId); + }, + generateMeta() { + throw new ConfigurationError("generateMeta is not implemented"); + }, + }, + async run(event) { + const { body } = event; + if (!body) { + return; + } + const meta = this.generateMeta(body); + this.$emit(body, meta); + }, +}; diff --git a/components/coinbase_developer_platform/sources/new-wallet-event/new-wallet-event.mjs b/components/coinbase_developer_platform/sources/new-wallet-event/new-wallet-event.mjs new file mode 100644 index 0000000000000..54ed2c65baf1a --- /dev/null +++ b/components/coinbase_developer_platform/sources/new-wallet-event/new-wallet-event.mjs @@ -0,0 +1,70 @@ +import common from "../common/base.mjs"; +import { ConfigurationError } from "@pipedream/platform"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + name: "New Wallet Event (Instant)", + key: "coinbase_developer_platform-new-wallet-event", + description: "Emit new event for each new wallet event. [See the documentation](https://docs.cdp.coinbase.com/webhooks/cdp-sdk#external-address-webhook)", + version: "0.0.1", + type: "source", + dedupe: "unique", + props: { + ...common.props, + walletAddress: { + propDefinition: [ + common.props.coinbase, + "walletAddress", + ], + }, + networkId: { + propDefinition: [ + common.props.coinbase, + "networkId", + ], + }, + }, + hooks: { + async activate() { + this.coinbase.configure(); + const webhook = await this.coinbase.createWebhook({ + notificationUri: this.http.endpoint, + eventType: "wallet_activity", + networkId: this.networkId, + eventTypeFilter: { + addresses: [ + this.walletAddress, + ], + wallet_id: "", + }, + }); + + if (!webhook?.model?.id) { + throw new ConfigurationError("Failed to create webhook"); + } + + this._setWebhookId(webhook.model.id); + }, + async deactivate() { + this.coinbase.configure(); + const webhookId = this._getWebhookId(); + if (webhookId) { + const { data: webhooks } = await this.coinbase.listWebhooks(); + const webhook = webhooks.find((webhook) => webhook.model.id === webhookId); + await this.coinbase.deleteWebhook(webhook); + } + }, + }, + methods: { + ...common.methods, + generateMeta(body) { + return { + id: body.transactionHash, + summary: `New ${body.eventType} event`, + ts: Date.parse(body.blockTime), + }; + }, + }, + sampleEmit, +}; diff --git a/components/coinbase_developer_platform/sources/new-wallet-event/test-event.mjs b/components/coinbase_developer_platform/sources/new-wallet-event/test-event.mjs new file mode 100644 index 0000000000000..646edc0cb4c89 --- /dev/null +++ b/components/coinbase_developer_platform/sources/new-wallet-event/test-event.mjs @@ -0,0 +1,15 @@ +export default { + "blockHash": "0x351bd04dfe350fca186cd47080220283a75d07018ed251748a4ad19e7f327caf", + "blockNumber": 20305354, + "blockTime": "2024-09-27T21:16:40.000Z", + "contractAddress": "0xab39a8b6801b0b6aa20e9a1953c861ec0a57d175", + "eventType": "erc20_transfer", + "from": "0x10db590ffa5b7bc46cffbd436180e01b6c5c0af6", + "logIndex": "121", + "network": "base-sepolia", + "to": "0x4a9ab171e31daff484c70921f2f5e89a8fe12f59", + "transactionHash": "0x940db3006449456b386397ab42114134d745d2876196226444601670f3e99db8", + "transactionIndex": "19", + "value": "1000000", + "webhookId": "66bd79d0b9c200eae1a43165" +} \ No newline at end of file diff --git a/components/timescaledb/timescaledb.app.mjs b/components/timescaledb/timescaledb.app.mjs index 243069d6303f7..f5ad18839a3fe 100644 --- a/components/timescaledb/timescaledb.app.mjs +++ b/components/timescaledb/timescaledb.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d17fc49d907df..afd66a8a07874 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3023,7 +3023,14 @@ importers: components/coinbase_commerce: {} - components/coinbase_developer_platform: {} + components/coinbase_developer_platform: + dependencies: + '@coinbase/coinbase-sdk': + specifier: ^0.25.0 + version: 0.25.0(typescript@5.9.2)(zod@4.0.14) + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 components/coingecko: {} @@ -16902,6 +16909,12 @@ packages: resolution: {integrity: sha512-sLIiSYjQbJz74hB7NpJ7HcQTJikbvADdMh4oOtktn3zMEStAyl8BVQ+x40FimHAFqY0lJl4G99ZJHUYX6HFDQA==} engines: {node: '>= 10.13.0', npm: '>= 5.6.0'} + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + '@adyen/api-library@20.0.0': resolution: {integrity: sha512-C+jj5XBTCNs7AFwufOkPLhuqn9bdgSDcqLB6b/Ppi9Fujwt613vWmA1hxeG76RX49vzHZIDJLq6N/v0o2SY1sA==} engines: {node: '>=18'} @@ -18192,6 +18205,9 @@ packages: '@bugsnag/safe-json-stringify@6.0.0': resolution: {integrity: sha512-htzFO1Zc57S8kgdRK9mLcPVTW1BY2ijfH7Dk2CeZmspTWKdKqSo1iwmqrq2WtRjFlo8aRZYgLX0wFrDXF/9DLA==} + '@coinbase/coinbase-sdk@0.25.0': + resolution: {integrity: sha512-VzRfeeCJsnML/HvSY+CowfSiPUprEvU5Mww9qJeoUZ7YVi3Yw3ul34UCZD5aXyXNlt/r6TQm7CEnODa5LpHEPg==} + '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} @@ -19762,6 +19778,29 @@ packages: '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -21426,6 +21465,15 @@ packages: '@scrapeless-ai/sdk@1.6.0': resolution: {integrity: sha512-U+VW0hIUf7x37P9rWDqNY3tzpDdTN1Akwds7hMBkoc1avrQyt8a+tV9nCJFcNTFDD0pfEM5esCJhhJhfIncMvw==} + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -22285,6 +22333,9 @@ packages: '@types/node@22.15.9': resolution: {integrity: sha512-l6QaCgJSJQ0HngL1TjvEY2DlefKggyGeXP1KYvYLBX41ZDPM1FsgDMAr5c+T673NMy7VCptMOzXOuJqf5uB0bA==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/node@24.0.10': resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==} @@ -22599,6 +22650,17 @@ packages: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} + abitype@1.1.0: + resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -22657,6 +22719,9 @@ packages: resolution: {integrity: sha512-lUI3ZSNsfQXNYNzGjt68MdxzCs0eW29lgL74y/Y2h4nARgHmH3poFWuK3LonvFbNHFt4dTb2X/QQ4c1ZUWWsJw==} engines: {node: '>=6.0'} + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -22992,6 +23057,16 @@ packages: resolution: {integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==} engines: {node: '>=4'} + axios-mock-adapter@1.22.0: + resolution: {integrity: sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==} + peerDependencies: + axios: '>= 0.17.0' + + axios-retry@4.5.0: + resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==} + peerDependencies: + axios: 0.x || 1.x + axios@0.19.2: resolution: {integrity: sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==} deprecated: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410 @@ -23138,6 +23213,9 @@ packages: base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + base-x@3.0.11: + resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -23186,6 +23264,13 @@ packages: bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bip32@4.0.0: + resolution: {integrity: sha512-aOGy88DDlVUhspIXJN+dVEtclhIsfAUppD43V0j40cPTld3pv/0X/MlrZSZ6jowIaQQzFwP8M6rFU2z2mVYjDQ==} + engines: {node: '>=6.0.0'} + + bip39@3.1.0: + resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==} + birpc@2.4.0: resolution: {integrity: sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==} @@ -23245,6 +23330,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + browser-request@0.3.3: resolution: {integrity: sha512-YyNI4qJJ+piQG6MMEuo7J3Bzaqssufx04zpEKYfSrl/1Op59HWali9zMtBpXnkmqMcOuWJPZvudrm9wISmnCbg==} engines: {'0': node} @@ -23258,6 +23346,12 @@ packages: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} engines: {node: '>= 6'} + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -24174,6 +24268,9 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} @@ -24545,6 +24642,9 @@ packages: ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + ed2curve@0.3.0: + resolution: {integrity: sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ==} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -24560,6 +24660,9 @@ packages: electron-to-chromium@1.5.64: resolution: {integrity: sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ==} + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + emitter-component@1.1.2: resolution: {integrity: sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==} @@ -25006,6 +25109,10 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + ethers@6.15.0: + resolution: {integrity: sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==} + engines: {node: '>=14.0.0'} + event-emitter@0.3.5: resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} @@ -26092,6 +26199,9 @@ packages: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} engines: {node: '>=4'} + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -26121,6 +26231,9 @@ packages: resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} engines: {node: '>=8'} + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -26702,6 +26815,10 @@ packages: resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} engines: {node: '>=0.10.0'} + is-retry-allowed@2.2.0: + resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} + engines: {node: '>=10'} + is-set@2.0.3: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} @@ -26827,6 +26944,11 @@ packages: peerDependencies: ws: '*' + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} @@ -27042,6 +27164,9 @@ packages: jose@4.15.5: resolution: {integrity: sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==} + jose@5.10.0: + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + jose@5.9.6: resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} @@ -28078,6 +28203,9 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimatch@10.0.1: resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} engines: {node: 20 || >=22} @@ -28352,6 +28480,9 @@ packages: node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + node-addon-api@5.1.0: + resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} @@ -28769,6 +28900,14 @@ packages: resolution: {integrity: sha512-sJBRCbS5vh1Jp9EOgwp1Ws3c16lJrUkJYlvWTYC03oyiYVwS/ns7lKRWow4w4XjDyTrA2pplQv4B2naWSR6yDA==} engines: {node: '>=14.16'} + ox@0.9.3: + resolution: {integrity: sha512-KzyJP+fPV4uhuuqrTZyok4DC7vFzi7HLUFiUNEmpbyh59htKWkOC98IONC1zgXJPbHAhQgqs6B0Z6StCGhmQvg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + p-cancelable@2.1.1: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} @@ -30108,6 +30247,10 @@ packages: scmp@2.1.0: resolution: {integrity: sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==} + secp256k1@5.0.1: + resolution: {integrity: sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA==} + engines: {node: '>=18.0.0'} + secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -31158,6 +31301,9 @@ packages: tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -31213,6 +31359,9 @@ packages: tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + twilio@3.84.1: resolution: {integrity: sha512-Q/xaPoayTj+bgJdnUgpE+EiB/VoNOG+byDFdlDej0FgxiHLgXKliZfVv6boqHPWvC1k7Dt0AK96OBFZ0P55QQg==} engines: {node: '>=6.0'} @@ -31289,6 +31438,9 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + typeforce@1.18.0: + resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} + typescript-eslint@8.15.0: resolution: {integrity: sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -31769,6 +31921,14 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + viem@2.37.5: + resolution: {integrity: sha512-bLKvKgLcge6KWBMLk8iP9weu5tHNr0hkxPNwQd+YQrHEgek7ogTBBeE10T0V6blwBMYmeZFZHLnMhDmPjp63/A==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + viesapi-client@1.2.7: resolution: {integrity: sha512-+KyTNegTHWUbfrIWNL8dcSMEgK1pvEbHurFlHSsIOSwiwjcNHwAz5kTL/ZnJj7UUYdsmKRvSEUfQIF/KA3dyCQ==} @@ -31932,6 +32092,9 @@ packages: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} + wif@2.0.6: + resolution: {integrity: sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==} + wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} @@ -32040,6 +32203,18 @@ packages: utf-8-validate: optional: true + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -32297,6 +32472,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@adraffy/ens-normalize@1.10.1': {} + + '@adraffy/ens-normalize@1.11.0': {} + '@adyen/api-library@20.0.0': dependencies: https-proxy-agent: 5.0.1 @@ -35666,6 +35845,29 @@ snapshots: '@bugsnag/safe-json-stringify@6.0.0': {} + '@coinbase/coinbase-sdk@0.25.0(typescript@5.9.2)(zod@4.0.14)': + dependencies: + '@scure/bip32': 1.7.0 + abitype: 1.1.0(typescript@5.9.2)(zod@4.0.14) + axios: 1.11.0(debug@3.2.7) + axios-mock-adapter: 1.22.0(axios@1.11.0) + axios-retry: 4.5.0(axios@1.11.0) + bip32: 4.0.0 + bip39: 3.1.0 + decimal.js: 10.6.0 + dotenv: 16.6.1 + ed2curve: 0.3.0 + ethers: 6.15.0 + jose: 5.10.0 + secp256k1: 5.0.1 + viem: 2.37.5(typescript@5.9.2)(zod@4.0.14) + transitivePeerDependencies: + - bufferutil + - debug + - typescript + - utf-8-validate + - zod + '@colors/colors@1.6.0': {} '@connectrpc/connect-web@2.0.0-rc.3(@bufbuild/protobuf@2.5.0)(@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.5.0))': @@ -37572,6 +37774,24 @@ snapshots: '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': optional: true + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.8.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -39476,6 +39696,19 @@ snapshots: - utf-8-validate - vue-tsc + '@scure/base@1.2.6': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@sec-ant/readable-stream@0.4.1': {} '@selderee/plugin-htmlparser2@0.11.0': @@ -40748,6 +40981,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + '@types/node@24.0.10': dependencies: undici-types: 7.8.0 @@ -41188,6 +41425,11 @@ snapshots: abbrev@3.0.1: {} + abitype@1.1.0(typescript@5.9.2)(zod@4.0.14): + optionalDependencies: + typescript: 5.9.2 + zod: 4.0.14 + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -41236,6 +41478,8 @@ snapshots: adm-zip@0.5.2: {} + aes-js@4.0.0-beta.5: {} + agent-base@6.0.2: dependencies: debug: 4.4.1(supports-color@10.0.0) @@ -41637,6 +41881,17 @@ snapshots: axe-core@4.10.2: {} + axios-mock-adapter@1.22.0(axios@1.11.0): + dependencies: + axios: 1.11.0(debug@3.2.7) + fast-deep-equal: 3.1.3 + is-buffer: 2.0.5 + + axios-retry@4.5.0(axios@1.11.0): + dependencies: + axios: 1.11.0(debug@3.2.7) + is-retry-allowed: 2.2.0 + axios@0.19.2: dependencies: follow-redirects: 1.5.10 @@ -41909,6 +42164,10 @@ snapshots: base-64@1.0.0: {} + base-x@3.0.11: + dependencies: + safe-buffer: 5.2.1 + base64-js@1.5.1: {} basic-ftp@5.0.5: {} @@ -41948,6 +42207,17 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 + bip32@4.0.0: + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + typeforce: 1.18.0 + wif: 2.0.6 + + bip39@3.1.0: + dependencies: + '@noble/hashes': 1.8.0 + birpc@2.4.0: {} bl@1.2.3: @@ -42048,6 +42318,8 @@ snapshots: dependencies: fill-range: 7.1.1 + brorand@1.1.0: {} + browser-request@0.3.3: {} browserslist@4.24.2: @@ -42061,6 +42333,16 @@ snapshots: dependencies: fast-json-stable-stringify: 2.1.0 + bs58@4.0.1: + dependencies: + base-x: 3.0.11 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + bser@2.1.1: dependencies: node-int64: 0.4.0 @@ -43058,6 +43340,8 @@ snapshots: decamelize@1.2.0: {} + decimal.js@10.6.0: {} + decode-named-character-reference@1.0.2: dependencies: character-entities: 2.0.2 @@ -43435,6 +43719,10 @@ snapshots: dependencies: safe-buffer: 5.2.1 + ed2curve@0.3.0: + dependencies: + tweetnacl: 1.0.3 + ee-first@1.1.1: {} eivindfjeldstad-dot@0.0.1: {} @@ -43445,6 +43733,16 @@ snapshots: electron-to-chromium@1.5.64: {} + elliptic@6.6.1: + dependencies: + bn.js: 4.12.1 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + emitter-component@1.1.2: {} emittery@0.13.1: {} @@ -44133,6 +44431,19 @@ snapshots: etag@1.8.1: {} + ethers@6.15.0: + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + event-emitter@0.3.5: dependencies: d: 1.0.2 @@ -45672,6 +45983,11 @@ snapshots: readable-stream: 3.6.2 safe-buffer: 5.2.1 + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -45718,6 +46034,12 @@ snapshots: hexoid@1.0.0: {} + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + hoist-non-react-statics@3.3.2: dependencies: react-is: 16.13.1 @@ -46303,6 +46625,8 @@ snapshots: dependencies: is-unc-path: 1.0.0 + is-retry-allowed@2.2.0: {} + is-set@2.0.3: {} is-shared-array-buffer@1.0.3: @@ -46408,6 +46732,10 @@ snapshots: dependencies: ws: 8.7.0 + isows@1.0.7(ws@8.18.3): + dependencies: + ws: 8.18.3 + isstream@0.1.2: {} istanbul-lib-coverage@3.2.0: {} @@ -47018,6 +47346,8 @@ snapshots: jose@4.15.5: {} + jose@5.10.0: {} + jose@5.9.6: {} joycon@3.1.1: {} @@ -48286,6 +48616,8 @@ snapshots: minimalistic-assert@1.0.1: {} + minimalistic-crypto-utils@1.0.1: {} + minimatch@10.0.1: dependencies: brace-expansion: 2.0.1 @@ -48731,6 +49063,8 @@ snapshots: node-abort-controller@3.1.1: {} + node-addon-api@5.1.0: {} + node-addon-api@6.1.0: {} node-addon-api@7.1.1: {} @@ -49278,6 +49612,21 @@ snapshots: lodash.isequal: 4.5.0 vali-date: 1.0.0 + ox@0.9.3(typescript@5.9.2)(zod@4.0.14): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.0(typescript@5.9.2)(zod@4.0.14) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - zod + p-cancelable@2.1.1: {} p-cancelable@3.0.0: {} @@ -51115,6 +51464,12 @@ snapshots: scmp@2.1.0: {} + secp256k1@5.0.1: + dependencies: + elliptic: 6.6.1 + node-addon-api: 5.1.0 + node-gyp-build: 4.8.4 + secure-json-parse@2.7.0: {} seek-bzip@1.0.6: @@ -52527,6 +52882,8 @@ snapshots: tslib@1.14.1: {} + tslib@2.7.0: {} + tslib@2.8.1: {} tslint@5.14.0(typescript@5.7.2): @@ -52658,6 +53015,8 @@ snapshots: tweetnacl@0.14.5: {} + tweetnacl@1.0.3: {} + twilio@3.84.1: dependencies: axios: 0.26.1 @@ -52749,6 +53108,8 @@ snapshots: typedarray@0.0.6: {} + typeforce@1.18.0: {} + typescript-eslint@8.15.0(eslint@8.57.1)(typescript@5.6.3): dependencies: '@typescript-eslint/eslint-plugin': 8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) @@ -53183,6 +53544,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 + viem@2.37.5(typescript@5.9.2)(zod@4.0.14): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.0(typescript@5.9.2)(zod@4.0.14) + isows: 1.0.7(ws@8.18.3) + ox: 0.9.3(typescript@5.9.2)(zod@4.0.14) + ws: 8.18.3 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + viesapi-client@1.2.7: dependencies: axios: 1.6.0 @@ -53372,6 +53750,10 @@ snapshots: dependencies: string-width: 7.2.0 + wif@2.0.6: + dependencies: + bs58check: 2.1.2 + wildcard@2.0.1: {} windows-release@6.1.0: @@ -53488,6 +53870,8 @@ snapshots: ws@8.16.0: {} + ws@8.17.1: {} + ws@8.18.0: {} ws@8.18.2: {} From 8268c0efb4cf6279ece9ffc0826ea74beff86448 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 16 Sep 2025 11:58:02 -0400 Subject: [PATCH 16/52] Hubspot - update search-crm (#18360) * update search-crm * limit results to one page * update version * package.json version --- .../hubspot/actions/search-crm/search-crm.mjs | 52 ++++++++++--------- components/hubspot/package.json | 2 +- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/components/hubspot/actions/search-crm/search-crm.mjs b/components/hubspot/actions/search-crm/search-crm.mjs index a879af3b5a1e1..12aa6cd77e206 100644 --- a/components/hubspot/actions/search-crm/search-crm.mjs +++ b/components/hubspot/actions/search-crm/search-crm.mjs @@ -4,7 +4,6 @@ import { DEFAULT_CONTACT_PROPERTIES, DEFAULT_DEAL_PROPERTIES, DEFAULT_LEAD_PROPERTIES, - DEFAULT_LIMIT, DEFAULT_LINE_ITEM_PROPERTIES, DEFAULT_PRODUCT_PROPERTIES, DEFAULT_TICKET_PROPERTIES, @@ -12,13 +11,14 @@ import { } from "../../common/constants.mjs"; import hubspot from "../../hubspot.app.mjs"; import common from "../common/common-create.mjs"; +const DEFAULT_LIMIT = 200; export default { key: "hubspot-search-crm", name: "Search CRM", description: "Search companies, contacts, deals, feedback submissions, products, tickets, line-items, quotes, leads, or custom objects. [See the documentation](https://developers.hubspot.com/docs/api/crm/search)", - version: "1.0.12", + version: "1.1.0", type: "action", props: { hubspot, @@ -52,6 +52,13 @@ export default { optional: true, reloadProps: true, }, + offset: { + type: "integer", + label: "Offset", + description: "The offset to start from. Used for pagination.", + default: 0, + optional: true, + }, }, async additionalProps() { const props = {}; @@ -224,23 +231,6 @@ export default { })) || [] ); }, - async paginate(params) { - let results; - const items = []; - while (!results || params.after) { - results = await this.hubspot.searchCRM(params); - if (results.paging) { - params.after = results.paging.next.after; - } else { - delete params.after; - } - results = results.results; - for (const result of results) { - items.push(result); - } - } - return items; - }, }, async run({ $ }) { const { @@ -251,6 +241,7 @@ export default { searchProperty, searchValue, exactMatch, + offset, /* eslint-disable no-unused-vars */ info, createIfNotFound, @@ -282,8 +273,18 @@ export default { properties: [ ...defaultProperties, ...additionalProperties, + searchProperty, ], + sorts: [ + { + propertyName: "createdate", + direction: "DESCENDING", + }, + ], + limit: DEFAULT_LIMIT, + after: offset, }; + if (exactMatch) { data.filters = [ { @@ -292,17 +293,17 @@ export default { value: searchValue, }, ]; - } else { - data.limit = DEFAULT_LIMIT; } - let results = await this.paginate({ + let { + results, paging, + } = await this.hubspot.searchCRM({ object: actualObjectType, data, }); if (!exactMatch) { - results = results.filter( + results = results?.filter( (result) => result.properties[searchProperty] && result.properties[searchProperty] @@ -328,6 +329,9 @@ export default { "$summary", `Successfully retrieved ${results?.length} object(s).`, ); - return results; + return { + results, + paging, + }; }, }; diff --git a/components/hubspot/package.json b/components/hubspot/package.json index f8fcd6358459d..9d6372eacca78 100644 --- a/components/hubspot/package.json +++ b/components/hubspot/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/hubspot", - "version": "1.7.4", + "version": "1.7.5", "description": "Pipedream Hubspot Components", "main": "hubspot.app.mjs", "keywords": [ From d5c554d75fead025b783aebeec6f725fd7a8d3cf Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 16 Sep 2025 21:35:30 -0400 Subject: [PATCH 17/52] Merging pull request #18347 * widget props * fix version --- .../hubspot/actions/common/common-page-prop.mjs | 12 ++++++++++++ .../create-landing-page/create-landing-page.mjs | 4 +++- .../hubspot/actions/create-page/create-page.mjs | 4 +++- components/hubspot/actions/list-pages/list-pages.mjs | 10 +++++----- .../update-landing-page/update-landing-page.mjs | 4 +++- .../hubspot/actions/update-page/update-page.mjs | 4 +++- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/components/hubspot/actions/common/common-page-prop.mjs b/components/hubspot/actions/common/common-page-prop.mjs index de1dce9727dfa..e96e359206ef9 100644 --- a/components/hubspot/actions/common/common-page-prop.mjs +++ b/components/hubspot/actions/common/common-page-prop.mjs @@ -76,4 +76,16 @@ export default { ], optional: true, }, + widgetContainers: { + type: "object", + label: "Widget Containers", + description: "A data structure containing the data for all the modules inside the containers for this page", + optional: true, + }, + widgets: { + type: "object", + label: "Widgets", + description: "A data structure containing the data for all the modules for this page", + optional: true, + }, }; diff --git a/components/hubspot/actions/create-landing-page/create-landing-page.mjs b/components/hubspot/actions/create-landing-page/create-landing-page.mjs index 76403a6d84c1f..44a18b8de2ef7 100644 --- a/components/hubspot/actions/create-landing-page/create-landing-page.mjs +++ b/components/hubspot/actions/create-landing-page/create-landing-page.mjs @@ -7,7 +7,7 @@ export default { name: "Create Landing Page", description: "Create a landing page in Hubspot. [See the documentation](https://developers.hubspot.com/docs/reference/api/cms/pages#post-%2Fcms%2Fv3%2Fpages%2Flanding-pages)", - version: "0.0.6", + version: "0.0.7", type: "action", props: { hubspot, @@ -44,6 +44,8 @@ export default { footerHtml: this.footerHtml, headHtml: this.headHtml, templatePath: this.templatePath, + widgetContainers: parseObject(this.widgetContainers), + widgets: parseObject(this.widgets), }, }); diff --git a/components/hubspot/actions/create-page/create-page.mjs b/components/hubspot/actions/create-page/create-page.mjs index 97979fe74b733..fd49610dc4467 100644 --- a/components/hubspot/actions/create-page/create-page.mjs +++ b/components/hubspot/actions/create-page/create-page.mjs @@ -7,7 +7,7 @@ export default { name: "Create Page", description: "Create a page in HubSpot. [See the documentation](https://developers.hubspot.com/docs/reference/api/cms/pages#post-%2Fcms%2Fv3%2Fpages%2Fsite-pages)", - version: "0.0.6", + version: "0.0.7", type: "action", props: { hubspot, @@ -36,6 +36,8 @@ export default { footerHtml: this.footerHtml, headHtml: this.headHtml, templatePath: this.templatePath, + widgetContainers: parseObject(this.widgetContainers), + widgets: parseObject(this.widgets), }, }); diff --git a/components/hubspot/actions/list-pages/list-pages.mjs b/components/hubspot/actions/list-pages/list-pages.mjs index 6b59086558983..cda2cdaac62c2 100644 --- a/components/hubspot/actions/list-pages/list-pages.mjs +++ b/components/hubspot/actions/list-pages/list-pages.mjs @@ -5,7 +5,7 @@ export default { name: "List Pages", description: "Retrieves a list of site pages. [See the documentation](https://developers.hubspot.com/docs/reference/api/cms/pages)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { hubspot, @@ -79,7 +79,7 @@ export default { }, }, async run({ $ }) { - const results = []; + const pages = []; let hasMore, count = 0; @@ -105,7 +105,7 @@ export default { break; } for (const item of results) { - results.push(item); + pages.push(item); count++; if (count >= this.maxResults) { break; @@ -117,10 +117,10 @@ export default { $.export( "$summary", - `Found ${results.length} page${results.length === 1 + `Found ${pages.length} page${pages.length === 1 ? "" : "s"}`, ); - return results; + return pages; }, }; diff --git a/components/hubspot/actions/update-landing-page/update-landing-page.mjs b/components/hubspot/actions/update-landing-page/update-landing-page.mjs index 60f871da9439e..30a5c1d10aa3f 100644 --- a/components/hubspot/actions/update-landing-page/update-landing-page.mjs +++ b/components/hubspot/actions/update-landing-page/update-landing-page.mjs @@ -7,7 +7,7 @@ export default { name: "Update Landing Page", description: "Update a landing page in HubSpot. [See the documentation](https://developers.hubspot.com/docs/reference/api/cms/pages#patch-%2Fcms%2Fv3%2Fpages%2Flanding-pages%2F%7Bobjectid%7D)", - version: "0.0.6", + version: "0.0.7", type: "action", props: { hubspot, @@ -53,6 +53,8 @@ export default { footerHtml: this.footerHtml, headHtml: this.headHtml, templatePath: this.templatePath, + widgetContainers: parseObject(this.widgetContainers), + widgets: parseObject(this.widgets), }, }); diff --git a/components/hubspot/actions/update-page/update-page.mjs b/components/hubspot/actions/update-page/update-page.mjs index 0e4e6ae011f70..744ba34ac923f 100644 --- a/components/hubspot/actions/update-page/update-page.mjs +++ b/components/hubspot/actions/update-page/update-page.mjs @@ -7,7 +7,7 @@ export default { name: "Update Page", description: "Update a page in Hubspot. [See the documentation](https://developers.hubspot.com/docs/reference/api/cms/pages#patch-%2Fcms%2Fv3%2Fpages%2Fsite-pages%2F%7Bobjectid%7D)", - version: "0.0.6", + version: "0.0.7", type: "action", props: { hubspot, @@ -45,6 +45,8 @@ export default { footerHtml: this.footerHtml, headHtml: this.headHtml, templatePath: this.templatePath, + widgetContainers: parseObject(this.widgetContainers), + widgets: parseObject(this.widgets), }, }); From 07aa960064c708503dea5ee6564ce5eeafc28817 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Tue, 16 Sep 2025 19:33:08 -0700 Subject: [PATCH 18/52] Adding app scaffolding for rundeck --- components/rundeck/package.json | 15 +++++++++++++++ components/rundeck/rundeck.app.mjs | 11 +++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/rundeck/package.json create mode 100644 components/rundeck/rundeck.app.mjs diff --git a/components/rundeck/package.json b/components/rundeck/package.json new file mode 100644 index 0000000000000..d6209df55d32f --- /dev/null +++ b/components/rundeck/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/rundeck", + "version": "0.0.1", + "description": "Pipedream Rundeck Components", + "main": "rundeck.app.mjs", + "keywords": [ + "pipedream", + "rundeck" + ], + "homepage": "https://pipedream.com/apps/rundeck", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/components/rundeck/rundeck.app.mjs b/components/rundeck/rundeck.app.mjs new file mode 100644 index 0000000000000..eb18a9222075a --- /dev/null +++ b/components/rundeck/rundeck.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "rundeck", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index afd66a8a07874..b505679354d5b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12268,6 +12268,9 @@ importers: specifier: ^3.0.3 version: 3.0.3 + components/rundeck: + specifiers: {} + components/runpod: {} components/runsignup: {} From cef1e1b98af5b3087e051642a5517609e7b2a49c Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 17 Sep 2025 00:02:51 -0300 Subject: [PATCH 19/52] Merging pull request #18378 * Update Taiga component with new actions and sources - Bump version to 0.1.0 in package.json and add dependency on @pipedream/platform. - Introduce new actions for creating, updating, and deleting issues, tasks, and user stories. - Add sources for tracking changes and deletions of issues and tasks. - Implement utility functions for parsing and cleaning objects in common/utils.mjs. - Enhance prop definitions for better integration with Taiga API. * pnpm update * Refactor Taiga actions to utilize parseObject utility - Added parseObject utility for tags, watchers, and points in update-issue, update-task, and update-userstory actions. - Removed the update-project action as it is no longer needed. - Enhanced base source to include secret key validation for webhook security. --- .../actions/create-issue/create-issue.mjs | 151 +++++ .../taiga/actions/create-task/create-task.mjs | 141 ++++ .../create-userstory/create-userstory.mjs | 161 +++++ .../actions/delete-issue/delete-issue.mjs | 36 + .../taiga/actions/delete-task/delete-task.mjs | 36 + .../delete-userstory/delete-userstory.mjs | 36 + .../taiga/actions/get-issue/get-issue.mjs | 36 + .../actions/get-userstory/get-userstory.mjs | 36 + .../actions/update-issue/update-issue.mjs | 168 +++++ .../taiga/actions/update-task/update-task.mjs | 157 +++++ .../update-userstory/update-userstory.mjs | 175 +++++ components/taiga/common/utils.mjs | 41 ++ components/taiga/package.json | 7 +- .../changed-issue-instant.mjs | 22 + .../changed-issue-instant/test-event.mjs | 81 +++ .../changed-issue-status-instant.mjs | 22 + .../test-event.mjs | 81 +++ .../changed-task-instant.mjs | 22 + .../changed-task-instant/test-event.mjs | 198 ++++++ .../changed-task-status-instant.mjs | 22 + .../test-event.mjs | 198 ++++++ components/taiga/sources/common/base.mjs | 83 +++ .../deleted-issue-instant.mjs | 22 + .../deleted-issue-instant/test-event.mjs | 68 ++ .../deleted-task-instant.mjs | 22 + .../deleted-task-instant/test-event.mjs | 172 +++++ .../new-issue-instant/new-issue-instant.mjs | 22 + .../sources/new-issue-instant/test-event.mjs | 68 ++ .../new-task-instant/new-task-instant.mjs | 22 + .../sources/new-task-instant/test-event.mjs | 185 +++++ components/taiga/taiga.app.mjs | 633 +++++++++++++++++- pnpm-lock.yaml | 6 +- 32 files changed, 3122 insertions(+), 8 deletions(-) create mode 100644 components/taiga/actions/create-issue/create-issue.mjs create mode 100644 components/taiga/actions/create-task/create-task.mjs create mode 100644 components/taiga/actions/create-userstory/create-userstory.mjs create mode 100644 components/taiga/actions/delete-issue/delete-issue.mjs create mode 100644 components/taiga/actions/delete-task/delete-task.mjs create mode 100644 components/taiga/actions/delete-userstory/delete-userstory.mjs create mode 100644 components/taiga/actions/get-issue/get-issue.mjs create mode 100644 components/taiga/actions/get-userstory/get-userstory.mjs create mode 100644 components/taiga/actions/update-issue/update-issue.mjs create mode 100644 components/taiga/actions/update-task/update-task.mjs create mode 100644 components/taiga/actions/update-userstory/update-userstory.mjs create mode 100644 components/taiga/common/utils.mjs create mode 100644 components/taiga/sources/changed-issue-instant/changed-issue-instant.mjs create mode 100644 components/taiga/sources/changed-issue-instant/test-event.mjs create mode 100644 components/taiga/sources/changed-issue-status-instant/changed-issue-status-instant.mjs create mode 100644 components/taiga/sources/changed-issue-status-instant/test-event.mjs create mode 100644 components/taiga/sources/changed-task-instant/changed-task-instant.mjs create mode 100644 components/taiga/sources/changed-task-instant/test-event.mjs create mode 100644 components/taiga/sources/changed-task-status-instant/changed-task-status-instant.mjs create mode 100644 components/taiga/sources/changed-task-status-instant/test-event.mjs create mode 100644 components/taiga/sources/common/base.mjs create mode 100644 components/taiga/sources/deleted-issue-instant/deleted-issue-instant.mjs create mode 100644 components/taiga/sources/deleted-issue-instant/test-event.mjs create mode 100644 components/taiga/sources/deleted-task-instant/deleted-task-instant.mjs create mode 100644 components/taiga/sources/deleted-task-instant/test-event.mjs create mode 100644 components/taiga/sources/new-issue-instant/new-issue-instant.mjs create mode 100644 components/taiga/sources/new-issue-instant/test-event.mjs create mode 100644 components/taiga/sources/new-task-instant/new-task-instant.mjs create mode 100644 components/taiga/sources/new-task-instant/test-event.mjs diff --git a/components/taiga/actions/create-issue/create-issue.mjs b/components/taiga/actions/create-issue/create-issue.mjs new file mode 100644 index 0000000000000..99e29d4ce0805 --- /dev/null +++ b/components/taiga/actions/create-issue/create-issue.mjs @@ -0,0 +1,151 @@ +import { parseObject } from "../../common/utils.mjs"; +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-create-issue", + name: "Create Issue", + description: "Create a new issue in a Taiga project. [See the documentation](https://docs.taiga.io/api.html#issues-create)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + subject: { + propDefinition: [ + taiga, + "issueSubject", + ], + }, + description: { + propDefinition: [ + taiga, + "issueDescription", + ], + optional: true, + }, + priority: { + propDefinition: [ + taiga, + "issuePriority", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + severity: { + propDefinition: [ + taiga, + "issueSeverity", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + status: { + propDefinition: [ + taiga, + "issueStatus", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + type: { + propDefinition: [ + taiga, + "issueType", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + assignedTo: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "Assigned To", + description: "User to assign the issue to", + optional: true, + }, + milestone: { + propDefinition: [ + taiga, + "milestone", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + tags: { + propDefinition: [ + taiga, + "tags", + ], + optional: true, + }, + blockedNote: { + propDefinition: [ + taiga, + "issueBlockedNote", + ], + optional: true, + }, + isBlocked: { + propDefinition: [ + taiga, + "isBlocked", + ], + optional: true, + }, + watchers: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + type: "string[]", + label: "Watchers", + description: "Users to watch the issue", + optional: true, + }, + }, + async run({ $ }) { + const response = await this.taiga.createIssue({ + $, + data: { + subject: this.subject, + description: this.description, + project: this.projectId, + priority: this.priority, + severity: this.severity, + status: this.status, + type: this.type, + assigned_to: this.assignedTo, + tags: parseObject(this.tags), + blocked_note: this.blockedNote, + is_blocked: this.isBlocked, + milestone: this.milestone, + watchers: parseObject(this.watchers), + }, + }); + + $.export("$summary", `Created issue: ${response.id}`); + return response; + }, +}; diff --git a/components/taiga/actions/create-task/create-task.mjs b/components/taiga/actions/create-task/create-task.mjs new file mode 100644 index 0000000000000..05aadb354c8d3 --- /dev/null +++ b/components/taiga/actions/create-task/create-task.mjs @@ -0,0 +1,141 @@ +import { parseObject } from "../../common/utils.mjs"; +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-create-task", + name: "Create Task", + description: "Create a new task in a Taiga project. [See the documentation](https://docs.taiga.io/api.html#tasks-create)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + subject: { + propDefinition: [ + taiga, + "taskSubject", + ], + }, + description: { + propDefinition: [ + taiga, + "taskDescription", + ], + optional: true, + }, + isBlocked: { + propDefinition: [ + taiga, + "isBlocked", + ], + description: "Whether the task is blocked", + optional: true, + }, + milestone: { + propDefinition: [ + taiga, + "milestone", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + status: { + propDefinition: [ + taiga, + "taskStatus", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + assignedTo: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "Assigned To", + description: "User to assign the task to", + optional: true, + }, + userStoryId: { + propDefinition: [ + taiga, + "userStoryId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "User Story", + description: "User story to associate the task with", + optional: true, + }, + usOrder: { + propDefinition: [ + taiga, + "usOrder", + ], + optional: true, + }, + taskboardOrder: { + propDefinition: [ + taiga, + "taskboardOrder", + ], + optional: true, + }, + tags: { + propDefinition: [ + taiga, + "tags", + ], + description: "Tags to associate with the task", + optional: true, + }, + watchers: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + type: "string[]", + label: "Watchers", + description: "Users to watch the task", + optional: true, + }, + }, + async run({ $ }) { + const response = await this.taiga.createTask({ + $, + data: { + subject: this.subject, + description: this.description, + project: this.projectId, + status: this.status, + assigned_to: this.assignedTo, + user_story: this.userStoryId, + tags: parseObject(this.tags), + is_blocked: this.isBlocked, + milestone: this.milestone, + user_story_order: this.usOrder, + taskboard_order: this.taskboardOrder, + watchers: parseObject(this.watchers), + }, + }); + + $.export("$summary", `Created task: ${response.id}`); + return response; + }, +}; diff --git a/components/taiga/actions/create-userstory/create-userstory.mjs b/components/taiga/actions/create-userstory/create-userstory.mjs new file mode 100644 index 0000000000000..ba2265cd10eba --- /dev/null +++ b/components/taiga/actions/create-userstory/create-userstory.mjs @@ -0,0 +1,161 @@ +import { parseObject } from "../../common/utils.mjs"; +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-create-userstory", + name: "Create User Story", + description: "Create a new user story in a Taiga project. [See the documentation](https://docs.taiga.io/api.html#user-stories-create)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + subject: { + propDefinition: [ + taiga, + "userStorySubject", + ], + }, + description: { + propDefinition: [ + taiga, + "userStoryDescription", + ], + optional: true, + }, + status: { + propDefinition: [ + taiga, + "userStoryStatus", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + assignedTo: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "Assigned To", + description: "User to assign the user story to", + optional: true, + }, + tags: { + propDefinition: [ + taiga, + "tags", + ], + description: "Tags to associate with the user story", + optional: true, + }, + backlogOrder: { + propDefinition: [ + taiga, + "backlogOrder", + ], + optional: true, + }, + kanbanOrder: { + propDefinition: [ + taiga, + "kanbanOrder", + ], + optional: true, + }, + sprintOrder: { + propDefinition: [ + taiga, + "sprintOrder", + ], + optional: true, + }, + clientRequirement: { + propDefinition: [ + taiga, + "clientRequirement", + ], + optional: true, + }, + isBlocked: { + propDefinition: [ + taiga, + "isBlocked", + ], + description: "Whether the user story is blocked", + optional: true, + }, + milestone: { + propDefinition: [ + taiga, + "milestone", + ({ projectId }) => ({ + projectId, + }), + ], + description: "Milestone to associate the user story with", + optional: true, + }, + points: { + propDefinition: [ + taiga, + "points", + ], + optional: true, + }, + teamRequirement: { + propDefinition: [ + taiga, + "teamRequirement", + ], + optional: true, + }, + watchers: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + type: "string[]", + label: "Watchers", + description: "Users to watch the user story", + optional: true, + }, + }, + async run({ $ }) { + const response = await this.taiga.createUserStory({ + $, + data: { + subject: this.subject, + description: this.description, + project: this.projectId, + status: this.status, + assigned_to: this.assignedTo, + tags: parseObject(this.tags), + backlog_order: this.backlogOrder, + client_requirement: this.clientRequirement, + is_blocked: this.isBlocked, + milestone: this.milestone, + points: parseObject(this.points), + kanban_order: this.kanbanOrder, + sprint_order: this.sprintOrder, + team_requirement: this.teamRequirement, + watchers: parseObject(this.watchers), + }, + }); + + $.export("$summary", `Created user story: ${response.subject}`); + return response; + }, +}; diff --git a/components/taiga/actions/delete-issue/delete-issue.mjs b/components/taiga/actions/delete-issue/delete-issue.mjs new file mode 100644 index 0000000000000..1272f33544425 --- /dev/null +++ b/components/taiga/actions/delete-issue/delete-issue.mjs @@ -0,0 +1,36 @@ +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-delete-issue", + name: "Delete Issue", + description: "Delete an existing issue from a Taiga project. [See the documentation](https://docs.taiga.io/api.html#issues-delete)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + issueId: { + propDefinition: [ + taiga, + "issueId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + }, + async run({ $ }) { + const response = await this.taiga.deleteIssue({ + $, + issueId: this.issueId, + }); + + $.export("$summary", `Deleted issue: ${this.issueId}`); + return response; + }, +}; diff --git a/components/taiga/actions/delete-task/delete-task.mjs b/components/taiga/actions/delete-task/delete-task.mjs new file mode 100644 index 0000000000000..6be7783428255 --- /dev/null +++ b/components/taiga/actions/delete-task/delete-task.mjs @@ -0,0 +1,36 @@ +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-delete-task", + name: "Delete Task", + description: "Delete an existing task from a Taiga project. [See the documentation](https://docs.taiga.io/api.html#tasks-delete)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + taskId: { + propDefinition: [ + taiga, + "taskId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + }, + async run({ $ }) { + const response = await this.taiga.deleteTask({ + $, + taskId: this.taskId, + }); + + $.export("$summary", `Deleted task: ${this.taskId}`); + return response; + }, +}; diff --git a/components/taiga/actions/delete-userstory/delete-userstory.mjs b/components/taiga/actions/delete-userstory/delete-userstory.mjs new file mode 100644 index 0000000000000..a4dfc07254b5a --- /dev/null +++ b/components/taiga/actions/delete-userstory/delete-userstory.mjs @@ -0,0 +1,36 @@ +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-delete-userstory", + name: "Delete User Story", + description: "Delete an existing user story from a Taiga project. [See the documentation](https://docs.taiga.io/api.html#user-stories-delete)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + userStoryId: { + propDefinition: [ + taiga, + "userStoryId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + }, + async run({ $ }) { + const response = await this.taiga.deleteUserStory({ + $, + userStoryId: this.userStoryId, + }); + + $.export("$summary", `Deleted user story: ${this.userStoryId}`); + return response; + }, +}; diff --git a/components/taiga/actions/get-issue/get-issue.mjs b/components/taiga/actions/get-issue/get-issue.mjs new file mode 100644 index 0000000000000..ff3d7a5d39373 --- /dev/null +++ b/components/taiga/actions/get-issue/get-issue.mjs @@ -0,0 +1,36 @@ +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-get-issue", + name: "Get Issue", + description: "Get an existing issue from a Taiga project. [See the documentation](https://docs.taiga.io/api.html#issues-get)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + issueId: { + propDefinition: [ + taiga, + "issueId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + }, + async run({ $ }) { + const response = await this.taiga.getIssue({ + $, + issueId: this.issueId, + }); + + $.export("$summary", `Retrieved issue: ${response.id}`); + return response; + }, +}; diff --git a/components/taiga/actions/get-userstory/get-userstory.mjs b/components/taiga/actions/get-userstory/get-userstory.mjs new file mode 100644 index 0000000000000..d44f03f6811b7 --- /dev/null +++ b/components/taiga/actions/get-userstory/get-userstory.mjs @@ -0,0 +1,36 @@ +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-get-userstory", + name: "Get User Story", + description: "Get an existing user story from a Taiga project. [See the documentation](https://docs.taiga.io/api.html#user-stories-get)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + userStoryId: { + propDefinition: [ + taiga, + "userStoryId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + }, + async run({ $ }) { + const response = await this.taiga.getUserStory({ + $, + userStoryId: this.userStoryId, + }); + + $.export("$summary", `Retrieved user story: ${this.userStoryId}`); + return response; + }, +}; diff --git a/components/taiga/actions/update-issue/update-issue.mjs b/components/taiga/actions/update-issue/update-issue.mjs new file mode 100644 index 0000000000000..5d6726245fd29 --- /dev/null +++ b/components/taiga/actions/update-issue/update-issue.mjs @@ -0,0 +1,168 @@ +import { + cleanObj, parseObject, +} from "../../common/utils.mjs"; +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-update-issue", + name: "Update Issue", + description: "Update an existing issue in a Taiga project. [See the documentation](https://docs.taiga.io/api.html#issues-edit)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + issueId: { + propDefinition: [ + taiga, + "issueId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + subject: { + propDefinition: [ + taiga, + "issueSubject", + ], + optional: true, + }, + description: { + propDefinition: [ + taiga, + "issueDescription", + ], + optional: true, + }, + priority: { + propDefinition: [ + taiga, + "issuePriority", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + severity: { + propDefinition: [ + taiga, + "issueSeverity", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + status: { + propDefinition: [ + taiga, + "issueStatus", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + type: { + propDefinition: [ + taiga, + "issueType", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + assignedTo: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "Assigned To", + description: "User to assign the issue to", + optional: true, + }, + milestone: { + propDefinition: [ + taiga, + "milestone", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + tags: { + propDefinition: [ + taiga, + "tags", + ], + optional: true, + }, + blockedNote: { + propDefinition: [ + taiga, + "issueBlockedNote", + ], + optional: true, + }, + isBlocked: { + propDefinition: [ + taiga, + "isBlocked", + ], + optional: true, + }, + watchers: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + type: "string[]", + label: "Watchers", + description: "Users to watch the issue", + optional: true, + }, + }, + async run({ $ }) { + const issue = await this.taiga.getIssue({ + issueId: this.issueId, + }); + const response = await this.taiga.updateIssue({ + $, + issueId: this.issueId, + data: cleanObj({ + version: issue.version, + subject: this.subject, + description: this.description, + priority: this.priority, + severity: this.severity, + status: this.status, + type: this.type, + assigned_to: this.assignedTo, + tags: parseObject(this.tags), + blocked_note: this.blockedNote, + is_blocked: this.isBlocked, + milestone: this.milestone, + watchers: parseObject(this.watchers), + project: this.projectId, + }), + }); + + $.export("$summary", `Updated issue: ${response.id}`); + return response; + }, +}; diff --git a/components/taiga/actions/update-task/update-task.mjs b/components/taiga/actions/update-task/update-task.mjs new file mode 100644 index 0000000000000..d1f85b49929c9 --- /dev/null +++ b/components/taiga/actions/update-task/update-task.mjs @@ -0,0 +1,157 @@ +import { + cleanObj, parseObject, +} from "../../common/utils.mjs"; +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-update-task", + name: "Update Task", + description: "Update an existing task in a Taiga project. [See the documentation](https://docs.taiga.io/api.html#tasks-edit)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + taskId: { + propDefinition: [ + taiga, + "taskId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + subject: { + propDefinition: [ + taiga, + "taskSubject", + ], + optional: true, + }, + description: { + propDefinition: [ + taiga, + "taskDescription", + ], + optional: true, + }, + isBlocked: { + propDefinition: [ + taiga, + "isBlocked", + ], + description: "Whether the task is blocked", + optional: true, + }, + milestone: { + propDefinition: [ + taiga, + "milestone", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + status: { + propDefinition: [ + taiga, + "taskStatus", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + assignedTo: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "Assigned To", + description: "User to assign the task to", + optional: true, + }, + userStoryId: { + propDefinition: [ + taiga, + "userStoryId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "User Story", + description: "User story to associate the task with", + optional: true, + }, + usOrder: { + propDefinition: [ + taiga, + "usOrder", + ], + optional: true, + }, + taskboardOrder: { + propDefinition: [ + taiga, + "taskboardOrder", + ], + optional: true, + }, + tags: { + propDefinition: [ + taiga, + "tags", + ], + description: "Tags to associate with the task", + optional: true, + }, + watchers: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + type: "string[]", + label: "Watchers", + description: "Users to watch the task", + optional: true, + }, + }, + async run({ $ }) { + const task = await this.taiga.getTask({ + taskId: this.taskId, + }); + const response = await this.taiga.updateTask({ + $, + taskId: this.taskId, + data: cleanObj({ + version: task.version, + subject: this.subject, + description: this.description, + status: this.status, + assigned_to: this.assignedTo, + user_story: this.userStoryId, + tags: parseObject(this.tags), + watchers: parseObject(this.watchers), + is_blocked: this.isBlocked, + milestone: this.milestone, + us_order: this.usOrder, + taskboard_order: this.taskboardOrder, + }), + }); + + $.export("$summary", `Updated task: ${response.id}`); + return response; + }, +}; diff --git a/components/taiga/actions/update-userstory/update-userstory.mjs b/components/taiga/actions/update-userstory/update-userstory.mjs new file mode 100644 index 0000000000000..6061e85716f17 --- /dev/null +++ b/components/taiga/actions/update-userstory/update-userstory.mjs @@ -0,0 +1,175 @@ +import { + cleanObj, parseObject, +} from "../../common/utils.mjs"; +import taiga from "../../taiga.app.mjs"; + +export default { + key: "taiga-update-userstory", + name: "Update User Story", + description: "Update an existing user story in a Taiga project. [See the documentation](https://docs.taiga.io/api.html#_user_stories)", + version: "0.0.1", + type: "action", + props: { + taiga, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + userStoryId: { + propDefinition: [ + taiga, + "userStoryId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + subject: { + propDefinition: [ + taiga, + "userStorySubject", + ], + optional: true, + }, + description: { + propDefinition: [ + taiga, + "userStoryDescription", + ], + optional: true, + }, + status: { + propDefinition: [ + taiga, + "userStoryStatus", + ({ projectId }) => ({ + projectId, + }), + ], + optional: true, + }, + assignedTo: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + label: "Assigned To", + description: "User to assign the user story to", + optional: true, + }, + tags: { + propDefinition: [ + taiga, + "tags", + ], + description: "Tags to associate with the user story", + optional: true, + }, + backlogOrder: { + propDefinition: [ + taiga, + "backlogOrder", + ], + optional: true, + }, + kanbanOrder: { + propDefinition: [ + taiga, + "kanbanOrder", + ], + optional: true, + }, + sprintOrder: { + propDefinition: [ + taiga, + "sprintOrder", + ], + optional: true, + }, + clientRequirement: { + propDefinition: [ + taiga, + "clientRequirement", + ], + optional: true, + }, + isBlocked: { + propDefinition: [ + taiga, + "isBlocked", + ], + description: "Whether the user story is blocked", + optional: true, + }, + milestone: { + propDefinition: [ + taiga, + "milestone", + ({ projectId }) => ({ + projectId, + }), + ], + description: "Milestone to associate the user story with", + optional: true, + }, + points: { + propDefinition: [ + taiga, + "points", + ], + optional: true, + }, + teamRequirement: { + propDefinition: [ + taiga, + "teamRequirement", + ], + optional: true, + }, + watchers: { + propDefinition: [ + taiga, + "userId", + ({ projectId }) => ({ + projectId, + }), + ], + type: "string[]", + label: "Watchers", + description: "Users to watch the user story", + optional: true, + }, + }, + async run({ $ }) { + const userStory = await this.taiga.getUserStory({ + userStoryId: this.userStoryId, + }); + const response = await this.taiga.updateUserStory({ + $, + userStoryId: this.userStoryId, + data: cleanObj({ + version: userStory.version, + subject: this.subject, + description: this.description, + status: this.status, + assigned_to: this.assignedTo, + tags: parseObject(this.tags), + backlog_order: this.backlogOrder, + client_requirement: this.clientRequirement, + is_blocked: this.isBlocked, + milestone: this.milestone, + points: parseObject(this.points), + team_requirement: this.teamRequirement, + watchers: parseObject(this.watchers), + }), + }); + + $.export("$summary", `Updated user story: ${response.id}`); + return response; + }, +}; diff --git a/components/taiga/common/utils.mjs b/components/taiga/common/utils.mjs new file mode 100644 index 0000000000000..4d412a63ac1b5 --- /dev/null +++ b/components/taiga/common/utils.mjs @@ -0,0 +1,41 @@ +export const parseObject = (obj) => { + if (!obj) return undefined; + + if (Array.isArray(obj)) { + return obj.map((item) => { + if (typeof item === "string") { + try { + return JSON.parse(item); + } catch (e) { + return item; + } + } + return item; + }); + } + if (typeof obj === "string") { + try { + return JSON.parse(obj); + } catch (e) { + return obj; + } + } + return obj; +}; + +export const cleanObj = (obj) => { + return Object.entries(obj) + .filter(([ + , + v, + ]) => ((v != null && v != "" && JSON.stringify(v) != "{}") || typeof v === "boolean")) + .reduce((acc, [ + k, + v, + ]) => ({ + ...acc, + [k]: (!Array.isArray(v) && v === Object(v)) + ? cleanObj(v) + : v, + }), {}); +}; diff --git a/components/taiga/package.json b/components/taiga/package.json index ad12132baf535..f09f59607bb7b 100644 --- a/components/taiga/package.json +++ b/components/taiga/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/taiga", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Taiga Components", "main": "taiga.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.1.0" } -} \ No newline at end of file +} diff --git a/components/taiga/sources/changed-issue-instant/changed-issue-instant.mjs b/components/taiga/sources/changed-issue-instant/changed-issue-instant.mjs new file mode 100644 index 0000000000000..e0eb8fa3975eb --- /dev/null +++ b/components/taiga/sources/changed-issue-instant/changed-issue-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-changed-issue-instant", + name: "Changed Issue (Instant)", + description: "Emit new event when an issue is updated in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `Changed Issue: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "issue" && body.action === "change" && !body.change.diff.status; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/changed-issue-instant/test-event.mjs b/components/taiga/sources/changed-issue-instant/test-event.mjs new file mode 100644 index 0000000000000..650f248c5acd7 --- /dev/null +++ b/components/taiga/sources/changed-issue-instant/test-event.mjs @@ -0,0 +1,81 @@ +export default { + "action": "change", + "type": "issue", + "by": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "date": "2025-09-16T14:00:23.279Z", + "data": { + "custom_attributes_values": {}, + "id": 123, + "ref": 123, + "created_date": "2025-09-16T13:45:14.508Z", + "modified_date": "2025-09-16T14:00:23.239Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "subject", + "external_reference": null, + "watchers": [], + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/issue/123", + "project": { + "id": 123, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "milestone": null, + "owner": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false + }, + "type": { + "id": 123, + "name": "Bug", + "color": "#E44057" + }, + "priority": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "severity": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "promoted_to": [] + }, + "change": { + "comment": "", + "comment_html": "", + "delete_comment_date": null, + "comment_versions": null, + "edit_comment_date": null, + "diff": { + "subject": { + "from": "subject", + "to": "changed subject" + } + } + } +} \ No newline at end of file diff --git a/components/taiga/sources/changed-issue-status-instant/changed-issue-status-instant.mjs b/components/taiga/sources/changed-issue-status-instant/changed-issue-status-instant.mjs new file mode 100644 index 0000000000000..36362baf0d6e7 --- /dev/null +++ b/components/taiga/sources/changed-issue-status-instant/changed-issue-status-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-changed-issue-status-instant", + name: "Changed Issue Status (Instant)", + description: "Emit new event when an issue status is changed in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `Changed Issue Status: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "issue" && body.action === "change" && body.change.diff.status; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/changed-issue-status-instant/test-event.mjs b/components/taiga/sources/changed-issue-status-instant/test-event.mjs new file mode 100644 index 0000000000000..8ee3c4deb0151 --- /dev/null +++ b/components/taiga/sources/changed-issue-status-instant/test-event.mjs @@ -0,0 +1,81 @@ +export default { + "action": "change", + "type": "issue", + "by": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "date": "2025-09-16T14:00:23.279Z", + "data": { + "custom_attributes_values": {}, + "id": 123, + "ref": 123, + "created_date": "2025-09-16T13:45:14.508Z", + "modified_date": "2025-09-16T14:00:23.239Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "subject", + "external_reference": null, + "watchers": [], + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/issue/123", + "project": { + "id": 123, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "milestone": null, + "owner": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false + }, + "type": { + "id": 123, + "name": "Bug", + "color": "#E44057" + }, + "priority": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "severity": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "promoted_to": [] + }, + "change": { + "comment": "", + "comment_html": "", + "delete_comment_date": null, + "comment_versions": null, + "edit_comment_date": null, + "diff": { + "status": { + "from": "In progress", + "to": "New" + } + } + } +} \ No newline at end of file diff --git a/components/taiga/sources/changed-task-instant/changed-task-instant.mjs b/components/taiga/sources/changed-task-instant/changed-task-instant.mjs new file mode 100644 index 0000000000000..06b5d81e37a72 --- /dev/null +++ b/components/taiga/sources/changed-task-instant/changed-task-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-changed-task-instant", + name: "Changed Task (Instant)", + description: "Emit new event when a task is updated in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `Changed Task: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "task" && body.action === "change" && !body.change.diff.status; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/changed-task-instant/test-event.mjs b/components/taiga/sources/changed-task-instant/test-event.mjs new file mode 100644 index 0000000000000..ac4641e2c6527 --- /dev/null +++ b/components/taiga/sources/changed-task-instant/test-event.mjs @@ -0,0 +1,198 @@ +export default { + "action": "change", + "type": "task", + "by": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4acf7f734332df6f6a65789330874e23" + }, + "date": "2025-09-16T14:07:00.458Z", + "data": { + "custom_attributes_values": {}, + "id": 123, + "ref": 15, + "created_date": "2025-09-16T14:06:23.334Z", + "modified_date": "2025-09-16T14:07:00.409Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "subject", + "us_order": 1758031583317, + "taskboard_order": 1758031583317, + "is_iocaine": false, + "external_reference": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/task/123", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "In progress", + "slug": "in-progress", + "color": "#E47C40", + "is_closed": false + }, + "user_story": { + "custom_attributes_values": {}, + "id": 8423509, + "ref": 123, + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "is_closed": false, + "created_date": "2025-09-15T19:13:09.501Z", + "modified_date": "2025-09-15T19:13:09.506Z", + "finish_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "user story subject", + "client_requirement": false, + "team_requirement": false, + "generated_from_issue": null, + "generated_from_task": null, + "from_task_ref": null, + "external_reference": null, + "tribe_gig": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/us/123", + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "assigned_users": [], + "points": [ + { + "role": "UX", + "name": "?", + "value": null + }, + { + "role": "Design", + "name": "?", + "value": null + }, + { + "role": "Front", + "name": "?", + "value": null + }, + { + "role": "Back", + "name": "?", + "value": null + }, + { + "role": "Stakeholder", + "name": "?", + "value": null + } + ], + "status": { + "id": 10498870, + "name": "In progress", + "slug": "new", + "color": "#70728F", + "is_closed": false, + "is_archived": false + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-test-01-2", + "estimated_start": "2025-09-15", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-15T15:28:48.984Z", + "modified_date": "2025-09-15T15:28:48.989Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4acf7f734332df6f6a65789330874e23" + } + } + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-test-01-2", + "estimated_start": "2025-09-15", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-15T15:28:48.984Z", + "modified_date": "2025-09-15T15:28:48.989Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + } + }, + "promoted_to": [] + }, + "change": { + "comment": "", + "comment_html": "", + "delete_comment_date": null, + "comment_versions": null, + "edit_comment_date": null, + "diff": { + "subject": { + "from": "subject", + "to": "changed subject" + } + } + } +} \ No newline at end of file diff --git a/components/taiga/sources/changed-task-status-instant/changed-task-status-instant.mjs b/components/taiga/sources/changed-task-status-instant/changed-task-status-instant.mjs new file mode 100644 index 0000000000000..dc73782b1102e --- /dev/null +++ b/components/taiga/sources/changed-task-status-instant/changed-task-status-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-changed-task-status-instant", + name: "Changed Task Status (Instant)", + description: "Emit new event when a task status is changed in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `Changed Task Status: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "task" && body.action === "change" && body.change.diff.status; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/changed-task-status-instant/test-event.mjs b/components/taiga/sources/changed-task-status-instant/test-event.mjs new file mode 100644 index 0000000000000..e34c5dac8881c --- /dev/null +++ b/components/taiga/sources/changed-task-status-instant/test-event.mjs @@ -0,0 +1,198 @@ +export default { + "action": "change", + "type": "task", + "by": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4acf7f734332df6f6a65789330874e23" + }, + "date": "2025-09-16T14:07:00.458Z", + "data": { + "custom_attributes_values": {}, + "id": 123, + "ref": 15, + "created_date": "2025-09-16T14:06:23.334Z", + "modified_date": "2025-09-16T14:07:00.409Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "subject", + "us_order": 1758031583317, + "taskboard_order": 1758031583317, + "is_iocaine": false, + "external_reference": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/task/123", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "In progress", + "slug": "in-progress", + "color": "#E47C40", + "is_closed": false + }, + "user_story": { + "custom_attributes_values": {}, + "id": 8423509, + "ref": 123, + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "is_closed": false, + "created_date": "2025-09-15T19:13:09.501Z", + "modified_date": "2025-09-15T19:13:09.506Z", + "finish_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "user story subject", + "client_requirement": false, + "team_requirement": false, + "generated_from_issue": null, + "generated_from_task": null, + "from_task_ref": null, + "external_reference": null, + "tribe_gig": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/us/123", + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "assigned_users": [], + "points": [ + { + "role": "UX", + "name": "?", + "value": null + }, + { + "role": "Design", + "name": "?", + "value": null + }, + { + "role": "Front", + "name": "?", + "value": null + }, + { + "role": "Back", + "name": "?", + "value": null + }, + { + "role": "Stakeholder", + "name": "?", + "value": null + } + ], + "status": { + "id": 10498870, + "name": "In progress", + "slug": "new", + "color": "#70728F", + "is_closed": false, + "is_archived": false + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-test-01-2", + "estimated_start": "2025-09-15", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-15T15:28:48.984Z", + "modified_date": "2025-09-15T15:28:48.989Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4acf7f734332df6f6a65789330874e23" + } + } + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-test-01-2", + "estimated_start": "2025-09-15", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-15T15:28:48.984Z", + "modified_date": "2025-09-15T15:28:48.989Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + } + }, + "promoted_to": [] + }, + "change": { + "comment": "", + "comment_html": "", + "delete_comment_date": null, + "comment_versions": null, + "edit_comment_date": null, + "diff": { + "status": { + "from": "New", + "to": "In progress" + } + } + } +} \ No newline at end of file diff --git a/components/taiga/sources/common/base.mjs b/components/taiga/sources/common/base.mjs new file mode 100644 index 0000000000000..e959f4469cd0a --- /dev/null +++ b/components/taiga/sources/common/base.mjs @@ -0,0 +1,83 @@ +import crypto from "crypto"; +import taiga from "../../taiga.app.mjs"; + +export default { + props: { + taiga, + db: "$.service.db", + http: { + type: "$.interface.http", + customResponse: true, + }, + projectId: { + propDefinition: [ + taiga, + "projectId", + ], + }, + name: { + type: "string", + label: "Name", + description: "The name of the webhook.", + }, + }, + methods: { + _setWebhookId(id) { + this.db.set("webhookId", id); + }, + _getWebhookId() { + return this.db.get("webhookId"); + }, + _getSecretKey() { + return this.db.get("secretKey"); + }, + _setSecretKey(secretKey) { + this.db.set("secretKey", secretKey); + }, + validateSecretKey(headers, bodyRaw) { + const secretKey = this._getSecretKey(); + const signature = headers["x-taiga-webhook-signature"]; + const hmac = crypto.createHmac("sha1", secretKey); + hmac.update(bodyRaw); + const signedMessage = hmac.digest("hex"); + + if (signature !== signedMessage) { + return this.http.respond({ + status: 401, + }); + } + }, + }, + hooks: { + async activate() { + const secretKey = crypto.randomUUID(); + const response = await this.taiga.createHook({ + data: { + key: secretKey, + name: this.name, + url: this.http.endpoint, + project: this.projectId, + }, + }); + this._setWebhookId(response.id); + this._setSecretKey(secretKey); + }, + async deactivate() { + const webhookId = this._getWebhookId(); + await this.taiga.deleteHook(webhookId); + }, + }, + async run({ + body, headers, bodyRaw, + }) { + if (!this.filterEvent(body)) return; + this.validateSecretKey(headers, bodyRaw); + + const ts = body.created || Date.now(); + this.$emit(body, { + id: `${body.id}-${ts}`, + summary: this.getSummary(body), + ts, + }); + }, +}; diff --git a/components/taiga/sources/deleted-issue-instant/deleted-issue-instant.mjs b/components/taiga/sources/deleted-issue-instant/deleted-issue-instant.mjs new file mode 100644 index 0000000000000..d7511942a47a8 --- /dev/null +++ b/components/taiga/sources/deleted-issue-instant/deleted-issue-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-deleted-issue-instant", + name: "Deleted Issue (Instant)", + description: "Emit new event when a issue is deleted in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `Deleted Issue: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "issue" && body.action === "delete"; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/deleted-issue-instant/test-event.mjs b/components/taiga/sources/deleted-issue-instant/test-event.mjs new file mode 100644 index 0000000000000..50fec44eacf3a --- /dev/null +++ b/components/taiga/sources/deleted-issue-instant/test-event.mjs @@ -0,0 +1,68 @@ +export default { + "action": "delete", + "type": "issue", + "by": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "date": "2025-09-16T13:57:05.239Z", + "data": { + "custom_attributes_values": null, + "id": 123, + "ref": 123, + "created_date": "2025-09-16T13:48:43.886Z", + "modified_date": "2025-09-16T13:48:43.896Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "subject", + "external_reference": null, + "watchers": [], + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/issue/123", + "project": { + "id": 123, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "milestone": null, + "owner": { + "id": 123, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false + }, + "type": { + "id": 123, + "name": "Bug", + "color": "#E44057" + }, + "priority": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "severity": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "promoted_to": [] + } +} \ No newline at end of file diff --git a/components/taiga/sources/deleted-task-instant/deleted-task-instant.mjs b/components/taiga/sources/deleted-task-instant/deleted-task-instant.mjs new file mode 100644 index 0000000000000..319f2b2d0c708 --- /dev/null +++ b/components/taiga/sources/deleted-task-instant/deleted-task-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-deleted-task-instant", + name: "Deleted Task (Instant)", + description: "Emit new event when a task is deleted in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `Deleted Task: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "task" && body.action === "delete"; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/deleted-task-instant/test-event.mjs b/components/taiga/sources/deleted-task-instant/test-event.mjs new file mode 100644 index 0000000000000..cc7dae1e9bbcf --- /dev/null +++ b/components/taiga/sources/deleted-task-instant/test-event.mjs @@ -0,0 +1,172 @@ +export default { + "custom_attributes_values": null, + "id": 8239144, + "ref": 14, + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "fgbnnvbvbn", + "us_order": 1758030633775, + "taskboard_order": 1758030633775, + "is_iocaine": false, + "external_reference": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/task/123", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false + }, + "user_story": { + "custom_attributes_values": {}, + "id": 8423509, + "ref": 123, + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "is_closed": false, + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "finish_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "user story subject", + "client_requirement": false, + "team_requirement": false, + "generated_from_issue": null, + "generated_from_task": null, + "from_task_ref": null, + "external_reference": null, + "tribe_gig": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/us/123", + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "assigned_users": [], + "points": [ + { + "role": "UX", + "name": "?", + "value": null + }, + { + "role": "Design", + "name": "?", + "value": null + }, + { + "role": "Front", + "name": "?", + "value": null + }, + { + "role": "Back", + "name": "?", + "value": null + }, + { + "role": "Stakeholder", + "name": "?", + "value": null + } + ], + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false, + "is_archived": false + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-subject-2", + "estimated_start": "2025-09-16", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + } + } + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-subject-2", + "estimated_start": "2025-09-16", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + } + }, + "promoted_to": [] +} \ No newline at end of file diff --git a/components/taiga/sources/new-issue-instant/new-issue-instant.mjs b/components/taiga/sources/new-issue-instant/new-issue-instant.mjs new file mode 100644 index 0000000000000..cff28c2c146e2 --- /dev/null +++ b/components/taiga/sources/new-issue-instant/new-issue-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-new-issue-instant", + name: "New Issue (Instant)", + description: "Emit new event when an issue is created in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `New Issue: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "issue" && body.action === "create"; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/new-issue-instant/test-event.mjs b/components/taiga/sources/new-issue-instant/test-event.mjs new file mode 100644 index 0000000000000..1274df45f604b --- /dev/null +++ b/components/taiga/sources/new-issue-instant/test-event.mjs @@ -0,0 +1,68 @@ +export default { + "action": "create", + "type": "issue", + "by": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "date": "2025-09-16T13:45:14.585Z", + "data": { + "custom_attributes_values": {}, + "id": 123, + "ref": 123, + "created_date": "2025-09-16T13:45:14.508Z", + "modified_date": "2025-09-16T13:45:14.519Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "subject", + "external_reference": null, + "watchers": [], + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/issue/123", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "milestone": null, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "pipedreamsage", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false + }, + "type": { + "id": 123, + "name": "Bug", + "color": "#E44057" + }, + "priority": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "severity": { + "id": 123, + "name": "Normal", + "color": "#A8E440" + }, + "promoted_to": [] + } +} \ No newline at end of file diff --git a/components/taiga/sources/new-task-instant/new-task-instant.mjs b/components/taiga/sources/new-task-instant/new-task-instant.mjs new file mode 100644 index 0000000000000..ed6952104f6d0 --- /dev/null +++ b/components/taiga/sources/new-task-instant/new-task-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "taiga-new-task-instant", + name: "New Task (Instant)", + description: "Emit new event when a task is created in the selected project. [See the documentation](https://docs.taiga.io/api.html#webhooks-create)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getSummary(body) { + return `New Task: ${body.data.id}`; + }, + filterEvent(body) { + return body.type === "task" && body.action === "create"; + }, + }, + sampleEmit, +}; diff --git a/components/taiga/sources/new-task-instant/test-event.mjs b/components/taiga/sources/new-task-instant/test-event.mjs new file mode 100644 index 0000000000000..edc31f346a80e --- /dev/null +++ b/components/taiga/sources/new-task-instant/test-event.mjs @@ -0,0 +1,185 @@ +export default { + "action": "create", + "type": "task", + "by": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/yourprofile", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "date": "2025-09-16T13:50:33.888Z", + "data": { + "custom_attributes_values": {}, + "id": 123, + "ref": 123, + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "finished_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "subject", + "us_order": 123, + "taskboard_order": 123, + "is_iocaine": false, + "external_reference": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/task/123", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false + }, + "user_story": { + "custom_attributes_values": {}, + "id": 123, + "ref": 123, + "project": { + "id": 123, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "is_closed": false, + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "finish_date": null, + "due_date": null, + "due_date_reason": "", + "subject": "user story subject", + "client_requirement": false, + "team_requirement": false, + "generated_from_issue": null, + "generated_from_task": null, + "from_task_ref": null, + "external_reference": null, + "tribe_gig": null, + "watchers": [], + "is_blocked": false, + "blocked_note": "", + "description": "", + "tags": [], + "permalink": "https://tree.taiga.io/project/project-name/us/123", + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + }, + "assigned_to": null, + "assigned_users": [], + "points": [ + { + "role": "UX", + "name": "?", + "value": null + }, + { + "role": "Design", + "name": "?", + "value": null + }, + { + "role": "Front", + "name": "?", + "value": null + }, + { + "role": "Back", + "name": "?", + "value": null + }, + { + "role": "Stakeholder", + "name": "?", + "value": null + } + ], + "status": { + "id": 123, + "name": "New", + "slug": "new", + "color": "#70728F", + "is_closed": false, + "is_archived": false + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-subject-2", + "estimated_start": "2025-09-16", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + } + } + }, + "milestone": { + "id": 476374, + "name": "sprint subject", + "slug": "sprint-subject-2", + "estimated_start": "2025-09-16", + "estimated_finish": "2025-09-29", + "created_date": "2025-09-16T13:50:33.791Z", + "modified_date": "2025-09-16T13:50:33.805Z", + "closed": false, + "disponibility": 0, + "permalink": "https://tree.taiga.io/project/project-name/taskboard/sprint-subject-2", + "project": { + "id": 1731087, + "permalink": "https://tree.taiga.io/project/project-name", + "name": "Project Name", + "logo_big_url": null + }, + "owner": { + "id": 845439, + "permalink": "https://tree.taiga.io/profile/username", + "username": "username", + "full_name": "Full Name", + "photo": null, + "gravatar_id": "4aca6578f7f7df634332f69330874e23" + } + }, + "promoted_to": [] + } +} \ No newline at end of file diff --git a/components/taiga/taiga.app.mjs b/components/taiga/taiga.app.mjs index 74edb05ef1988..cfa77c70c2eab 100644 --- a/components/taiga/taiga.app.mjs +++ b/components/taiga/taiga.app.mjs @@ -1,11 +1,634 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "taiga", - propDefinitions: {}, + propDefinitions: { + projectId: { + type: "string", + label: "Project ID", + description: "Select a project or provide a project ID", + async options({ page }) { + let projects = []; + try { + projects = await this.listProjects({ + params: { + page: page + 1, + }, + }); + } catch (error) { + projects = []; + } + return projects.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + issuePriority: { + type: "string", + label: "Priority", + description: "Select a priority or provide a priority", + async options({ + page, projectId, + }) { + let priorities = []; + try { + priorities = await this.listPriorities({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + priorities = []; + } + return priorities.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + issueSeverity: { + type: "string", + label: "Severity", + description: "Select a severity or provide a severity", + async options({ + page, projectId, + }) { + let severities = []; + try { + severities = await this.listSeverities({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + severities = []; + } + return severities.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + issueStatus: { + type: "string", + label: "Status", + description: "Select a status or provide a status", + async options({ + page, projectId, + }) { + let statuses = []; + try { + statuses = await this.listStatuses({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + statuses = []; + } + return statuses.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + issueType: { + type: "string", + label: "Type", + description: "Select a type or provide a type", + async options({ + page, projectId, + }) { + let types = []; + try { + types = await this.listTypes({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + types = []; + } + return types.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + userId: { + type: "string", + label: "User ID", + description: "Select a user or provide a user ID", + async options({ + page, projectId, + }) { + let users = []; + try { + users = await this.listUsers({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + users = []; + } + return users.map(({ + id, full_name_display, username, + }) => ({ + label: `${full_name_display} (${username})`, + value: id, + })); + }, + }, + milestone: { + type: "string", + label: "Milestone", + description: "Select a milestone or provide a milestone", + async options({ + page, projectId, + }) { + let milestones = []; + try { + milestones = await this.listMilestones({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + milestones = []; + } + return milestones.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + taskStatus: { + type: "string", + label: "Task Status", + description: "Select a task status or provide a task status", + async options({ + page, projectId, + }) { + let statuses = []; + try { + statuses = await this.listTaskStatuses({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + statuses = []; + } + return statuses.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + issueId: { + type: "string", + label: "Issue ID", + description: "Select an issue or provide an issue ID", + async options({ + page, projectId, + }) { + let issues = []; + try { + issues = await this.listIssues({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + issues = []; + } + return issues.map(({ + id: value, subject: label, + }) => ({ + label, + value, + })); + }, + }, + taskId: { + type: "string", + label: "Task ID", + description: "Select a task or provide a task ID", + async options({ + page, projectId, + }) { + let tasks = []; + try { + tasks = await this.listTasks({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + tasks = []; + } + return tasks.map(({ + id: value, subject: label, + }) => ({ + label, + value, + })); + }, + }, + userStoryId: { + type: "string", + label: "User Story ID", + description: "Select a user story or provide a user story ID", + async options({ + page, projectId, + }) { + let userStories = []; + try { + userStories = await this.listUserStories({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + userStories = []; + } + return userStories.map(({ + id: value, subject: label, + }) => ({ + label, + value, + })); + }, + }, + userStoryStatus: { + type: "string", + label: "User Story Status", + description: "Select a user story status or provide a user story status", + async options({ + page, projectId, + }) { + let statuses = []; + try { + statuses = await this.listUserStoryStatuses({ + params: { + page: page + 1, + project: projectId, + }, + }); + } catch (error) { + statuses = []; + } + return statuses.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + issueSubject: { + type: "string", + label: "Subject", + description: "The issue subject/title", + }, + issueDescription: { + type: "string", + label: "Description", + description: "The issue description", + }, + tags: { + type: "string[]", + label: "Tags", + description: "Tags to associate with the issue", + }, + issueBlockedNote: { + type: "string", + label: "Blocked Note", + description: "The reason why the issue is blocked", + }, + isBlocked: { + type: "boolean", + label: "Is Blocked", + description: "Whether the issue is blocked", + }, + taskSubject: { + type: "string", + label: "Subject", + description: "The task subject/title", + }, + taskDescription: { + type: "string", + label: "Description", + description: "The task description", + }, + usOrder: { + type: "integer", + label: "User Story Order", + description: "The order in the user story", + }, + taskboardOrder: { + type: "integer", + label: "Taskboard Order", + description: "The order in the taskboard", + }, + userStorySubject: { + type: "string", + label: "Subject", + description: "The user story subject/title", + }, + userStoryDescription: { + type: "string", + label: "Description", + description: "The user story description", + }, + backlogOrder: { + type: "integer", + label: "Backlog Order", + description: "The order in the backlog", + }, + kanbanOrder: { + type: "integer", + label: "Kanban Order", + description: "The order in the kanban", + }, + sprintOrder: { + type: "integer", + label: "Sprint Order", + description: "The order in the sprint", + }, + clientRequirement: { + type: "boolean", + label: "Client Requirement", + description: "Whether the user story is a client requirement", + }, + points: { + type: "object", + label: "Points", + description: "A dictionary of points. The key is the id of the [role](https://docs.taiga.io/api.html#roles-list) and the value is the id of the [points](https://docs.taiga.io/api.html#points-list). Format: `{\"10469741\": 20817870, \"10469742\": 20817871, \"10469743\": 20817872, \"10469744\": 20817873}`", + }, + teamRequirement: { + type: "boolean", + label: "Team Requirement", + description: "Whether the user story is a team requirement", + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return `${this.$auth.api_url}/api/v1`; + }, + _headers() { + return { + "Authorization": `Bearer ${this.$auth.oauth_access_token}`, + "content-type": "application/json", + }; + }, + _makeRequest({ + $ = this, path, ...opts + }) { + return axios($, { + url: this._baseUrl() + path, + headers: this._headers(), + ...opts, + }); + }, + getMe() { + return this._makeRequest({ + path: "/users/me", + }); + }, + listPriorities(opts = {}) { + return this._makeRequest({ + path: "/priorities", + ...opts, + }); + }, + listSeverities(opts = {}) { + return this._makeRequest({ + path: "/severities", + ...opts, + }); + }, + listStatuses(opts = {}) { + return this._makeRequest({ + path: "/issue-statuses", + ...opts, + }); + }, + listTypes(opts = {}) { + return this._makeRequest({ + path: "/issue-types", + ...opts, + }); + }, + listMilestones(opts = {}) { + return this._makeRequest({ + path: "/milestones", + ...opts, + }); + }, + listTaskStatuses(opts = {}) { + return this._makeRequest({ + path: "/task-statuses", + ...opts, + }); + }, + listUserStoryStatuses(opts = {}) { + return this._makeRequest({ + path: "/userstory-statuses", + ...opts, + }); + }, + async listProjects({ + params, ...opts + }) { + const me = await this.getMe(); + return await this._makeRequest({ + path: "/projects", + params: { + member: me.id, + ...params, + }, + ...opts, + }); + }, + createIssue(opts = {}) { + return this._makeRequest({ + path: "/issues", + method: "POST", + ...opts, + }); + }, + createProject(opts = {}) { + return this._makeRequest({ + path: "/projects", + method: "POST", + ...opts, + }); + }, + createTask(opts = {}) { + return this._makeRequest({ + path: "/tasks", + method: "POST", + ...opts, + }); + }, + createUserStory(opts = {}) { + return this._makeRequest({ + path: "/userstories", + method: "POST", + ...opts, + }); + }, + deleteTask({ + taskId, ...opts + }) { + return this._makeRequest({ + path: `/tasks/${taskId}`, + method: "DELETE", + ...opts, + }); + }, + updateIssue({ + issueId, ...opts + }) { + return this._makeRequest({ + path: `/issues/${issueId}`, + method: "PATCH", + ...opts, + }); + }, + listIssues(opts = {}) { + return this._makeRequest({ + path: "/issues", + ...opts, + }); + }, + getIssue({ + issueId, ...opts + }) { + return this._makeRequest({ + path: `/issues/${issueId}`, + ...opts, + }); + }, + deleteIssue({ + issueId, ...opts + }) { + return this._makeRequest({ + path: `/issues/${issueId}`, + method: "DELETE", + ...opts, + }); + }, + deleteUserStory({ + userStoryId, ...opts + }) { + return this._makeRequest({ + path: `/userstories/${userStoryId}`, + method: "DELETE", + ...opts, + }); + }, + getTask({ + taskId, ...opts + }) { + return this._makeRequest({ + path: `/tasks/${taskId}`, + ...opts, + }); + }, + getUserStory({ + userStoryId, ...opts + }) { + return this._makeRequest({ + path: `/userstories/${userStoryId}`, + ...opts, + }); + }, + createHook(opts = {}) { + return this._makeRequest({ + path: "/webhooks", + method: "POST", + ...opts, + }); + }, + deleteHook(hookId) { + return this._makeRequest({ + path: `/webhooks/${hookId}`, + method: "DELETE", + }); + }, + updateUserStory({ + userStoryId, ...opts + }) { + return this._makeRequest({ + path: `/userstories/${userStoryId}`, + method: "PATCH", + ...opts, + }); + }, + updateProject({ + projectId, ...opts + }) { + return this._makeRequest({ + path: `/projects/${projectId}`, + method: "PATCH", + ...opts, + }); + }, + listUsers(opts = {}) { + return this._makeRequest({ + path: "/users", + ...opts, + }); + }, + listTasks(opts = {}) { + return this._makeRequest({ + path: "/tasks", + ...opts, + }); + }, + updateTask({ + taskId, ...opts + }) { + return this._makeRequest({ + path: `/tasks/${taskId}`, + method: "PATCH", + ...opts, + }); + }, + listUserStories(opts = {}) { + return this._makeRequest({ + path: "/userstories", + ...opts, + }); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b505679354d5b..5871a2a47b66f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14065,7 +14065,11 @@ importers: components/taggun: {} - components/taiga: {} + components/taiga: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 components/tailscale: {} From 3cb8df54ea26f1ed3172c297797465ee51e4437e Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 16 Sep 2025 23:15:21 -0400 Subject: [PATCH 20/52] Merging pull request #18382 * add testSources prop * pnpm-lock.yaml * fix --- components/gtmetrix/package.json | 4 ++-- .../new-test-completed/new-test-completed.mjs | 19 ++++++++++++++++++- pnpm-lock.yaml | 13 +++++-------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/components/gtmetrix/package.json b/components/gtmetrix/package.json index 6d0b895c4d761..cf831669ec171 100644 --- a/components/gtmetrix/package.json +++ b/components/gtmetrix/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/gtmetrix", - "version": "0.1.0", + "version": "0.1.1", "description": "Pipedream GTmetrix Components", "main": "gtmetrix.app.mjs", "keywords": [ @@ -13,6 +13,6 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^1.5.1" + "@pipedream/platform": "^3.1.0" } } diff --git a/components/gtmetrix/sources/new-test-completed/new-test-completed.mjs b/components/gtmetrix/sources/new-test-completed/new-test-completed.mjs index 45d72e55a16ee..ec23a8252f378 100644 --- a/components/gtmetrix/sources/new-test-completed/new-test-completed.mjs +++ b/components/gtmetrix/sources/new-test-completed/new-test-completed.mjs @@ -5,9 +5,25 @@ export default { key: "gtmetrix-new-test-completed", name: "New Test Completed", description: "Emit new event when a test is completed in GTMetrix. [See the documentation](https://gtmetrix.com/api/docs/2.0/#api-test-list)", - version: "0.0.1", + version: "0.0.2", type: "source", dedupe: "unique", + props: { + ...common.props, + testSources: { + type: "string[]", + label: "Test Sources", + description: "The test sources to emit events for", + options: [ + "api", + "on-demand", + "monitored", + ], + default: [ + "api", + ], + }, + }, methods: { ...common.methods, getResourceFn() { @@ -19,6 +35,7 @@ export default { "sort": "-finished", "filter[state]": "completed", "filter[finished:gt]": lastTs, + "filter[source]": this.testSources.join(", "), }, }; }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5871a2a47b66f..d87b9031436c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4946,8 +4946,7 @@ importers: specifier: ^3.1.0 version: 3.1.0 - components/financial_data: - specifiers: {} + components/financial_data: {} components/findymail: dependencies: @@ -6281,8 +6280,8 @@ importers: components/gtmetrix: dependencies: '@pipedream/platform': - specifier: ^1.5.1 - version: 1.6.6 + specifier: ^3.1.0 + version: 3.1.0 components/guardrails: {} @@ -7921,8 +7920,7 @@ importers: components/lightpanda: {} - components/lightspeed_ecom_c_series: - specifiers: {} + components/lightspeed_ecom_c_series: {} components/lightspeed_retail_pos: dependencies: @@ -8766,8 +8764,7 @@ importers: components/microsoft_advertising: {} - components/microsoft_authenticator: - specifiers: {} + components/microsoft_authenticator: {} components/microsoft_azure_ai_translator: dependencies: From 6f23e27aa7cf13b1402345deb07273e280821c88 Mon Sep 17 00:00:00 2001 From: Lucas Caresia Date: Wed, 17 Sep 2025 00:23:53 -0300 Subject: [PATCH 21/52] Merging pull request #18323 * Added actions * Added actions * Added actions --- .../actions/get-categories/get-categories.mjs | 20 ++++ .../actions/get-zones/get-zones.mjs | 19 ++++ .../sproutgigs/actions/post-job/post-job.mjs | 84 ++++++++++++++ components/sproutgigs/package.json | 7 +- components/sproutgigs/sproutgigs.app.mjs | 107 +++++++++++++++++- pnpm-lock.yaml | 6 +- 6 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 components/sproutgigs/actions/get-categories/get-categories.mjs create mode 100644 components/sproutgigs/actions/get-zones/get-zones.mjs create mode 100644 components/sproutgigs/actions/post-job/post-job.mjs diff --git a/components/sproutgigs/actions/get-categories/get-categories.mjs b/components/sproutgigs/actions/get-categories/get-categories.mjs new file mode 100644 index 0000000000000..c443d2cbc91c9 --- /dev/null +++ b/components/sproutgigs/actions/get-categories/get-categories.mjs @@ -0,0 +1,20 @@ +import app from "../../sproutgigs.app.mjs"; + +export default { + key: "sproutgigs-get-categories", + name: "Get Categories", + description: "Get a list of categories from Sproutgigs. [See the documentation](https://sproutgigs.com/api/documentation.php#gigs-categories)", + version: "0.0.1", + type: "action", + props: { + app, + }, + async run({ $ }) { + const response = await this.app.getCategories({ + $, + data: {}, + }); + $.export("$summary", "Successfully sent the request. " + response.length + " results retrieved"); + return response; + }, +}; diff --git a/components/sproutgigs/actions/get-zones/get-zones.mjs b/components/sproutgigs/actions/get-zones/get-zones.mjs new file mode 100644 index 0000000000000..fdd3dfb343e13 --- /dev/null +++ b/components/sproutgigs/actions/get-zones/get-zones.mjs @@ -0,0 +1,19 @@ +import app from "../../sproutgigs.app.mjs"; + +export default { + key: "sproutgigs-get-zones", + name: "Get Zones", + description: "Get the available zones. [See the documentation](https://sproutgigs.com/api/documentation.php#jobs-zones)", + version: "0.0.1", + type: "action", + props: { + app, + }, + async run({ $ }) { + const response = await this.app.getZones({ + $, + }); + $.export("$summary", "Successfully sent the request. " + response.length + " results retrieved"); + return response; + }, +}; diff --git a/components/sproutgigs/actions/post-job/post-job.mjs b/components/sproutgigs/actions/post-job/post-job.mjs new file mode 100644 index 0000000000000..741bf1b85f959 --- /dev/null +++ b/components/sproutgigs/actions/post-job/post-job.mjs @@ -0,0 +1,84 @@ +import app from "../../sproutgigs.app.mjs"; + +export default { + key: "sproutgigs-post-job", + name: "Post Job", + description: "Post a new job to Sproutgigs. [See the documentation](https://sproutgigs.com/api/documentation.php#jobs-post)", + version: "0.0.1", + type: "action", + props: { + app, + test: { + propDefinition: [ + app, + "test", + ], + }, + zoneId: { + propDefinition: [ + app, + "zoneId", + ], + }, + categoryId: { + propDefinition: [ + app, + "categoryId", + ], + }, + title: { + propDefinition: [ + app, + "title", + ], + }, + instructions: { + propDefinition: [ + app, + "instructions", + ], + }, + proofs: { + propDefinition: [ + app, + "proofs", + ], + }, + numTasks: { + propDefinition: [ + app, + "numTasks", + ], + }, + taskValue: { + propDefinition: [ + app, + "taskValue", + ], + }, + }, + async run({ $ }) { + const response = await this.app.postJob({ + $, + data: { + test: this.test + ? 1 + : 0, + zone_id: this.zoneId, + category_id: this.categoryId, + title: this.title, + instructions: this.instructions, + proofs: JSON.parse(this.proofs), + num_tasks: this.numTasks, + task_value: this.taskValue, + }, + }); + + if (response.ok === false) { + throw new Error(`Job creation failed: ${response.message}`); + } + + $.export("$summary", "Successfully sent the request. Result message: " + response.message); + return response; + }, +}; diff --git a/components/sproutgigs/package.json b/components/sproutgigs/package.json index 05acb878ce262..c268367ea673d 100644 --- a/components/sproutgigs/package.json +++ b/components/sproutgigs/package.json @@ -1,15 +1,18 @@ { "name": "@pipedream/sproutgigs", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream SproutGigs Components", "main": "sproutgigs.app.mjs", "keywords": [ "pipedream", "sproutgigs" ], - "homepage": "https://pipedream.com/apps/sproutgigs", "author": "Pipedream (https://pipedream.com/)", + "homepage": "https://pipedream.com/apps/sproutgigs", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.1.0" } } diff --git a/components/sproutgigs/sproutgigs.app.mjs b/components/sproutgigs/sproutgigs.app.mjs index aececcb59ce0c..ff81807149567 100644 --- a/components/sproutgigs/sproutgigs.app.mjs +++ b/components/sproutgigs/sproutgigs.app.mjs @@ -1,11 +1,108 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "sproutgigs", - propDefinitions: {}, + propDefinitions: { + test: { + type: "boolean", + label: "Test", + description: "Enable development mode, the job will not be created", + optional: true, + }, + zoneId: { + type: "string", + label: "Zone ID", + description: "Zone ID for the job", + async options() { + const response = await this.getZones(); + return response.map(({ + id, zone, + }) => ({ + value: id, + label: zone, + })); + }, + }, + categoryId: { + type: "string", + label: "Category ID", + description: "Category ID for the job", + async options() { + const response = await this.getCategories(); + return response.map(({ + id, subcategory, + }) => ({ + value: id, + label: subcategory, + })); + }, + }, + title: { + type: "string", + label: "Title", + description: "Job title", + }, + instructions: { + type: "string[]", + label: "Instructions", + description: "List of expected work steps", + }, + proofs: { + type: "string", + label: "Proofs", + description: "Array of up to 4 proofs, each with description and type (text or screenshot), i.e.: `[{\"description\":\"Profile screenshot\",\"type\":\"screenshot\"}]`", + }, + numTasks: { + type: "integer", + label: "Number of Tasks", + description: "Number of tasks to be performed", + }, + taskValue: { + type: "string", + label: "Task Value", + description: "Amount paid per task", + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://sproutgigs.com/api"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, + path, + auth, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + url: this._baseUrl() + path, + auth: { + username: `${this.$auth.user_id}`, + password: `${this.$auth.api_secret}`, + ...auth, + }, + }); + }, + async postJob(args = {}) { + return this._makeRequest({ + path: "/jobs/post-job.php", + method: "post", + ...args, + }); + }, + async getCategories(args = {}) { + return this._makeRequest({ + path: "/jobs/get-categories.php", + ...args, + }); + }, + async getZones(args = {}) { + return this._makeRequest({ + path: "/jobs/get-zones.php", + ...args, + }); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d87b9031436c8..487a6e8bc361d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13652,7 +13652,11 @@ importers: specifier: ^2.29.4 version: 2.30.1 - components/sproutgigs: {} + components/sproutgigs: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 components/spydra: {} From e35feaff59f10631bf21540ffefed6d070b0b2b3 Mon Sep 17 00:00:00 2001 From: Lucas Caresia Date: Wed, 17 Sep 2025 00:32:05 -0300 Subject: [PATCH 22/52] Merging pull request #18377 * Added actions * Update components/weaviate/actions/create-class/create-class.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: Luan Cazarine Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../actions/create-class/create-class.mjs | 60 ++++++++++++ .../actions/delete-class/delete-class.mjs | 26 ++++++ .../actions/get-schema/get-schema.mjs | 19 ++++ components/weaviate/common/constants.mjs | 6 ++ components/weaviate/package.json | 5 +- components/weaviate/weaviate.app.mjs | 92 ++++++++++++++++++- pnpm-lock.yaml | 6 +- 7 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 components/weaviate/actions/create-class/create-class.mjs create mode 100644 components/weaviate/actions/delete-class/delete-class.mjs create mode 100644 components/weaviate/actions/get-schema/get-schema.mjs create mode 100644 components/weaviate/common/constants.mjs diff --git a/components/weaviate/actions/create-class/create-class.mjs b/components/weaviate/actions/create-class/create-class.mjs new file mode 100644 index 0000000000000..ae5b9a97993db --- /dev/null +++ b/components/weaviate/actions/create-class/create-class.mjs @@ -0,0 +1,60 @@ +import app from "../../weaviate.app.mjs"; + +export default { + key: "weaviate-create-class", + name: "Create Class", + description: "Create a new class in Weaviate. [See the documentation](https://docs.weaviate.io/weaviate/api/rest#tag/schema/post/schema)", + version: "0.0.1", + type: "action", + props: { + app, + className: { + propDefinition: [ + app, + "className", + ], + }, + properties: { + propDefinition: [ + app, + "properties", + ], + }, + description: { + propDefinition: [ + app, + "description", + ], + }, + multiTenancyEnabled: { + propDefinition: [ + app, + "multiTenancyEnabled", + ], + }, + vectorIndexType: { + propDefinition: [ + app, + "vectorIndexType", + ], + }, + }, + async run({ $ }) { + const parsedProperties = this.properties?.map((p) => JSON.parse(p)) || []; + const response = await this.app.createClass({ + $, + data: { + class: this.className, + description: this.description, + vectorizer: this.vectorizer, + multiTenancyConfig: { + enabled: this.multiTenancyEnabled, + }, + vectorIndexType: this.vectorIndexType, + properties: parsedProperties, + }, + }); + $.export("$summary", "Successfully sent the request to create a new class"); + return response; + }, +}; diff --git a/components/weaviate/actions/delete-class/delete-class.mjs b/components/weaviate/actions/delete-class/delete-class.mjs new file mode 100644 index 0000000000000..529601c4c06f8 --- /dev/null +++ b/components/weaviate/actions/delete-class/delete-class.mjs @@ -0,0 +1,26 @@ +import app from "../../weaviate.app.mjs"; + +export default { + key: "weaviate-delete-class", + name: "Delete Class", + description: "Delete a class from Weaviate. [See the documentation](https://docs.weaviate.io/weaviate/api/rest#tag/schema/delete/schema/{className})", + version: "0.0.1", + type: "action", + props: { + app, + classId: { + propDefinition: [ + app, + "classId", + ], + }, + }, + async run({ $ }) { + const response = await this.app.deleteClass({ + $, + classId: this.classId, + }); + $.export("$summary", "Successfully deleted the class named " + this.classId); + return response; + }, +}; diff --git a/components/weaviate/actions/get-schema/get-schema.mjs b/components/weaviate/actions/get-schema/get-schema.mjs new file mode 100644 index 0000000000000..938715e2b0cff --- /dev/null +++ b/components/weaviate/actions/get-schema/get-schema.mjs @@ -0,0 +1,19 @@ +import app from "../../weaviate.app.mjs"; + +export default { + key: "weaviate-get-schema", + name: "Get Schema", + description: "Get schema from Weaviate. [See the documentation](https://docs.weaviate.io/weaviate/api/rest#tag/schema/get/schema)", + version: "0.0.1", + type: "action", + props: { + app, + }, + async run({ $ }) { + const response = await this.app.getSchema({ + $, + }); + $.export("$summary", "Successfully retrieved the current database schema"); + return response; + }, +}; diff --git a/components/weaviate/common/constants.mjs b/components/weaviate/common/constants.mjs new file mode 100644 index 0000000000000..1e18520d94454 --- /dev/null +++ b/components/weaviate/common/constants.mjs @@ -0,0 +1,6 @@ +export default { + VECTOR_TYPES: [ + "hnsw", + "flat", + ], +}; diff --git a/components/weaviate/package.json b/components/weaviate/package.json index 69219b7e928bc..047b6f8943b79 100644 --- a/components/weaviate/package.json +++ b/components/weaviate/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/weaviate", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Weaviate Components", "main": "weaviate.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.1.0" } } diff --git a/components/weaviate/weaviate.app.mjs b/components/weaviate/weaviate.app.mjs index c0bc9cc789d62..d56c31f8db9ef 100644 --- a/components/weaviate/weaviate.app.mjs +++ b/components/weaviate/weaviate.app.mjs @@ -1,11 +1,93 @@ +import { axios } from "@pipedream/platform"; +import constants from "./common/constants.mjs"; + export default { type: "app", app: "weaviate", - propDefinitions: {}, + propDefinitions: { + className: { + type: "string", + label: "Class Name", + description: "The name of the class to create", + }, + properties: { + type: "string[]", + label: "Properties", + description: "The properties of the class. Each item must be a JSON object string, e.g.: `{ \"name\": \"title\", \"dataType\": [\"text\"], \"description\": \"Title of the object\" }`", + }, + description: { + type: "string", + label: "Description", + description: "Optional description of the class", + optional: true, + }, + multiTenancyEnabled: { + type: "boolean", + label: "Multi-tenancy Enabled", + description: "Set to `true` to enable multi-tenancy for this class", + optional: true, + }, + vectorIndexType: { + type: "string", + label: "Vector Index Type", + description: "Type of vector index to use", + optional: true, + options: constants.VECTOR_TYPES, + }, + classId: { + type: "string", + label: "Class Name", + description: "Name of the Class", + async options() { + const response = await this.getSchema(); + return response.classes.map(({ class: className }) => ({ + value: className, + label: className, + })); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return `https://${this.$auth.cluster_url}`; + }, + async _makeRequest(opts = {}) { + const { + $ = this, + path, + headers, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + url: this._baseUrl() + path, + headers: { + Authorization: `Bearer ${this.$auth.api_key}`, + ...headers, + }, + }); + }, + async createClass(args = {}) { + return this._makeRequest({ + path: "/v1/schema", + method: "post", + ...args, + }); + }, + async deleteClass({ + classId, ...args + }) { + return this._makeRequest({ + path: `/v1/schema/${classId}`, + method: "delete", + ...args, + }); + }, + async getSchema(args = {}) { + return this._makeRequest({ + path: "/v1/schema", + ...args, + }); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 487a6e8bc361d..d6e35ad6ebddd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15602,7 +15602,11 @@ importers: specifier: ^1.4.1 version: 1.6.6 - components/weaviate: {} + components/weaviate: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 components/webflow: dependencies: From 874a7cfd75067022b6700a3058707f2c10418142 Mon Sep 17 00:00:00 2001 From: Lucas Caresia Date: Wed, 17 Sep 2025 00:37:50 -0300 Subject: [PATCH 23/52] Merging pull request #18376 --- .../actions/add-zipcode/add-zipcode.mjs | 37 +++++++++++ .../get-account-data/get-account-data.mjs | 19 ++++++ .../search-categories/search-categories.mjs | 28 +++++++++ components/redcircle_api/package.json | 5 +- .../redcircle_api/redcircle_api.app.mjs | 63 +++++++++++++++++-- pnpm-lock.yaml | 6 +- 6 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 components/redcircle_api/actions/add-zipcode/add-zipcode.mjs create mode 100644 components/redcircle_api/actions/get-account-data/get-account-data.mjs create mode 100644 components/redcircle_api/actions/search-categories/search-categories.mjs diff --git a/components/redcircle_api/actions/add-zipcode/add-zipcode.mjs b/components/redcircle_api/actions/add-zipcode/add-zipcode.mjs new file mode 100644 index 0000000000000..8ae5268a8164c --- /dev/null +++ b/components/redcircle_api/actions/add-zipcode/add-zipcode.mjs @@ -0,0 +1,37 @@ +import app from "../../redcircle_api.app.mjs"; + +export default { + key: "redcircle_api-add-zipcode", + name: "Add Zipcode", + description: "Add a zipcode to Redcircle API. [See the documentation](https://docs.trajectdata.com/redcircleapi/zipcodes-api/add)", + version: "0.0.1", + type: "action", + props: { + app, + zipcode: { + propDefinition: [ + app, + "zipcode", + ], + }, + domain: { + propDefinition: [ + app, + "domain", + ], + }, + }, + async run({ $ }) { + const response = await this.app.addZipcode({ + $, + data: [ + { + zipcode: this.zipcode, + domain: this.domain, + }, + ], + }); + $.export("$summary", "Successfully sent the request"); + return response; + }, +}; diff --git a/components/redcircle_api/actions/get-account-data/get-account-data.mjs b/components/redcircle_api/actions/get-account-data/get-account-data.mjs new file mode 100644 index 0000000000000..04a91c989fa01 --- /dev/null +++ b/components/redcircle_api/actions/get-account-data/get-account-data.mjs @@ -0,0 +1,19 @@ +import app from "../../redcircle_api.app.mjs"; + +export default { + key: "redcircle_api-get-account-data", + name: "Get Account Data", + description: "Get your account details. [See the documentation](https://docs.trajectdata.com/redcircleapi/account-api)", + version: "0.0.1", + type: "action", + props: { + app, + }, + async run({ $ }) { + const response = await this.app.getAccountData({ + $, + }); + $.export("$summary", "Successfully retrieved the account data"); + return response; + }, +}; diff --git a/components/redcircle_api/actions/search-categories/search-categories.mjs b/components/redcircle_api/actions/search-categories/search-categories.mjs new file mode 100644 index 0000000000000..a135293563c19 --- /dev/null +++ b/components/redcircle_api/actions/search-categories/search-categories.mjs @@ -0,0 +1,28 @@ +import app from "../../redcircle_api.app.mjs"; + +export default { + key: "redcircle_api-search-categories", + name: "Search Categories", + description: "Search for a category in Redcirle API. [See the documentation](https://docs.trajectdata.com/redcircleapi/categories-api/list-and-search)", + version: "0.0.1", + type: "action", + props: { + app, + searchTerm: { + propDefinition: [ + app, + "searchTerm", + ], + }, + }, + async run({ $ }) { + const response = await this.app.searchCategories({ + $, + params: { + "search_term": this.searchTerm, + }, + }); + $.export("$summary", "Successfully sent the request and retrieved " + response.categories.length + " categories"); + return response; + }, +}; diff --git a/components/redcircle_api/package.json b/components/redcircle_api/package.json index 57b45351906af..f89f7e2189ea1 100644 --- a/components/redcircle_api/package.json +++ b/components/redcircle_api/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/redcircle_api", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream RedCircle API Components", "main": "redcircle_api.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.1.0" } } diff --git a/components/redcircle_api/redcircle_api.app.mjs b/components/redcircle_api/redcircle_api.app.mjs index b57d3ab691910..31c149d8aad1a 100644 --- a/components/redcircle_api/redcircle_api.app.mjs +++ b/components/redcircle_api/redcircle_api.app.mjs @@ -1,11 +1,64 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "redcircle_api", - propDefinitions: {}, + propDefinitions: { + searchTerm: { + type: "string", + label: "Search Term", + description: "The term to search for a category", + optional: true, + }, + zipcode: { + type: "string", + label: "Zipcode", + description: "Description for zipcode", + }, + domain: { + type: "string", + label: "Domain", + description: "Description for domain", + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://api.redcircleapi.com"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, + path, + params, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + url: this._baseUrl() + path, + params: { + api_key: `${this.$auth.api_key}`, + ...params, + }, + }); + }, + async searchCategories(args = {}) { + return this._makeRequest({ + path: "/categories", + ...args, + }); + }, + async getAccountData(args = {}) { + return this._makeRequest({ + path: "/account", + ...args, + }); + }, + async addZipcode(args = {}) { + return this._makeRequest({ + path: "/zipcodes", + method: "post", + ...args, + }); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6e35ad6ebddd..55bf9fe320507 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11694,7 +11694,11 @@ importers: specifier: ^3.24.0 version: 3.30.0 - components/redcircle_api: {} + components/redcircle_api: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 components/reddit: dependencies: From f381c6752d972f1a5e3b8bafc62dd15881cee141 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:33:07 -0700 Subject: [PATCH 24/52] Adding app scaffolding for etrusted --- components/etrusted/etrusted.app.mjs | 11 +++++++++++ components/etrusted/package.json | 15 +++++++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/etrusted/etrusted.app.mjs create mode 100644 components/etrusted/package.json diff --git a/components/etrusted/etrusted.app.mjs b/components/etrusted/etrusted.app.mjs new file mode 100644 index 0000000000000..c7b97945a8aa4 --- /dev/null +++ b/components/etrusted/etrusted.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "etrusted", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/components/etrusted/package.json b/components/etrusted/package.json new file mode 100644 index 0000000000000..78c501c3ffc32 --- /dev/null +++ b/components/etrusted/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/etrusted", + "version": "0.0.1", + "description": "Pipedream eTrusted Components", + "main": "etrusted.app.mjs", + "keywords": [ + "pipedream", + "etrusted" + ], + "homepage": "https://pipedream.com/apps/etrusted", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55bf9fe320507..384d92054f29a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4628,6 +4628,9 @@ importers: components/ethereum: {} + components/etrusted: + specifiers: {} + components/etsy: dependencies: '@pipedream/platform': From d11624e96e7d7e70a28bbc9a8db345fc4a6f2c57 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:33:09 -0700 Subject: [PATCH 25/52] Adding app scaffolding for intelliflo_office --- .../intelliflo_office/intelliflo_office.app.mjs | 11 +++++++++++ components/intelliflo_office/package.json | 15 +++++++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/intelliflo_office/intelliflo_office.app.mjs create mode 100644 components/intelliflo_office/package.json diff --git a/components/intelliflo_office/intelliflo_office.app.mjs b/components/intelliflo_office/intelliflo_office.app.mjs new file mode 100644 index 0000000000000..0987df89e37e6 --- /dev/null +++ b/components/intelliflo_office/intelliflo_office.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "intelliflo_office", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/components/intelliflo_office/package.json b/components/intelliflo_office/package.json new file mode 100644 index 0000000000000..842820565415b --- /dev/null +++ b/components/intelliflo_office/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/intelliflo_office", + "version": "0.0.1", + "description": "Pipedream intelliflo office Components", + "main": "intelliflo_office.app.mjs", + "keywords": [ + "pipedream", + "intelliflo_office" + ], + "homepage": "https://pipedream.com/apps/intelliflo_office", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 384d92054f29a..42b0319372683 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7105,6 +7105,9 @@ importers: specifier: ^1.5.1 version: 1.6.6 + components/intelliflo_office: + specifiers: {} + components/intellihr: dependencies: '@pipedream/platform': From dc3964aeb5780dfceb5a101547a4fdd6e2286261 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:33:11 -0700 Subject: [PATCH 26/52] Adding app scaffolding for thoughtspot --- components/thoughtspot/package.json | 15 +++++++++++++++ components/thoughtspot/thoughtspot.app.mjs | 11 +++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/thoughtspot/package.json create mode 100644 components/thoughtspot/thoughtspot.app.mjs diff --git a/components/thoughtspot/package.json b/components/thoughtspot/package.json new file mode 100644 index 0000000000000..0735b297c03e1 --- /dev/null +++ b/components/thoughtspot/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/thoughtspot", + "version": "0.0.1", + "description": "Pipedream ThoughtSpot Components", + "main": "thoughtspot.app.mjs", + "keywords": [ + "pipedream", + "thoughtspot" + ], + "homepage": "https://pipedream.com/apps/thoughtspot", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/components/thoughtspot/thoughtspot.app.mjs b/components/thoughtspot/thoughtspot.app.mjs new file mode 100644 index 0000000000000..297653d604fed --- /dev/null +++ b/components/thoughtspot/thoughtspot.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "thoughtspot", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42b0319372683..e18d06a0b1f2c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14426,6 +14426,9 @@ importers: specifier: ^1.6.5 version: 1.6.6 + components/thoughtspot: + specifiers: {} + components/threads: dependencies: '@pipedream/platform': From bbde963548225cd134819841110f6d0846666061 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:33:13 -0700 Subject: [PATCH 27/52] Adding app scaffolding for kordiam --- components/kordiam/kordiam.app.mjs | 11 +++++++++++ components/kordiam/package.json | 15 +++++++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/kordiam/kordiam.app.mjs create mode 100644 components/kordiam/package.json diff --git a/components/kordiam/kordiam.app.mjs b/components/kordiam/kordiam.app.mjs new file mode 100644 index 0000000000000..49bd329ae66ec --- /dev/null +++ b/components/kordiam/kordiam.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "kordiam", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/components/kordiam/package.json b/components/kordiam/package.json new file mode 100644 index 0000000000000..d77bb65185080 --- /dev/null +++ b/components/kordiam/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/kordiam", + "version": "0.0.1", + "description": "Pipedream Kordiam Components", + "main": "kordiam.app.mjs", + "keywords": [ + "pipedream", + "kordiam" + ], + "homepage": "https://pipedream.com/apps/kordiam", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e18d06a0b1f2c..e25151de11987 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7626,6 +7626,9 @@ importers: specifier: ^1.0.1 version: 1.0.1 + components/kordiam: + specifiers: {} + components/koyeb: {} components/kraken_io: {} From fc90f7b7e442b5b4c96499fe44ad6f1b50f8c6ee Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:33:23 -0700 Subject: [PATCH 28/52] Adding app scaffolding for ticketsauce --- components/ticketsauce/package.json | 15 +++++++++++++++ components/ticketsauce/ticketsauce.app.mjs | 11 +++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/ticketsauce/package.json create mode 100644 components/ticketsauce/ticketsauce.app.mjs diff --git a/components/ticketsauce/package.json b/components/ticketsauce/package.json new file mode 100644 index 0000000000000..9d812ec5b5894 --- /dev/null +++ b/components/ticketsauce/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/ticketsauce", + "version": "0.0.1", + "description": "Pipedream TicketSauce Components", + "main": "ticketsauce.app.mjs", + "keywords": [ + "pipedream", + "ticketsauce" + ], + "homepage": "https://pipedream.com/apps/ticketsauce", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/components/ticketsauce/ticketsauce.app.mjs b/components/ticketsauce/ticketsauce.app.mjs new file mode 100644 index 0000000000000..21ab9d092e971 --- /dev/null +++ b/components/ticketsauce/ticketsauce.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "ticketsauce", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e25151de11987..1fa2beb8c5996 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14463,6 +14463,9 @@ importers: specifier: ^1.0.1 version: 1.0.1 + components/ticketsauce: + specifiers: {} + components/ticktick: dependencies: '@pipedream/platform': From 961dd55ad5f04a45ad192aa9725291eade60ca85 Mon Sep 17 00:00:00 2001 From: Job <9075380+Afstkla@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:25:08 +0200 Subject: [PATCH 29/52] trustpilot fixes (#18152) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * trustpilot fixes * more fixes * update versions * more version updates * fixes * Bump all Trustpilot actions to version 0.1.0 Major improvements and API updates across all actions: - Enhanced private API support with proper authentication - Improved parameter handling and validation - Better error handling and response structures - Added new conversation flow for product reviews - Fixed endpoint URLs to match latest API documentation - Streamlined request/response processing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * up version and clean up sources * merge * fix business ID * delete temp action * Update components/trustpilot/sources/new-product-reviews/new-product-reviews.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update components/trustpilot/sources/new-product-reviews/new-product-reviews.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update components/trustpilot/sources/new-product-reviews/new-product-reviews.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update components/trustpilot/sources/new-service-reviews/new-service-reviews.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * comments * Pagination * fixes * comments * missed some `$`'s * unduplicated * more fixes * final comments * more comments * . --------- Co-authored-by: Claude Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- components/etrusted/etrusted.app.mjs | 2 +- .../financial_data/financial_data.app.mjs | 2 +- .../intelliflo_office.app.mjs | 2 +- components/kordiam/kordiam.app.mjs | 2 +- .../lightspeed_ecom_c_series.app.mjs | 2 +- .../microsoft_authenticator.app.mjs | 2 +- components/rundeck/rundeck.app.mjs | 2 +- components/thoughtspot/thoughtspot.app.mjs | 2 +- components/ticketsauce/ticketsauce.app.mjs | 2 +- .../fetch-product-review-by-id.mjs | 28 +- .../fetch-product-reviews.mjs | 83 +-- .../fetch-service-review-by-id.mjs | 45 +- .../fetch-service-reviews.mjs | 228 +++++-- .../get-conversation-from-product-review.mjs | 90 +++ .../reply-to-product-review.mjs | 135 +++- .../reply-to-service-review.mjs | 94 ++- components/trustpilot/common/api-client.mjs | 111 +++ components/trustpilot/common/constants.mjs | 103 +-- components/trustpilot/common/utils.mjs | 140 ++-- components/trustpilot/package.json | 2 +- .../trustpilot/sources/common/polling.mjs | 263 +++---- .../new-conversations/new-conversations.mjs | 41 -- .../new-product-review-replies.mjs | 72 -- .../new-product-reviews.mjs | 89 ++- .../new-service-review-replies.mjs | 71 -- .../new-service-reviews.mjs | 62 +- .../updated-conversations.mjs | 42 -- .../updated-product-reviews.mjs | 40 -- .../updated-service-reviews.mjs | 39 -- components/trustpilot/trustpilot.app.mjs | 641 +++++------------- 30 files changed, 1116 insertions(+), 1321 deletions(-) create mode 100644 components/trustpilot/actions/get-conversation-from-product-review/get-conversation-from-product-review.mjs create mode 100644 components/trustpilot/common/api-client.mjs delete mode 100644 components/trustpilot/sources/new-conversations/new-conversations.mjs delete mode 100644 components/trustpilot/sources/new-product-review-replies/new-product-review-replies.mjs delete mode 100644 components/trustpilot/sources/new-service-review-replies/new-service-review-replies.mjs delete mode 100644 components/trustpilot/sources/updated-conversations/updated-conversations.mjs delete mode 100644 components/trustpilot/sources/updated-product-reviews/updated-product-reviews.mjs delete mode 100644 components/trustpilot/sources/updated-service-reviews/updated-service-reviews.mjs diff --git a/components/etrusted/etrusted.app.mjs b/components/etrusted/etrusted.app.mjs index c7b97945a8aa4..5e41c9504b032 100644 --- a/components/etrusted/etrusted.app.mjs +++ b/components/etrusted/etrusted.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/financial_data/financial_data.app.mjs b/components/financial_data/financial_data.app.mjs index 2ebd5e4c145d8..d21de5a68c40a 100644 --- a/components/financial_data/financial_data.app.mjs +++ b/components/financial_data/financial_data.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/intelliflo_office/intelliflo_office.app.mjs b/components/intelliflo_office/intelliflo_office.app.mjs index 0987df89e37e6..c5bcc4d835d73 100644 --- a/components/intelliflo_office/intelliflo_office.app.mjs +++ b/components/intelliflo_office/intelliflo_office.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/kordiam/kordiam.app.mjs b/components/kordiam/kordiam.app.mjs index 49bd329ae66ec..9cb0e8979b7bc 100644 --- a/components/kordiam/kordiam.app.mjs +++ b/components/kordiam/kordiam.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs b/components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs index 741ab63c52762..47001046778b7 100644 --- a/components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs +++ b/components/lightspeed_ecom_c_series/lightspeed_ecom_c_series.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/microsoft_authenticator/microsoft_authenticator.app.mjs b/components/microsoft_authenticator/microsoft_authenticator.app.mjs index 3911b9e7409f3..dd83b59dd35a9 100644 --- a/components/microsoft_authenticator/microsoft_authenticator.app.mjs +++ b/components/microsoft_authenticator/microsoft_authenticator.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/rundeck/rundeck.app.mjs b/components/rundeck/rundeck.app.mjs index eb18a9222075a..ea54315a2b959 100644 --- a/components/rundeck/rundeck.app.mjs +++ b/components/rundeck/rundeck.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/thoughtspot/thoughtspot.app.mjs b/components/thoughtspot/thoughtspot.app.mjs index 297653d604fed..b0214d5211435 100644 --- a/components/thoughtspot/thoughtspot.app.mjs +++ b/components/thoughtspot/thoughtspot.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/ticketsauce/ticketsauce.app.mjs b/components/ticketsauce/ticketsauce.app.mjs index 21ab9d092e971..f665cd726ff5b 100644 --- a/components/ticketsauce/ticketsauce.app.mjs +++ b/components/ticketsauce/ticketsauce.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/trustpilot/actions/fetch-product-review-by-id/fetch-product-review-by-id.mjs b/components/trustpilot/actions/fetch-product-review-by-id/fetch-product-review-by-id.mjs index 8360d522e88b1..9b5f1994b7cd1 100644 --- a/components/trustpilot/actions/fetch-product-review-by-id/fetch-product-review-by-id.mjs +++ b/components/trustpilot/actions/fetch-product-review-by-id/fetch-product-review-by-id.mjs @@ -1,10 +1,17 @@ import trustpilot from "../../trustpilot.app.mjs"; +import { makeRequest } from "../../common/api-client.mjs"; +import { ENDPOINTS } from "../../common/constants.mjs"; +import { + buildUrl, + parseProductReview, + validateReviewId, +} from "../../common/utils.mjs"; export default { key: "trustpilot-fetch-product-review-by-id", name: "Fetch Product Review by ID", description: "Retrieves detailed information about a specific product review on Trustpilot. Use this action to get comprehensive data about a single product review, including customer feedback, star rating, review text, and metadata. Perfect for analyzing individual customer experiences, responding to specific feedback, or integrating review data into your customer service workflows. [See the documentation](https://developers.trustpilot.com/product-reviews-api#get-private-product-review)", - version: "0.0.3", + version: "0.1.0", type: "action", props: { trustpilot, @@ -18,11 +25,28 @@ export default { async run({ $ }) { const { reviewId } = this; + // Validate required parameters + if (!reviewId) { + throw new Error("Review ID is required"); + } + if (!validateReviewId(reviewId)) { + throw new Error("Invalid review ID format"); + } + try { - const review = await this.trustpilot.getProductReviewById({ + // Build the endpoint URL + const endpoint = buildUrl(ENDPOINTS.PRIVATE_PRODUCT_REVIEW_BY_ID, { reviewId, }); + // Make the API request + const response = await makeRequest($, this.trustpilot, { + endpoint, + }); + + // Parse the product review with the correct parser + const review = parseProductReview(response); + $.export("$summary", `Successfully fetched product review ${reviewId}`); return { diff --git a/components/trustpilot/actions/fetch-product-reviews/fetch-product-reviews.mjs b/components/trustpilot/actions/fetch-product-reviews/fetch-product-reviews.mjs index 5a19583331584..2acc51c2905e1 100644 --- a/components/trustpilot/actions/fetch-product-reviews/fetch-product-reviews.mjs +++ b/components/trustpilot/actions/fetch-product-reviews/fetch-product-reviews.mjs @@ -3,8 +3,8 @@ import trustpilot from "../../trustpilot.app.mjs"; export default { key: "trustpilot-fetch-product-reviews", name: "Fetch Product Reviews", - description: "Retrieves a list of product reviews for a specific business unit on Trustpilot. This action enables you to fetch multiple product reviews with powerful filtering options including star ratings, language, tags, and sorting preferences. Ideal for monitoring product feedback trends, generating reports, analyzing customer sentiment across your product catalog, or building review dashboards. Supports pagination for handling large review volumes. [See the documentation](https://developers.trustpilot.com/product-reviews-api#get-private-product-reviews)", - version: "0.0.3", + description: "Retrieves a list of product reviews for a specific business unit. See documentation [here](https://developers.trustpilot.com/product-reviews-api/#get-private-product-reviews)", + version: "1.0.0", type: "action", props: { trustpilot, @@ -14,96 +14,69 @@ export default { "businessUnitId", ], }, - stars: { + page: { propDefinition: [ trustpilot, - "stars", + "page", ], }, - sortBy: { + perPage: { propDefinition: [ trustpilot, - "sortBy", + "perPage", ], }, - limit: { + sku: { propDefinition: [ trustpilot, - "limit", + "sku", ], }, - includeReportedReviews: { + language: { propDefinition: [ trustpilot, - "includeReportedReviews", + "language", ], }, - tags: { + state: { propDefinition: [ trustpilot, - "tags", + "state", ], }, - language: { + locale: { propDefinition: [ trustpilot, - "language", + "locale", ], }, - offset: { - type: "integer", - label: "Offset", - description: "Number of results to skip (for pagination)", - min: 0, - default: 0, - optional: true, - }, }, async run({ $ }) { const { businessUnitId, - stars, - sortBy, - limit, - includeReportedReviews, - tags, + page, + perPage, + sku, language, - offset, + state, + locale, } = this; try { - const result = await this.trustpilot.getProductReviews({ + // Use the shared method from the app + const result = await this.trustpilot.fetchProductReviews($, { businessUnitId, - stars, - sortBy, - limit, - includeReportedReviews, - tags, + page, + perPage, + sku, language, - offset, + state, + locale, }); - const { - reviews, pagination, - } = result; - - $.export("$summary", `Successfully fetched ${reviews.length} product review(s) for business unit ${businessUnitId}`); + $.export("$summary", `Successfully fetched ${result.reviews.length} product review(s) for business unit ${businessUnitId}`); - return { - reviews, - pagination, - metadata: { - businessUnitId, - filters: { - stars, - sortBy, - includeReportedReviews, - tags, - language, - }, - requestTime: new Date().toISOString(), - }, - }; + return result; } catch (error) { throw new Error(`Failed to fetch product reviews: ${error.message}`); } diff --git a/components/trustpilot/actions/fetch-service-review-by-id/fetch-service-review-by-id.mjs b/components/trustpilot/actions/fetch-service-review-by-id/fetch-service-review-by-id.mjs index 539ec50372681..0289bab9e6deb 100644 --- a/components/trustpilot/actions/fetch-service-review-by-id/fetch-service-review-by-id.mjs +++ b/components/trustpilot/actions/fetch-service-review-by-id/fetch-service-review-by-id.mjs @@ -1,19 +1,20 @@ import trustpilot from "../../trustpilot.app.mjs"; +import { makeRequest } from "../../common/api-client.mjs"; +import { ENDPOINTS } from "../../common/constants.mjs"; +import { + buildUrl, + parseServiceReview, + validateReviewId, +} from "../../common/utils.mjs"; export default { key: "trustpilot-fetch-service-review-by-id", name: "Fetch Service Review by ID", - description: "Retrieves detailed information about a specific service review for your business on Trustpilot. Use this action to access comprehensive data about an individual service review, including the customer's rating, review content, date, and any responses. Essential for customer service teams to analyze specific feedback, track review history, or integrate individual review data into CRM systems and support tickets. [See the documentation](https://developers.trustpilot.com/business-units-api#get-business-unit-review)", - version: "0.0.3", + description: "Get a private service review by ID, including customer email and order ID. Access comprehensive data about an individual service review for your business. [See the documentation](https://developers.trustpilot.com/business-units-api#get-private-review-by-id)", + version: "0.1.0", type: "action", props: { trustpilot, - businessUnitId: { - propDefinition: [ - trustpilot, - "businessUnitId", - ], - }, reviewId: { propDefinition: [ trustpilot, @@ -22,23 +23,35 @@ export default { }, }, async run({ $ }) { - const { - businessUnitId, - reviewId, - } = this; + const { reviewId } = this; + + // Validate required parameters + if (!reviewId) { + throw new Error("Review ID is required"); + } + if (!validateReviewId(reviewId)) { + throw new Error("Invalid review ID format"); + } try { - const review = await this.trustpilot.getServiceReviewById({ - businessUnitId, + // Build the endpoint URL for private service review + const endpoint = buildUrl(ENDPOINTS.SERVICE_REVIEW_BY_ID, { reviewId, }); - $.export("$summary", `Successfully fetched service review ${reviewId} for business unit ${businessUnitId}`); + // Make the API request + const response = await makeRequest($, this.trustpilot, { + endpoint, + }); + + // Parse the service review with the correct parser + const review = parseServiceReview(response); + + $.export("$summary", `Successfully fetched service review ${reviewId}`); return { review, metadata: { - businessUnitId, reviewId, requestTime: new Date().toISOString(), }, diff --git a/components/trustpilot/actions/fetch-service-reviews/fetch-service-reviews.mjs b/components/trustpilot/actions/fetch-service-reviews/fetch-service-reviews.mjs index 8408483dc736a..7cfa4e5ce3920 100644 --- a/components/trustpilot/actions/fetch-service-reviews/fetch-service-reviews.mjs +++ b/components/trustpilot/actions/fetch-service-reviews/fetch-service-reviews.mjs @@ -3,8 +3,8 @@ import trustpilot from "../../trustpilot.app.mjs"; export default { key: "trustpilot-fetch-service-reviews", name: "Fetch Service Reviews", - description: "Fetches service reviews for a specific business unit from Trustpilot with support for filtering by star rating, tags, language, and more. [See the documentation](https://developers.trustpilot.com/business-units-api#get-business-unit-reviews)", - version: "0.0.3", + description: "Get private reviews for a business unit. Response includes customer email and order ID. [See the documentation](https://developers.trustpilot.com/business-units-api#get-private-reviews-for-business-unit)", + version: "0.1.0", type: "action", props: { trustpilot, @@ -14,48 +14,141 @@ export default { "businessUnitId", ], }, - stars: { + language: { propDefinition: [ trustpilot, - "stars", + "language", ], }, - sortBy: { - propDefinition: [ - trustpilot, - "sortBy", - ], + page: { + type: "integer", + label: "Page", + description: "The page to retrieve. If the page number requested is higher than the available number of pages, an empty array will be returned.", + min: 1, + default: 1, + optional: true, }, - limit: { - propDefinition: [ - trustpilot, - "limit", - ], + stars: { + type: "string", + label: "Star Rating", + description: "Filter by reviews with a specific star rating. 1-5, separated by commas.", + optional: true, }, - includeReportedReviews: { - propDefinition: [ - trustpilot, - "includeReportedReviews", - ], + internalLocationId: { + type: "string", + label: "Internal Location ID", + description: "Filter by reviews with a specific location", + optional: true, }, - tags: { - propDefinition: [ - trustpilot, - "tags", - ], + perPage: { + type: "integer", + label: "Per Page", + description: "The number of reviews to retrieve per page", + min: 1, + max: 100, + default: 20, + optional: true, }, - language: { - propDefinition: [ - trustpilot, - "language", + orderBy: { + type: "string", + label: "Order By", + description: "The order in which the results should be sorted", + options: [ + { + label: "Created At (Ascending)", + value: "createdat.asc", + }, + { + label: "Created At (Descending)", + value: "createdat.desc", + }, + { + label: "Stars (Ascending)", + value: "stars.asc", + }, + { + label: "Stars (Descending)", + value: "stars.desc", + }, ], + default: "createdat.desc", + optional: true, }, - offset: { - type: "integer", - label: "Offset", - description: "Number of results to skip (for pagination)", - min: 0, - default: 0, + tagGroup: { + type: "string", + label: "Tag Group", + description: "Filtering reviews on Tag group", + optional: true, + }, + tagValue: { + type: "string", + label: "Tag Value", + description: "Filtering reviews on Tag value", + optional: true, + }, + ignoreTagValueCase: { + type: "boolean", + label: "Ignore Tag Value Case", + description: "Ignore tag value case", + default: false, + optional: true, + }, + responded: { + type: "boolean", + label: "Responded", + description: "Filter reviews by responded state", + optional: true, + }, + referenceId: { + type: "string", + label: "Reference ID", + description: "Filter reviews by reference Id", + optional: true, + }, + referralEmail: { + type: "string", + label: "Referral Email", + description: "Filter reviews by referral email", + optional: true, + }, + reported: { + type: "boolean", + label: "Reported", + description: "Filter reviews by reported state", + optional: true, + }, + startDateTime: { + type: "string", + label: "Start Date Time", + description: "Filter reviews by datetime range. If no time is specified, then time is implicitly `00:00:00`. Format: `2013-09-07T13:37:00`", + optional: true, + }, + endDateTime: { + type: "string", + label: "End Date Time", + description: "Filter reviews by datetime range. If no time is specified, then time is implicitly `00:00:00`. Format: `2013-09-07T13:37:00`", + optional: true, + }, + source: { + type: "string", + label: "Source", + description: "Filter reviews by source", + optional: true, + }, + username: { + type: "string", + label: "Username", + description: "Filter reviews by user name", + optional: true, + }, + findReviewer: { + type: "string", + label: "Find Reviewer", + description: "Filter reviews by Find Reviewer requests (contacted or not contacted)", + options: [ + "contacted", + "notContacted", + ], optional: true, }, }, @@ -63,47 +156,52 @@ export default { const { businessUnitId, stars, - sortBy, - limit, - includeReportedReviews, - tags, language, - offset, + page = 1, + internalLocationId, + perPage = 20, + orderBy = "createdat.desc", + tagGroup, + tagValue, + ignoreTagValueCase = false, + responded, + referenceId, + referralEmail, + reported, + startDateTime, + endDateTime, + source, + username, + findReviewer, } = this; try { - const result = await this.trustpilot.getServiceReviews({ + // Use the shared method from the app + const result = await this.trustpilot.fetchServiceReviews($, { businessUnitId, stars, - sortBy, - limit, - includeReportedReviews, - tags, language, - offset, + page, + internalLocationId, + perPage, + orderBy, + tagGroup, + tagValue, + ignoreTagValueCase, + responded, + referenceId, + referralEmail, + reported, + startDateTime, + endDateTime, + source, + username, + findReviewer, }); - const { - reviews, pagination, - } = result; - - $.export("$summary", `Successfully fetched ${reviews.length} service review(s) for business unit ${businessUnitId}`); + $.export("$summary", `Successfully fetched ${result.reviews.length} service review(s) for business unit ${businessUnitId}`); - return { - reviews, - pagination, - metadata: { - businessUnitId, - filters: { - stars, - sortBy, - includeReportedReviews, - tags, - language, - }, - requestTime: new Date().toISOString(), - }, - }; + return result; } catch (error) { throw new Error(`Failed to fetch service reviews: ${error.message}`); } diff --git a/components/trustpilot/actions/get-conversation-from-product-review/get-conversation-from-product-review.mjs b/components/trustpilot/actions/get-conversation-from-product-review/get-conversation-from-product-review.mjs new file mode 100644 index 0000000000000..a71fadb03802c --- /dev/null +++ b/components/trustpilot/actions/get-conversation-from-product-review/get-conversation-from-product-review.mjs @@ -0,0 +1,90 @@ +import { ConfigurationError } from "@pipedream/platform"; +import trustpilot from "../../trustpilot.app.mjs"; +import { makeRequest } from "../../common/api-client.mjs"; +import { ENDPOINTS } from "../../common/constants.mjs"; +import { + buildUrl, + validateReviewId, +} from "../../common/utils.mjs"; + +export default { + key: "trustpilot-get-conversation-from-product-review", + name: "Get Conversation from Product Review", + description: "Get conversation and related comments from a product review. First fetches the review to get the conversationId, then retrieves the full conversation details. [See the documentation](https://developers.trustpilot.com/conversations-api#get-conversation)", + version: "0.0.1", + type: "action", + props: { + trustpilot, + reviewId: { + propDefinition: [ + trustpilot, + "reviewId", + ], + }, + }, + async run({ $ }) { + const { reviewId } = this; + + // Validate required parameters + if (!reviewId) { + throw new ConfigurationError("Review ID is required"); + } + if (!validateReviewId(reviewId)) { + throw new ConfigurationError("Invalid review ID format"); + } + + // Step 1: Get the product review to get the conversationId + $.export("$summary", "Fetching product review details..."); + + const getReviewEndpoint = buildUrl(ENDPOINTS.PRIVATE_PRODUCT_REVIEW_BY_ID, { + reviewId, + }); + + const review = await makeRequest($, this.trustpilot, { + endpoint: getReviewEndpoint, + }); + + const conversationId = review.conversationId; + + if (!conversationId) { + return { + success: false, + message: "No conversation found for this product review", + review: { + id: reviewId, + hasConversation: false, + }, + metadata: { + reviewId, + requestTime: new Date().toISOString(), + }, + }; + } + + // Step 2: Get the conversation details + $.export("$summary", "Fetching conversation details..."); + + const getConversationEndpoint = buildUrl(ENDPOINTS.CONVERSATION_BY_ID, { + conversationId, + }); + + const conversation = await makeRequest($, this.trustpilot, { + endpoint: getConversationEndpoint, + }); + + $.export("$summary", `Successfully retrieved conversation ${conversationId} for product review ${reviewId}`); + + return { + success: true, + conversation, + metadata: { + reviewId, + conversationId, + commentCount: conversation.comments?.length || 0, + conversationState: conversation.state, + source: conversation.source, + requestTime: new Date().toISOString(), + }, + }; + }, +}; diff --git a/components/trustpilot/actions/reply-to-product-review/reply-to-product-review.mjs b/components/trustpilot/actions/reply-to-product-review/reply-to-product-review.mjs index 527c9d6af84b3..1bbf3e34150b9 100644 --- a/components/trustpilot/actions/reply-to-product-review/reply-to-product-review.mjs +++ b/components/trustpilot/actions/reply-to-product-review/reply-to-product-review.mjs @@ -1,11 +1,17 @@ import { ConfigurationError } from "@pipedream/platform"; import trustpilot from "../../trustpilot.app.mjs"; +import { makeRequest } from "../../common/api-client.mjs"; +import { ENDPOINTS } from "../../common/constants.mjs"; +import { + buildUrl, + validateReviewId, +} from "../../common/utils.mjs"; export default { key: "trustpilot-reply-to-product-review", name: "Reply to Product Review", - description: "Posts a public reply to a product review on Trustpilot on behalf of your business. This action allows you to respond to customer feedback, address concerns, thank customers for positive reviews, or provide additional information about products. Replies help demonstrate your commitment to customer satisfaction and can improve your overall reputation. Note that replies are publicly visible and cannot be edited once posted. [See the documentation](https://developers.trustpilot.com/product-reviews-api#reply-to-product-review)", - version: "0.0.3", + description: "Reply to a product review by creating a conversation and posting a comment. This follows the proper flow: fetch review -> create conversation if needed -> post comment. [See the documentation](https://developers.trustpilot.com/product-reviews-api#reply-to-product-review)", + version: "0.1.0", type: "action", props: { trustpilot, @@ -15,37 +21,124 @@ export default { "reviewId", ], }, - message: { + content: { type: "string", - label: "Reply Message", - description: "The message to reply to the review with", + label: "Reply Content", + description: "The content of your reply to the review", + }, + integrationId: { + type: "string", + label: "Integration ID", + description: "Optional integration ID to track the source of the reply", + optional: true, + }, + businessUserId: { + type: "string", + label: "Business User ID", + description: "The ID of the business user posting the reply (required for creating comments)", }, }, async run({ $ }) { const { reviewId, - message, + content, + integrationId, + businessUserId, } = this; - if (!message || message.trim().length === 0) { - throw new ConfigurationError("Reply message cannot be empty"); + // Validate required parameters + if (!reviewId) { + throw new ConfigurationError("Review ID is required"); + } + if (!validateReviewId(reviewId)) { + throw new ConfigurationError("Invalid review ID format"); + } + if (!content || content.trim().length === 0) { + throw new ConfigurationError("Reply content cannot be empty"); + } + if (!businessUserId) { + throw new ConfigurationError("Business User ID is required"); } - const result = await this.trustpilot.replyToProductReview({ - reviewId, - message: message.trim(), - }); + const trimmedContent = content.trim(); - $.export("$summary", `Successfully replied to product review ${reviewId}`); + try { + // Step 1: Get the product review to check if it has a conversationId + $.export("$summary", "Fetching product review details..."); - return { - success: true, - reply: result, - metadata: { + const getReviewEndpoint = buildUrl(ENDPOINTS.PRIVATE_PRODUCT_REVIEW_BY_ID, { reviewId, - messageLength: message.trim().length, - requestTime: new Date().toISOString(), - }, - }; + }); + + const review = await makeRequest($, this.trustpilot, { + endpoint: getReviewEndpoint, + }); + + let conversationId = review.conversationId; + + // Step 2: Create conversation if it doesn't exist + if (!conversationId) { + $.export("$summary", "Creating conversation for review..."); + + const createConversationEndpoint = buildUrl(ENDPOINTS.CREATE_CONVERSATION_FOR_REVIEW, { + reviewId, + }); + + const createConversationResponse = await makeRequest($, this.trustpilot, { + endpoint: createConversationEndpoint, + method: "POST", + }); + + conversationId = createConversationResponse.conversationId; + + if (!conversationId) { + throw new Error("Failed to create conversation - no conversationId returned"); + } + } + + // Step 3: Create comment on the conversation + $.export("$summary", "Posting reply comment..."); + + const replyEndpoint = buildUrl(ENDPOINTS.REPLY_TO_CONVERSATION, { + conversationId, + }); + + // Prepare request data + const requestData = { + content: trimmedContent, + }; + + // Add integrationId if provided + if (integrationId) { + requestData.integrationId = integrationId; + } + + const replyResponse = await makeRequest($, this.trustpilot, { + endpoint: replyEndpoint, + method: "POST", + data: requestData, + additionalHeaders: { + "x-business-user-id": businessUserId, + }, + }); + + $.export("$summary", `Successfully replied to product review ${reviewId}`); + + return { + success: true, + comment: replyResponse, + metadata: { + reviewId, + conversationId, + businessUserId, + contentLength: trimmedContent.length, + integrationId: integrationId || null, + wasConversationCreated: !review.conversationId, + requestTime: new Date().toISOString(), + }, + }; + } catch (error) { + throw new ConfigurationError(`Failed to reply to product review: ${error.message}`); + } }, }; diff --git a/components/trustpilot/actions/reply-to-service-review/reply-to-service-review.mjs b/components/trustpilot/actions/reply-to-service-review/reply-to-service-review.mjs index fdc8b71e01360..f9a082ef815cf 100644 --- a/components/trustpilot/actions/reply-to-service-review/reply-to-service-review.mjs +++ b/components/trustpilot/actions/reply-to-service-review/reply-to-service-review.mjs @@ -1,20 +1,20 @@ import { ConfigurationError } from "@pipedream/platform"; import trustpilot from "../../trustpilot.app.mjs"; +import { makeRequest } from "../../common/api-client.mjs"; +import { ENDPOINTS } from "../../common/constants.mjs"; +import { + buildUrl, + validateReviewId, +} from "../../common/utils.mjs"; export default { key: "trustpilot-reply-to-service-review", name: "Reply to Service Review", - description: "Posts a public reply to a service review on Trustpilot on behalf of your business. This action enables you to engage with customers who have reviewed your services, allowing you to address complaints, clarify misunderstandings, express gratitude for positive feedback, or provide updates on how you're improving based on their input. Professional responses to reviews can significantly impact your business reputation and show potential customers that you value feedback. Remember that all replies are permanent and publicly visible. [See the documentation](https://developers.trustpilot.com/business-units-api#reply-to-review)", - version: "0.0.3", + description: "Reply to a service review on Trustpilot.", + version: "0.1.0", type: "action", props: { trustpilot, - businessUnitId: { - propDefinition: [ - trustpilot, - "businessUnitId", - ], - }, reviewId: { propDefinition: [ trustpilot, @@ -24,37 +24,79 @@ export default { message: { type: "string", label: "Reply Message", - description: "The message to reply to the review with", + description: "The message content of your reply to the review", + }, + authorBusinessUserId: { + type: "string", + label: "Author Business User ID", + description: "The ID of the business user posting the reply", }, }, async run({ $ }) { const { - businessUnitId, reviewId, message, + authorBusinessUserId, } = this; + // Validate required parameters + if (!reviewId) { + throw new ConfigurationError("Review ID is required"); + } + if (!validateReviewId(reviewId)) { + throw new ConfigurationError("Invalid review ID format"); + } if (!message || message.trim().length === 0) { throw new ConfigurationError("Reply message cannot be empty"); } + if (!authorBusinessUserId) { + throw new ConfigurationError("Author Business User ID is required"); + } - const result = await this.trustpilot.replyToServiceReview({ - businessUnitId, - reviewId, - message: message.trim(), - }); - - $.export("$summary", `Successfully replied to service review ${reviewId}`); + const trimmedMessage = message.trim(); - return { - success: true, - reply: result, - metadata: { - businessUnitId, + try { + // Build the endpoint URL for replying to service review + const endpoint = buildUrl(ENDPOINTS.REPLY_TO_SERVICE_REVIEW, { reviewId, - messageLength: message.trim().length, - requestTime: new Date().toISOString(), - }, - }; + }); + + // Prepare request data according to API specification + const requestData = { + authorBusinessUserId, + message: trimmedMessage, + }; + + // Make the API request + await makeRequest($, this.trustpilot, { + endpoint, + method: "POST", + data: requestData, + }); + + $.export("$summary", `Successfully replied to service review ${reviewId}`); + + // API returns 201 Created on success, response body may be empty + return { + success: true, + reply: { + message: trimmedMessage, + authorBusinessUserId, + reviewId, + status: "created", + statusCode: 201, + postedAt: new Date().toISOString(), + }, + metadata: { + reviewId, + authorBusinessUserId, + messageLength: trimmedMessage.length, + requestTime: new Date().toISOString(), + httpStatus: "201 Created", + }, + }; + } catch (error) { + throw new ConfigurationError(`Failed to reply to service review: ${error.message}`); + } }, }; diff --git a/components/trustpilot/common/api-client.mjs b/components/trustpilot/common/api-client.mjs new file mode 100644 index 0000000000000..74d357963bb5c --- /dev/null +++ b/components/trustpilot/common/api-client.mjs @@ -0,0 +1,111 @@ +import { axios } from "@pipedream/platform"; +import { BASE_URL } from "./constants.mjs"; +import { formatQueryParams } from "./utils.mjs"; + +/** + * Make an authenticated request to the Trustpilot API + * @param {object} trustpilotApp - The Trustpilot app instance with auth credentials + * @param {object} options - Request options + * @param {string} options.endpoint - API endpoint path + * @param {string} [options.method="GET"] - HTTP method + * @param {object} [options.params={}] - Query parameters + * @param {object} [options.data] - Request body data + * @param {object} [options.additionalHeaders={}] - Additional headers to include in the request + * @param {number} [options.timeout=30000] - Request timeout + * @returns {Promise} API response data + */ +export async function makeRequest($, trustpilotApp, { + endpoint, + method = "GET", + params = {}, + data = null, + timeout = 30000, + additionalHeaders = {}, + ...args +}) { + const url = `${BASE_URL}${endpoint}`; + const headers = { + ...getAuthHeaders(trustpilotApp, url), + ...additionalHeaders, + }; + + const config = { + method, + url, + headers, + params: formatQueryParams(params), + timeout, + ...args, + }; + + if (data) { + config.data = data; + } + + const response = await axios($ ?? trustpilotApp, config); + return response.data || response; +} + +/** + * Determine if a URL requires private authentication + * @param {string} url - The full URL + * @returns {boolean} - True if URL requires OAuth token + */ +function isPrivateURL(url) { + return url.includes("private"); +} + +/** + * Get authentication headers for private URLs (OAuth) + * @param {object} trustpilotApp - The Trustpilot app instance + * @returns {object} - Headers with OAuth token + */ +function getAuthHeadersForPrivateURL(trustpilotApp) { + if (!trustpilotApp.$auth?.oauth_access_token) { + throw new Error("Authentication required: OAuth token is required for private requests"); + } + return { + "Authorization": `Bearer ${trustpilotApp.$auth.oauth_access_token}`, + }; +} + +/** + * Get authentication headers for public URLs (API key) + * @param {object} trustpilotApp - The Trustpilot app instance + * @returns {object} - Headers with API key + */ +function getAuthHeadersForPublicURL(trustpilotApp) { + if (!trustpilotApp.$auth?.api_key) { + throw new Error("Authentication required: API key is required for public requests"); + } + return { + "apikey": trustpilotApp.$auth.api_key, + }; +} + +/** + * Get appropriate authentication headers based on URL + * @param {object} trustpilotApp - The Trustpilot app instance + * @param {string} url - The full URL + * @returns {object} - Complete headers for the request + */ +function getAuthHeaders(trustpilotApp, url) { + const headers = { + "Content-Type": "application/json", + "User-Agent": "Pipedream/1.0", + }; + + const isPrivate = isPrivateURL(url); + + if (isPrivate) { + return { + ...headers, + ...getAuthHeadersForPrivateURL(trustpilotApp), + }; + } else { + return { + ...headers, + ...getAuthHeadersForPublicURL(trustpilotApp), + }; + } +} diff --git a/components/trustpilot/common/constants.mjs b/components/trustpilot/common/constants.mjs index d993e6bb5b0b9..e2d5a8aedb50a 100644 --- a/components/trustpilot/common/constants.mjs +++ b/components/trustpilot/common/constants.mjs @@ -1,112 +1,23 @@ export const BASE_URL = "https://api.trustpilot.com/v1"; -export const WEBHOOK_EVENTS = { - REVIEW_CREATED: "review.created", - REVIEW_REVISED: "review.revised", - REVIEW_DELETED: "review.deleted", - REPLY_CREATED: "reply.created", - INVITATION_SENT: "invitation.sent", - INVITATION_FAILED: "invitation.failed", -}; - export const ENDPOINTS = { // Business Units - BUSINESS_UNITS: "/business-units", - BUSINESS_UNIT_BY_ID: "/business-units/{businessUnitId}", - - // Public Reviews - PUBLIC_REVIEWS: "/business-units/{businessUnitId}/reviews", - PUBLIC_REVIEW_BY_ID: "/business-units/{businessUnitId}/reviews/{reviewId}", + BUSINESS_UNITS: "/business-units/search", - // Private Reviews (Service) - PRIVATE_SERVICE_REVIEWS: "/private/business-units/{businessUnitId}/reviews", - PRIVATE_SERVICE_REVIEW_BY_ID: "/private/business-units/{businessUnitId}/reviews/{reviewId}", - REPLY_TO_SERVICE_REVIEW: "/private/business-units/{businessUnitId}/reviews/{reviewId}/reply", - - // Public Reviews (Product) - PUBLIC_PRODUCT_REVIEWS: "/product-reviews/business-units/{businessUnitId}/reviews", - PUBLIC_PRODUCT_REVIEW_BY_ID: "/product-reviews/{reviewId}", + // Service Reviews + SERVICE_REVIEWS: "/private/business-units/{businessUnitId}/reviews", + SERVICE_REVIEW_BY_ID: "/private/reviews/{reviewId}", + REPLY_TO_SERVICE_REVIEW: "/private/reviews/{reviewId}/reply", // Private Reviews (Product) PRIVATE_PRODUCT_REVIEWS: "/private/product-reviews/business-units/{businessUnitId}/reviews", PRIVATE_PRODUCT_REVIEW_BY_ID: "/private/product-reviews/{reviewId}", - REPLY_TO_PRODUCT_REVIEW: "/private/product-reviews/{reviewId}/reply", + CREATE_CONVERSATION_FOR_REVIEW: "/private/product-reviews/{reviewId}/create-conversation", // Conversations - CONVERSATIONS: "/private/conversations", CONVERSATION_BY_ID: "/private/conversations/{conversationId}", - REPLY_TO_CONVERSATION: "/private/conversations/{conversationId}/reply", - - // Invitations - EMAIL_INVITATIONS: "/private/business-units/{businessUnitId}/email-invitations", - - // Webhooks - // Note: This integration uses polling sources instead of webhooks for better reliability - // and simpler implementation. Webhook signature validation is implemented in the app - // using HMAC-SHA256 with the x-trustpilot-signature header for future webhook sources. - // These endpoints and validation methods are ready for webhook implementation if needed. - WEBHOOKS: "/private/webhooks", - WEBHOOK_BY_ID: "/private/webhooks/{webhookId}", + REPLY_TO_CONVERSATION: "/private/conversations/{conversationId}/comments", }; -export const REVIEW_TYPES = { - SERVICE: "service", - PRODUCT: "product", -}; - -export const INVITATION_TYPES = { - REVIEW: "review", - PRODUCT_REVIEW: "product-review", -}; - -export const SORT_OPTIONS = { - CREATED_AT_ASC: "createdat.asc", - CREATED_AT_DESC: "createdat.desc", - STARS_ASC: "stars.asc", - STARS_DESC: "stars.desc", - UPDATED_AT_ASC: "updatedat.asc", - UPDATED_AT_DESC: "updatedat.desc", -}; - -export const RATING_SCALE = [ - 1, - 2, - 3, - 4, - 5, -]; - export const DEFAULT_LIMIT = 20; export const MAX_LIMIT = 100; - -export const HTTP_STATUS = { - OK: 200, - CREATED: 201, - NO_CONTENT: 204, - BAD_REQUEST: 400, - UNAUTHORIZED: 401, - FORBIDDEN: 403, - NOT_FOUND: 404, - TOO_MANY_REQUESTS: 429, - INTERNAL_SERVER_ERROR: 500, -}; - -export const RETRY_CONFIG = { - MAX_RETRIES: 3, - INITIAL_DELAY: 1000, - MAX_DELAY: 10000, -}; - -export const POLLING_CONFIG = { - DEFAULT_TIMER_INTERVAL_SECONDS: 15 * 60, // 15 minutes - MAX_ITEMS_PER_POLL: 100, - LOOKBACK_HOURS: 24, // How far back to look on first run -}; - -export const SOURCE_TYPES = { - NEW_REVIEWS: "new_reviews", - UPDATED_REVIEWS: "updated_reviews", - NEW_REPLIES: "new_replies", - NEW_CONVERSATIONS: "new_conversations", - UPDATED_CONVERSATIONS: "updated_conversations", -}; diff --git a/components/trustpilot/common/utils.mjs b/components/trustpilot/common/utils.mjs index 20677e7cac566..89c3e059f1139 100644 --- a/components/trustpilot/common/utils.mjs +++ b/components/trustpilot/common/utils.mjs @@ -100,46 +100,113 @@ export function parseReview(review) { } /** - * Parse Trustpilot business unit data - * @param {object} businessUnit - Raw business unit data from API - * @returns {object} - Parsed business unit data + * Parse Trustpilot product review data + * @param {object} review - Raw product review data from API + * @returns {object} - Parsed product review data */ -export function parseBusinessUnit(businessUnit) { +export function parseProductReview(review) { return { - id: businessUnit.id, - displayName: businessUnit.displayName, - identifyingName: businessUnit.identifyingName, - trustScore: businessUnit.trustScore, - stars: businessUnit.stars, - numberOfReviews: businessUnit.numberOfReviews, - profileUrl: businessUnit.profileUrl, - websiteUrl: businessUnit.websiteUrl, - country: businessUnit.country, - status: businessUnit.status, - createdAt: businessUnit.createdAt, - categories: businessUnit.categories || [], - images: businessUnit.images || [], + id: review.id, + createdAt: review.createdAt, + updatedAt: review.updatedAt, + businessUnitId: review.businessUnitId, + stars: review.stars, + content: escapeHtml(review.content), + product: review.product + ? { + id: review.product.id, + productUrl: review.product.productUrl, + productImages: review.product.productImages || [], + name: escapeHtml(review.product.name), + sku: review.product.sku, + gtin: review.product.gtin, + mpn: review.product.mpn, + brand: escapeHtml(review.product.brand), + } + : null, + consumer: review.consumer + ? { + id: review.consumer.id, + email: review.consumer.email, + name: escapeHtml(review.consumer.name), + } + : null, + referenceId: review.referenceId, + locale: review.locale, + language: review.language, + redirectUri: review.redirectUri, + state: review.state, + hasModerationHistory: review.hasModerationHistory || false, + conversationId: review.conversationId, + attributeRatings: review.attributeRatings?.map((attr) => ({ + attributeId: attr.attributeId, + attributeName: escapeHtml(attr.attributeName), + attributeType: attr.attributeType, + attributeOptions: attr.attributeOptions, + rating: attr.rating, + })) || [], + attachments: review.attachments || [], }; } /** - * Parse webhook payload - * @param {object} payload - Raw webhook payload - * @returns {object} - Parsed webhook data + * Parse Trustpilot service review data + * @param {object} review - Raw service review data from API + * @returns {object} - Parsed service review data */ -export function parseWebhookPayload(payload) { - const { - event, data, - } = payload; - +export function parseServiceReview(review) { return { - event: event?.type || payload.eventType, - timestamp: event?.timestamp || payload.timestamp, - businessUnitId: data?.businessUnit?.id || payload.businessUnitId, - reviewId: data?.review?.id || payload.reviewId, - consumerId: data?.consumer?.id || payload.consumerId, - data: data || payload.data, - raw: payload, + links: review.links || [], + id: review.id, + consumer: review.consumer + ? { + links: review.consumer.links || [], + id: review.consumer.id, + displayName: escapeHtml(review.consumer.displayName), + displayLocation: escapeHtml(review.consumer.displayLocation), + numberOfReviews: review.consumer.numberOfReviews, + } + : null, + businessUnit: review.businessUnit + ? { + links: review.businessUnit.links || [], + id: review.businessUnit.id, + identifyingName: escapeHtml(review.businessUnit.identifyingName), + displayName: escapeHtml(review.businessUnit.displayName), + } + : null, + location: escapeHtml(review.location), + stars: review.stars, + title: escapeHtml(review.title), + text: escapeHtml(review.text), + language: review.language, + createdAt: review.createdAt, + experiencedAt: review.experiencedAt, + updatedAt: review.updatedAt, + companyReply: review.companyReply + ? { + text: escapeHtml(review.companyReply.text), + authorBusinessUserId: review.companyReply.authorBusinessUserId, + authorBusinessUserName: escapeHtml(review.companyReply.authorBusinessUserName), + createdAt: review.companyReply.createdAt, + updatedAt: review.companyReply.updatedAt, + } + : null, + isVerified: review.isVerified || false, + source: review.source, + numberOfLikes: review.numberOfLikes || 0, + status: review.status, + reportData: review.reportData, + complianceLabels: review.complianceLabels || [], + countsTowardsTrustScore: review.countsTowardsTrustScore || false, + countsTowardsLocationTrustScore: review.countsTowardsLocationTrustScore, + invitation: review.invitation + ? { + businessUnitId: review.invitation.businessUnitId, + } + : null, + businessUnitHistory: review.businessUnitHistory || [], + reviewVerificationLevel: review.reviewVerificationLevel, }; } @@ -214,12 +281,3 @@ export function parseApiError(error) { code: "UNKNOWN_ERROR", }; } - -/** - * Sleep function for retry logic - * @param {number} ms - Milliseconds to sleep - * @returns {Promise} - Promise that resolves after delay - */ -export function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} diff --git a/components/trustpilot/package.json b/components/trustpilot/package.json index 7e03ac2b66435..5c3271fa982b2 100644 --- a/components/trustpilot/package.json +++ b/components/trustpilot/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/trustpilot", - "version": "0.1.3", + "version": "0.2.0", "description": "Pipedream Trustpilot Components", "main": "trustpilot.app.mjs", "keywords": [ diff --git a/components/trustpilot/sources/common/polling.mjs b/components/trustpilot/sources/common/polling.mjs index 2af5b59d4c30a..112ded8cb876a 100644 --- a/components/trustpilot/sources/common/polling.mjs +++ b/components/trustpilot/sources/common/polling.mjs @@ -1,19 +1,11 @@ import trustpilot from "../../trustpilot.app.mjs"; -import { - POLLING_CONFIG, SOURCE_TYPES, -} from "../../common/constants.mjs"; +import { DEFAULT_LIMIT } from "../../common/constants.mjs"; /** * Base polling source for Trustpilot integration * - * This integration uses polling instead of webhooks for the following reasons: - * 1. Better reliability - polling ensures no events are missed - * 2. Simpler implementation - no need for webhook endpoint management - * 3. Consistent data retrieval - can backfill historical data if needed - * 4. Works with all authentication methods (API key and OAuth) - * - * All sources poll every 15 minutes by default and maintain deduplication - * to ensure events are only emitted once. + * Provides common functionality for polling Trustpilot API endpoints + * and emitting new events with deduplication. */ export default { props: { @@ -22,7 +14,7 @@ export default { timer: { type: "$.interface.timer", default: { - intervalSeconds: POLLING_CONFIG.DEFAULT_TIMER_INTERVAL_SECONDS, + intervalSeconds: 15 * 60, // 15 minutes }, }, businessUnitId: { @@ -30,159 +22,120 @@ export default { trustpilot, "businessUnitId", ], - optional: true, - description: "Business Unit ID to filter events for. If not provided, will receive events for all business units.", }, }, methods: { - _getLastPolled() { - return this.db.get("lastPolled"); - }, - _setLastPolled(timestamp) { - this.db.set("lastPolled", timestamp); - }, - _getSeenItems() { - return this.db.get("seenItems") || {}; - }, - _setSeenItems(seenItems) { - this.db.set("seenItems", seenItems); - }, - _cleanupSeenItems(seenItems, hoursToKeep = 72) { - const cutoff = Date.now() - (hoursToKeep * 60 * 60 * 1000); - const cleaned = {}; - - Object.entries(seenItems).forEach(([ - key, - timestamp, - ]) => { - if (timestamp > cutoff) { - cleaned[key] = timestamp; - } - }); - - return cleaned; - }, - getSourceType() { - // Override in child classes - return SOURCE_TYPES.NEW_REVIEWS; - }, - getPollingMethod() { - // Override in child classes to return the app method to call - throw new Error("getPollingMethod must be implemented in child class"); - }, - getPollingParams() { - // Override in child classes to return method-specific parameters + _getLastReviewTime() { + return this.db.get(`lastReviewTime:${this.businessUnitId}`); + }, + _setLastReviewTime(time) { + this.db.set(`lastReviewTime:${this.businessUnitId}`, time); + }, + /** + * Override in child classes to provide review type-specific summary + * @param {Object} _review - The review object + * @returns {string} - Human-readable summary + */ + // eslint-disable-next-line no-unused-vars + generateSummary(_review) { + throw new Error("generateSummary must be implemented in child class"); + }, + /** + * Override in child classes to fetch reviews. + * Requirements: + * - Must return ALL reviews newer than `lastReviewTime` (handle pagination internally), or + * - Return the first page AND expose a pagination cursor so the base can iterate (future). + * @param {Object} _$ - Pipedream step context + * @param {Object} _params - Fetch parameters produced by `getFetchParams(lastReviewTime)` + * @returns {{ reviews: Array }} - Array of normalized reviews + */ + // eslint-disable-next-line no-unused-vars + async fetchReviews(_$, _params) { + throw new Error("fetchReviews must be implemented in child class"); + }, + /** + * Override in child classes to provide fetch parameters + * @param {string} _lastReviewTime - ISO timestamp of last review + * @returns {Object} - Parameters for fetchReviews call + */ + // eslint-disable-next-line no-unused-vars + getFetchParams(_lastReviewTime) { return { businessUnitId: this.businessUnitId, - limit: POLLING_CONFIG.MAX_ITEMS_PER_POLL, - sortBy: "createdat.desc", // Most recent first - }; - }, - isNewItem(item, sourceType) { - // For "new" sources, check creation date - // For "updated" sources, check update date - const itemDate = sourceType.includes("updated") - ? new Date(item.updatedAt) - : new Date(item.createdAt || item.updatedAt); - - const lastPolled = this._getLastPolled(); - return !lastPolled || itemDate > new Date(lastPolled); - }, - generateDedupeKey(item, sourceType) { - // Create unique key: itemId + relevant timestamp - const timestamp = sourceType.includes("updated") - ? item.updatedAt - : (item.createdAt || item.updatedAt); - - return `${item.id}_${timestamp}`; - }, - generateMeta(item, sourceType) { - const dedupeKey = this.generateDedupeKey(item, sourceType); - const summary = this.generateSummary(item); - const timestamp = sourceType.includes("updated") - ? item.updatedAt - : (item.createdAt || item.updatedAt); - - return { - id: dedupeKey, - summary, - ts: new Date(timestamp).getTime(), + perPage: DEFAULT_LIMIT, }; }, - generateSummary(item) { - // Override in child classes for specific summaries - return `${this.getSourceType()} - ${item.id}`; + /** + * Override in child classes to filter reviews (for APIs without time filtering) + * @param {Array} reviews - Array of reviews from API + * @param {string} _lastReviewTime - ISO timestamp of last review + * @returns {Array} - Filtered array of new reviews + */ + // eslint-disable-next-line no-unused-vars + filterNewReviews(reviews, _lastReviewTime) { + if (!_lastReviewTime) return reviews; + const lastMs = Date.parse(_lastReviewTime); + if (Number.isNaN(lastMs)) return reviews; + + return reviews.filter((r) => { + const ms = Date.parse(r?.createdAt); + return Number.isFinite(ms) && ms > lastMs; + }); }, - async fetchItems() { - const method = this.getPollingMethod(); - const params = this.getPollingParams(); - - try { - const result = await this.trustpilot[method](params); - - // Handle different response formats - if (result.reviews) { - return result.reviews; - } else if (result.conversations) { - return result.conversations; - } else if (Array.isArray(result)) { - return result; - } else { - return []; - } - } catch (error) { - console.error(`Error fetching items with ${method}:`, error); - throw error; + }, + async run({ $ }) { + // Get the last review time for filtering new reviews + const lastReviewTime = this._getLastReviewTime(); + + // Get fetch parameters from child class + const fetchParams = this.getFetchParams(lastReviewTime); + + // Fetch reviews using child class method + const result = await this.fetchReviews($, fetchParams); + const reviews = result.reviews || []; + + if (!reviews.length) { + console.log("No reviews found"); + return; + } + + // Filter for new reviews (child class may override) + const newReviews = this.filterNewReviews(reviews, lastReviewTime); + + if (!newReviews.length) { + console.log("No new reviews since last poll"); + return; + } + + // Track the latest review time + let latestReviewTime = lastReviewTime; + + for (const review of newReviews) { + // Track the latest review time + const createdMs = Date.parse(review?.createdAt); + if (!Number.isFinite(createdMs)) { + ($.logger?.warn ?? console.warn)("Skipping review with invalid createdAt", { + id: review?.id, + createdAt: review?.createdAt, + }); + continue; + } + const reviewTime = new Date(createdMs).toISOString(); + if (!latestReviewTime || createdMs > Date.parse(latestReviewTime)) { + latestReviewTime = reviewTime; } - }, - async pollForItems() { - const sourceType = this.getSourceType(); - const lastPolled = this._getLastPolled(); - const seenItems = this._getSeenItems(); - - // If first run, look back 24 hours - const lookbackMs = POLLING_CONFIG.LOOKBACK_HOURS * 60 * 60 * 1000; - const since = lastPolled || new Date(Date.now() - lookbackMs).toISOString(); - - console.log(`Polling for ${sourceType} since ${since}`); - - try { - const items = await this.fetchItems(since); - const newItems = []; - const currentTime = Date.now(); - - for (const item of items) { - // Check if item is new based on source type - if (this.isNewItem(item, sourceType)) { - const dedupeKey = this.generateDedupeKey(item, sourceType); - - // Check if we've already seen this exact item+timestamp - if (!seenItems[dedupeKey]) { - seenItems[dedupeKey] = currentTime; - newItems.push(item); - } - } - } - - // Emit new items - for (const item of newItems.reverse()) { // Oldest first - const meta = this.generateMeta(item, sourceType); - this.$emit(item, meta); - } - - // Update state - this._setLastPolled(new Date().toISOString()); - this._setSeenItems(this._cleanupSeenItems(seenItems)); - console.log(`Found ${newItems.length} new items of type ${sourceType}`); + // Emit the review with unique ID and summary + this.$emit(review, { + id: review.id, + summary: this.generateSummary(review), + ts: createdMs, + }); + } - } catch (error) { - console.error(`Polling failed for ${sourceType}:`, error); - throw error; - } - }, - }, - async run() { - await this.pollForItems(); + // Update the last review time for next poll + if (latestReviewTime && latestReviewTime !== lastReviewTime) { + this._setLastReviewTime(latestReviewTime); + } }, }; diff --git a/components/trustpilot/sources/new-conversations/new-conversations.mjs b/components/trustpilot/sources/new-conversations/new-conversations.mjs deleted file mode 100644 index d9671f964605e..0000000000000 --- a/components/trustpilot/sources/new-conversations/new-conversations.mjs +++ /dev/null @@ -1,41 +0,0 @@ -import { - SORT_OPTIONS, - SOURCE_TYPES, -} from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; - -export default { - ...common, - key: "trustpilot-new-conversations", - name: "New Conversations", - description: "Emit new event when a new conversation is started on Trustpilot. This source periodically polls the Trustpilot API to detect new customer-business conversations. Each event contains conversation details including participants, subject, business unit, and creation timestamp. Useful for tracking customer inquiries, support requests, and maintaining real-time communication with customers.", - version: "0.0.3", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - getSourceType() { - return SOURCE_TYPES.NEW_CONVERSATIONS; - }, - getPollingMethod() { - return "getConversations"; - }, - getPollingParams() { - return { - businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.CREATED_AT_DESC, - offset: 0, - }; - }, - generateSummary(item) { - const participantName = item.participants?.[0]?.displayName || - item.consumer?.displayName || - "Anonymous"; - const subject = item.subject || item.title || "New conversation"; - const businessUnit = item.businessUnit?.displayName || this.businessUnitId || "Unknown"; - - return `New conversation "${subject}" started by ${participantName} (${businessUnit})`; - }, - }, -}; diff --git a/components/trustpilot/sources/new-product-review-replies/new-product-review-replies.mjs b/components/trustpilot/sources/new-product-review-replies/new-product-review-replies.mjs deleted file mode 100644 index faeb1b447d0e2..0000000000000 --- a/components/trustpilot/sources/new-product-review-replies/new-product-review-replies.mjs +++ /dev/null @@ -1,72 +0,0 @@ -import { - SORT_OPTIONS, - SOURCE_TYPES, -} from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; - -export default { - ...common, - key: "trustpilot-new-product-review-replies", - name: "New Product Review Replies", - description: "Emit new event when a business replies to a product review on Trustpilot. This source periodically polls the Trustpilot API to detect new replies to product reviews. Each event includes the reply text, creation timestamp, and associated review details (product name, star rating, consumer info). Ideal for monitoring business responses to customer feedback, tracking customer service performance, and ensuring timely engagement with product reviews.", - version: "0.0.3", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - getSourceType() { - return SOURCE_TYPES.NEW_REPLIES; - }, - getPollingMethod() { - return "getProductReviews"; - }, - getPollingParams() { - return { - businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.UPDATED_AT_DESC, // Use updated to catch new replies - offset: 0, - }; - }, - async fetchItems() { - const result = await this.trustpilot.getProductReviews(this.getPollingParams()); - - // Filter for reviews that have replies and extract the replies - const repliesWithReviews = []; - - if (result.reviews) { - for (const review of result.reviews) { - if (review.company?.reply) { - // Create a pseudo-reply object that includes review context - repliesWithReviews.push({ - id: `reply_${review.id}`, - reviewId: review.id, - text: review.company.reply.text, - createdAt: review.company.reply.createdAt, - updatedAt: review.company.reply.createdAt, // Replies don't get updated - review: { - id: review.id, - title: review.title, - stars: review.stars, - consumer: review.consumer, - product: review.product, - }, - }); - } - } - } - - return repliesWithReviews; - }, - generateSummary(item) { - const productName = item.review?.product?.title || "Unknown Product"; - const consumerName = item.review?.consumer?.displayName || "Anonymous"; - const replyPreview = item.text?.substring(0, 50) || ""; - const preview = replyPreview.length > 50 - ? `${replyPreview}...` - : replyPreview; - - return `New reply to product "${productName}" review by ${consumerName}: "${preview}"`; - }, - }, -}; diff --git a/components/trustpilot/sources/new-product-reviews/new-product-reviews.mjs b/components/trustpilot/sources/new-product-reviews/new-product-reviews.mjs index 8a68b21f553a1..d04132e3c7f92 100644 --- a/components/trustpilot/sources/new-product-reviews/new-product-reviews.mjs +++ b/components/trustpilot/sources/new-product-reviews/new-product-reviews.mjs @@ -1,40 +1,91 @@ +import common from "../common/polling.mjs"; import { - SORT_OPTIONS, - SOURCE_TYPES, + DEFAULT_LIMIT, + MAX_LIMIT, } from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; export default { ...common, key: "trustpilot-new-product-reviews", name: "New Product Reviews", description: "Emit new event when a customer posts a new product review on Trustpilot. This source periodically polls the Trustpilot API to detect new product reviews. Each event contains the complete review data including star rating, review text, product information, consumer details, and timestamps. Perfect for monitoring product feedback, analyzing customer satisfaction trends, and triggering automated responses or alerts for specific products.", - version: "0.0.3", + version: "0.1.0", type: "source", dedupe: "unique", methods: { ...common.methods, - getSourceType() { - return SOURCE_TYPES.NEW_REVIEWS; - }, - getPollingMethod() { - return "getProductReviews"; + generateSummary(review) { + const stars = review.stars || "N/A"; + const consumerName = review.consumer?.name || "Anonymous"; + const productName = review.product?.name || "Unknown Product"; + const businessUnit = this.businessUnitId || "Unknown"; + + return `New ${stars}-star product review by ${consumerName} for "${productName}" (${businessUnit})`; }, - getPollingParams() { + getFetchParams() { + // Note: Product reviews API doesn't support time-based filtering, + // so we'll rely on pagination and client-side filtering return { businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.CREATED_AT_DESC, - offset: 0, + perPage: DEFAULT_LIMIT, + page: 1, }; }, - generateSummary(item) { - const stars = item.stars || "N/A"; - const consumerName = item.consumer?.displayName || "Anonymous"; - const productName = item.product?.title || "Unknown Product"; - const businessUnit = item.businessUnit?.displayName || this.businessUnitId || "Unknown"; + async fetchReviews($, params) { + const perPage = params.perPage ?? DEFAULT_LIMIT; + let page = params.page ?? 1; - return `New ${stars}-star product review by ${consumerName} for "${productName}" (${businessUnit})`; + // fetch first page + let result = await this.trustpilot.fetchProductReviews($, { + ...params, + page, + }); + let all = Array.isArray(result.reviews) + ? result.reviews + : []; + let lastPageSize = all.length; + + // keep paging while we get a full page and stay under MAX_LIMIT + while (lastPageSize === perPage && all.length < MAX_LIMIT) { + page += 1; + const next = await this.trustpilot.fetchProductReviews($, { + ...params, + page, + }); + const chunk = Array.isArray(next.reviews) ? + next.reviews : + []; + if (chunk.length === 0) break; + + all = all.concat(chunk); + lastPageSize = chunk.length; + result = next; // preserve any metadata from the latest fetch + } + + // truncate to MAX_LIMIT in case there are more than allowed + result.reviews = all.slice(0, MAX_LIMIT); + return result; + }, + filterNewReviews(reviews, lastReviewTime) { + // Product reviews require client-side filtering since API doesn't support + // time-based filtering + const lastTs = Number(lastReviewTime) || 0; + const toMs = (d) => new Date(d).getTime(); + + return lastTs + ? reviews.filter((r) => toMs(r.createdAt) > lastTs) + : reviews; + }, + _getLastReviewTime() { + // Product reviews store timestamp as number (ms), others store as ISO string + return this.db.get("lastReviewTime"); + }, + _setLastReviewTime(time) { + // Store as number for product reviews to match existing behavior + const timeMs = typeof time === "string" + ? new Date(time).getTime() + : time; + this.db.set("lastReviewTime", timeMs); }, }, }; diff --git a/components/trustpilot/sources/new-service-review-replies/new-service-review-replies.mjs b/components/trustpilot/sources/new-service-review-replies/new-service-review-replies.mjs deleted file mode 100644 index 98e65170cccdf..0000000000000 --- a/components/trustpilot/sources/new-service-review-replies/new-service-review-replies.mjs +++ /dev/null @@ -1,71 +0,0 @@ -import { - SORT_OPTIONS, - SOURCE_TYPES, -} from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; - -export default { - ...common, - key: "trustpilot-new-service-review-replies", - name: "New Service Review Replies", - description: "Emit new event when a business replies to a service review on Trustpilot. This source periodically polls the Trustpilot API to detect new replies to service reviews. Each event includes the reply text, creation timestamp, and associated review details (star rating, review title, consumer info). Essential for tracking business engagement with customer feedback, monitoring response times, and ensuring all service reviews receive appropriate attention.", - version: "0.0.3", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - getSourceType() { - return SOURCE_TYPES.NEW_REPLIES; - }, - getPollingMethod() { - return "getServiceReviews"; - }, - getPollingParams() { - return { - businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.UPDATED_AT_DESC, // Use updated to catch new replies - offset: 0, - }; - }, - async fetchItems() { - const result = await this.trustpilot.getServiceReviews(this.getPollingParams()); - - // Filter for reviews that have replies and extract the replies - const repliesWithReviews = []; - - if (result.reviews) { - for (const review of result.reviews) { - if (review.company?.reply) { - // Create a pseudo-reply object that includes review context - repliesWithReviews.push({ - id: `reply_${review.id}`, - reviewId: review.id, - text: review.company.reply.text, - createdAt: review.company.reply.createdAt, - updatedAt: review.company.reply.createdAt, // Replies don't get updated - review: { - id: review.id, - title: review.title, - stars: review.stars, - consumer: review.consumer, - }, - }); - } - } - } - - return repliesWithReviews; - }, - generateSummary(item) { - const reviewTitle = item.review?.title || "Review"; - const consumerName = item.review?.consumer?.displayName || "Anonymous"; - const replyPreview = item.text?.substring(0, 50) || ""; - const preview = replyPreview.length > 50 - ? `${replyPreview}...` - : replyPreview; - - return `New reply to "${reviewTitle}" by ${consumerName}: "${preview}"`; - }, - }, -}; diff --git a/components/trustpilot/sources/new-service-reviews/new-service-reviews.mjs b/components/trustpilot/sources/new-service-reviews/new-service-reviews.mjs index 22c2787be72a8..e58cce907fe95 100644 --- a/components/trustpilot/sources/new-service-reviews/new-service-reviews.mjs +++ b/components/trustpilot/sources/new-service-reviews/new-service-reviews.mjs @@ -1,40 +1,60 @@ +import common from "../common/polling.mjs"; import { - SORT_OPTIONS, - SOURCE_TYPES, + DEFAULT_LIMIT, + MAX_LIMIT, } from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; export default { ...common, key: "trustpilot-new-service-reviews", name: "New Service Reviews", - description: "Emit new event when a customer posts a new service review on Trustpilot. This source periodically polls the Trustpilot API to detect new service reviews, combining both public and private reviews for comprehensive coverage. Each event contains the complete review data including star rating, review text, consumer details, business unit info, and timestamps. Ideal for monitoring overall business reputation, tracking customer satisfaction metrics, and triggering workflows based on review ratings or content.", - version: "0.0.3", + description: "Emit new event when a customer posts a new service review on Trustpilot. This source periodically polls the Trustpilot API to detect new service reviews using the private reviews API for comprehensive coverage.", + version: "0.1.0", type: "source", dedupe: "unique", methods: { ...common.methods, - getSourceType() { - return SOURCE_TYPES.NEW_REVIEWS; - }, - getPollingMethod() { - // Use private endpoint first as it has more data, fallback to public if needed - return "getServiceReviews"; + generateSummary(review) { + const stars = review.stars || "N/A"; + const consumerName = review.consumer?.displayName || "Anonymous"; + const businessUnit = review.businessUnit?.displayName || this.businessUnitId || "Unknown"; + + return `New ${stars}-star service review by ${consumerName} for ${businessUnit}`; }, - getPollingParams() { - return { + getFetchParams(lastReviewTime) { + const params = { businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.CREATED_AT_DESC, - offset: 0, + perPage: DEFAULT_LIMIT, + orderBy: "createdat.desc", }; + + // If we have a last review time, filter for reviews after that time + if (lastReviewTime) { + params.startDateTime = lastReviewTime; + } + + return params; }, - generateSummary(item) { - const stars = item.stars || "N/A"; - const consumerName = item.consumer?.displayName || "Anonymous"; - const businessUnit = item.businessUnit?.displayName || this.businessUnitId || "Unknown"; + async fetchReviews($, params) { + // Use the shared method from the app directly with pagination support + let result = await this.trustpilot.fetchServiceReviews($, params); - return `New ${stars}-star service review by ${consumerName} for ${businessUnit}`; + // Handle pagination for service reviews + if (result.reviews && result.reviews.length === DEFAULT_LIMIT) { + while (true) { + params.page = (params.page || 1) + 1; + const nextResult = await this.trustpilot.fetchServiceReviews($, params); + result.reviews = result.reviews.concat(nextResult.reviews || []); + + if (!nextResult.reviews || + nextResult.reviews.length < DEFAULT_LIMIT || + result.reviews.length >= MAX_LIMIT) { + break; + } + } + } + + return result; }, }, }; diff --git a/components/trustpilot/sources/updated-conversations/updated-conversations.mjs b/components/trustpilot/sources/updated-conversations/updated-conversations.mjs deleted file mode 100644 index fe839cb905253..0000000000000 --- a/components/trustpilot/sources/updated-conversations/updated-conversations.mjs +++ /dev/null @@ -1,42 +0,0 @@ -import { - SORT_OPTIONS, - SOURCE_TYPES, -} from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; - -export default { - ...common, - key: "trustpilot-updated-conversations", - name: "New Updated Conversations", - description: "Emit new event when an existing conversation is updated with new messages on Trustpilot. This source periodically polls the Trustpilot API to detect conversations that have received new messages. Each event contains updated conversation details including participants, subject, message count, and latest update timestamp. Useful for tracking ongoing customer interactions, ensuring timely responses to follow-up messages, and maintaining conversation continuity.", - version: "0.0.3", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - getSourceType() { - return SOURCE_TYPES.UPDATED_CONVERSATIONS; - }, - getPollingMethod() { - return "getConversations"; - }, - getPollingParams() { - return { - businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.UPDATED_AT_DESC, - offset: 0, - }; - }, - generateSummary(item) { - const participantName = item.participants?.[0]?.displayName || - item.consumer?.displayName || - "Anonymous"; - const subject = item.subject || item.title || "Conversation"; - const businessUnit = item.businessUnit?.displayName || this.businessUnitId || "Unknown"; - const messageCount = item.messageCount || item.messages?.length || "Unknown"; - - return `Conversation "${subject}" updated by ${participantName} (${messageCount} messages) - ${businessUnit}`; - }, - }, -}; diff --git a/components/trustpilot/sources/updated-product-reviews/updated-product-reviews.mjs b/components/trustpilot/sources/updated-product-reviews/updated-product-reviews.mjs deleted file mode 100644 index 1d2cec1ae341a..0000000000000 --- a/components/trustpilot/sources/updated-product-reviews/updated-product-reviews.mjs +++ /dev/null @@ -1,40 +0,0 @@ -import { - SORT_OPTIONS, - SOURCE_TYPES, -} from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; - -export default { - ...common, - key: "trustpilot-updated-product-reviews", - name: "New Updated Product Reviews", - description: "Emit new event when an existing product review is updated or revised on Trustpilot. This source periodically polls the Trustpilot API to detect product reviews that have been modified. Each event contains the updated review data including any changes to star rating, review text, or other review attributes. Perfect for tracking review modifications, monitoring changes in customer sentiment, and ensuring product feedback accuracy over time.", - version: "0.0.3", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - getSourceType() { - return SOURCE_TYPES.UPDATED_REVIEWS; - }, - getPollingMethod() { - return "getProductReviews"; - }, - getPollingParams() { - return { - businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.UPDATED_AT_DESC, - offset: 0, - }; - }, - generateSummary(item) { - const stars = item.stars || "N/A"; - const consumerName = item.consumer?.displayName || "Anonymous"; - const productName = item.product?.title || "Unknown Product"; - const businessUnit = item.businessUnit?.displayName || this.businessUnitId || "Unknown"; - - return `Product review updated by ${consumerName} (${stars} stars) for "${productName}" (${businessUnit})`; - }, - }, -}; diff --git a/components/trustpilot/sources/updated-service-reviews/updated-service-reviews.mjs b/components/trustpilot/sources/updated-service-reviews/updated-service-reviews.mjs deleted file mode 100644 index 13f9721b634a8..0000000000000 --- a/components/trustpilot/sources/updated-service-reviews/updated-service-reviews.mjs +++ /dev/null @@ -1,39 +0,0 @@ -import { - SORT_OPTIONS, - SOURCE_TYPES, -} from "../../common/constants.mjs"; -import common from "../common/polling.mjs"; - -export default { - ...common, - key: "trustpilot-updated-service-reviews", - name: "New Updated Service Reviews", - description: "Emit new event when an existing service review is updated or revised on Trustpilot. This source periodically polls the Trustpilot API to detect service reviews that have been modified. Each event contains the updated review data including any changes to star rating, review text, or other review attributes. Essential for tracking review modifications, monitoring evolving customer feedback, and identifying patterns in review updates.", - version: "0.0.3", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - getSourceType() { - return SOURCE_TYPES.UPDATED_REVIEWS; - }, - getPollingMethod() { - return "getServiceReviews"; - }, - getPollingParams() { - return { - businessUnitId: this.businessUnitId, - limit: 100, - sortBy: SORT_OPTIONS.UPDATED_AT_DESC, - offset: 0, - }; - }, - generateSummary(item) { - const stars = item.stars || "N/A"; - const consumerName = item.consumer?.displayName || "Anonymous"; - const businessUnit = item.businessUnit?.displayName || this.businessUnitId || "Unknown"; - - return `Service review updated by ${consumerName} (${stars} stars) for ${businessUnit}`; - }, - }, -}; diff --git a/components/trustpilot/trustpilot.app.mjs b/components/trustpilot/trustpilot.app.mjs index 2f6be2e4e5e3b..31e6f84f23d8d 100644 --- a/components/trustpilot/trustpilot.app.mjs +++ b/components/trustpilot/trustpilot.app.mjs @@ -1,25 +1,10 @@ -import { axios } from "@pipedream/platform"; -import * as crypto from "crypto"; -import { - BASE_URL, - DEFAULT_LIMIT, - ENDPOINTS, - HTTP_STATUS, - MAX_LIMIT, - RATING_SCALE, - RETRY_CONFIG, - SORT_OPTIONS, -} from "./common/constants.mjs"; +import { makeRequest } from "./common/api-client.mjs"; +import { ENDPOINTS } from "./common/constants.mjs"; import { buildUrl, - formatQueryParams, - parseBusinessUnit, - parseReview, - parseWebhookPayload, - sanitizeInput, - sleep, + parseServiceReview, + parseProductReview, validateBusinessUnitId, - validateReviewId, } from "./common/utils.mjs"; export default { @@ -30,18 +15,33 @@ export default { type: "string", label: "Business Unit ID", description: "The unique identifier for your business unit on Trustpilot", - async options() { + useQuery: true, + async options({ + page, query, + }) { try { + if (query === "") { + // Trustpilot requires a query to be passed in, default to "a" if empty + query = "a"; + } + const businessUnits = await this.searchBusinessUnits({ - query: "", - limit: 20, + // Trustpilot requires the page to be 1-indexed + // whereas pipedream is 0-indexed + page: page + 1, + query, + }); + + return businessUnits.map((businessUnit) => { + const { + id, displayName, + } = businessUnit; + + return { + label: displayName, + value: id, + }; }); - return businessUnits.map(({ - id, displayName, name: { identifying }, - }) => ({ - label: `${identifying || displayName}`, - value: id, - })); } catch (error) { console.error("Error fetching business units:", error); return []; @@ -53,47 +53,27 @@ export default { label: "Review ID", description: "The unique identifier for a review", }, - stars: { - type: "integer", - label: "Star Rating", - description: "Filter by star rating (1-5)", - options: RATING_SCALE, - optional: true, - }, - sortBy: { + sku: { type: "string", - label: "Sort By", - description: "How to sort the results", - options: Object.entries(SORT_OPTIONS).map(([ - key, - value, - ]) => ({ - label: key.replace(/_/g, " ").toLowerCase(), - value, - })), + label: "SKU", + description: "Filter by SKU", optional: true, - default: SORT_OPTIONS.CREATED_AT_DESC, }, - limit: { + page: { type: "integer", - label: "Limit", - description: "Maximum number of results to return", + label: "Page", + description: "The page to retrieve", min: 1, - max: MAX_LIMIT, - default: DEFAULT_LIMIT, + default: 1, optional: true, }, - includeReportedReviews: { - type: "boolean", - label: "Include Reported Reviews", - description: "Whether to include reviews that have been reported", - default: false, - optional: true, - }, - tags: { - type: "string[]", - label: "Tags", - description: "Filter reviews by tags", + perPage: { + type: "integer", + label: "Per Page", + description: "The number of items to retrieve per page", + min: 1, + max: 100, + default: 20, optional: true, }, language: { @@ -102,479 +82,162 @@ export default { description: "Filter reviews by language (ISO 639-1 code)", optional: true, }, - }, - methods: { - // Authentication and base request methods - _getAuthHeaders() { - const headers = { - "Content-Type": "application/json", - "User-Agent": "Pipedream/1.0", - }; - - if (!this.$auth?.api_key && !this.$auth?.oauth_access_token) { - throw new Error("Authentication required: Configure either API key or OAuth token"); - } - - if (this.$auth?.api_key) { - headers["apikey"] = this.$auth.api_key; - } - - if (this.$auth?.oauth_access_token) { - headers["Authorization"] = `Bearer ${this.$auth.oauth_access_token}`; - } - - return headers; - }, - - async _makeRequest({ - endpoint, method = "GET", params = {}, data = null, ...args - }) { - const url = `${BASE_URL}${endpoint}`; - const headers = this._getAuthHeaders(); - - const config = { - method, - url, - headers, - params: formatQueryParams(params), - timeout: 30000, - ...args, - }; - - if (data) { - config.data = data; - } - - const response = await axios(this, config); - return response.data || response; - }, - - async _makeRequestWithRetry(config, retries = RETRY_CONFIG.MAX_RETRIES) { - try { - return await this._makeRequest(config); - } catch (error) { - if (retries > 0 && error.response?.status === HTTP_STATUS.TOO_MANY_REQUESTS) { - const delay = Math.min( - RETRY_CONFIG.INITIAL_DELAY * (RETRY_CONFIG.MAX_RETRIES - retries + 1), - RETRY_CONFIG.MAX_DELAY, - ); - await sleep(delay); - return this._makeRequestWithRetry(config, retries - 1); - } - throw error; - } + state: { + type: "string", + label: "State", + description: "Which reviews to retrieve according to their review state. Default is Published.", + options: [ + "published", + "unpublished", + ], + optional: true, }, - - // Business Unit methods - async getBusinessUnit(businessUnitId) { - if (!validateBusinessUnitId(businessUnitId)) { - throw new Error("Invalid business unit ID"); - } - - const endpoint = buildUrl(ENDPOINTS.BUSINESS_UNIT_BY_ID, { - businessUnitId, - }); - const response = await this._makeRequest({ - endpoint, - }); - return parseBusinessUnit(response); + locale: { + type: "string", + label: "Locale", + description: "The language in which the attributes, if any, are returned", + optional: true, }, - + }, + methods: { async searchBusinessUnits({ - query = "", limit = DEFAULT_LIMIT, offset = 0, + query = "a", page = 1, } = {}) { - const response = await this._makeRequest({ + const response = await makeRequest(this, this, { endpoint: ENDPOINTS.BUSINESS_UNITS, params: { query, - limit, - offset, + page, }, }); - return response.businessUnits?.map(parseBusinessUnit) || []; + return response.businessUnits || []; }, - // Public Review methods (no auth required for basic info) - async getPublicServiceReviews({ - businessUnitId, - stars = null, - sortBy = SORT_OPTIONS.CREATED_AT_DESC, - limit = DEFAULT_LIMIT, - offset = 0, - tags = [], - language = null, - }) { - if (!validateBusinessUnitId(businessUnitId)) { - throw new Error("Invalid business unit ID"); - } - - const endpoint = buildUrl(ENDPOINTS.PUBLIC_REVIEWS, { + // Shared method for fetching service reviews - used by both actions and sources + async fetchServiceReviews($, params = {}) { + const { businessUnitId, - }); - const params = { - stars, - orderBy: sortBy, - perPage: limit, - page: Math.floor(offset / limit) + 1, - language, - }; + page = 1, + perPage = 20, + orderBy = "createdat.desc", + ignoreTagValueCase = false, + ...filters + } = params; - if (tags.length > 0) { - params.tags = tags.join(","); + // Validate required parameters + if (!businessUnitId) { + throw new Error("Business Unit ID is required"); } - - const response = await this._makeRequestWithRetry({ - endpoint, - params, - }); - - return { - reviews: response.reviews?.map(parseReview) || [], - pagination: { - total: response.pagination?.total || 0, - page: response.pagination?.page || 1, - perPage: response.pagination?.perPage || limit, - hasMore: response.pagination?.hasMore || false, - }, - }; - }, - - async getPublicServiceReviewById({ - businessUnitId, reviewId, - }) { if (!validateBusinessUnitId(businessUnitId)) { - throw new Error("Invalid business unit ID"); - } - if (!validateReviewId(reviewId)) { - throw new Error("Invalid review ID"); + throw new Error("Invalid business unit ID format"); } - const endpoint = buildUrl(ENDPOINTS.PUBLIC_REVIEW_BY_ID, { + // Build the endpoint URL + const endpoint = buildUrl(ENDPOINTS.SERVICE_REVIEWS, { businessUnitId, - reviewId, }); - const response = await this._makeRequest({ - endpoint, - }); - return parseReview(response); - }, - - // Private helper for fetching reviews - async _getReviews({ - endpoint, - businessUnitId, - stars = null, - sortBy = SORT_OPTIONS.CREATED_AT_DESC, - limit = DEFAULT_LIMIT, - offset = 0, - includeReportedReviews = false, - tags = [], - language = null, - }) { - if (businessUnitId && !validateBusinessUnitId(businessUnitId)) { - throw new Error("Invalid business unit ID"); - } - const params = { - stars, - orderBy: sortBy, - perPage: limit, - page: Math.floor(offset / limit) + 1, - includeReportedReviews, - language, + // Prepare query parameters + const queryParams = { + ...filters, + page, + perPage, + orderBy, + ignoreTagValueCase, }; - if (tags.length > 0) { - params.tags = tags.join(","); - } - - const response = await this._makeRequestWithRetry({ - endpoint: endpoint || ENDPOINTS.PRIVATE_SERVICE_REVIEWS, - params, - }); + // Make the API request + const response = await makeRequest($, this, { + endpoint, + params: queryParams, + }); + + // Handle the correct response structure (reviews array) + const reviews = response.reviews?.map(parseServiceReview) || []; + const pagination = { + total: typeof response.total === "number" + ? response.total : + null, + // Preserve the page and perPage we requested + page: queryParams.page, + perPage: queryParams.perPage, + // Determine if there’s a next page by checking for a "next" link + hasMore: Array.isArray(response.links) + ? response.links.some((l) => l?.rel === "next-page") + : false, + }; return { - reviews: response.reviews?.map(parseReview) || [], - pagination: { - total: response.pagination?.total || 0, - page: response.pagination?.page || 1, - perPage: response.pagination?.perPage || limit, - hasMore: response.pagination?.hasMore || false, + reviews, + pagination, + metadata: { + businessUnitId, + filters: queryParams, + requestTime: new Date().toISOString(), }, }; }, - // Private Service Review methods - async getServiceReviews(options = {}) { - const endpoint = buildUrl(ENDPOINTS.PUBLIC_REVIEWS, { - businessUnitId: options.businessUnitId, - }); - return this._getReviews({ - endpoint, - ...options, - }); - }, - - async getServiceReviewById({ - businessUnitId, reviewId, - }) { - if (!validateBusinessUnitId(businessUnitId)) { - throw new Error("Invalid business unit ID"); - } - if (!validateReviewId(reviewId)) { - throw new Error("Invalid review ID"); - } - - const endpoint = buildUrl(ENDPOINTS.PRIVATE_SERVICE_REVIEW_BY_ID, { + // Shared method for fetching product reviews - used by both actions and sources + async fetchProductReviews($, params = {}) { + const { businessUnitId, - reviewId, - }); - const response = await this._makeRequest({ - endpoint, - }); - return parseReview(response); - }, + page, + perPage, + sku, + language, + state, + locale, + } = params; - async replyToServiceReview({ - businessUnitId, reviewId, message, - }) { - if (!validateBusinessUnitId(businessUnitId)) { - throw new Error("Invalid business unit ID"); - } - if (!validateReviewId(reviewId)) { - throw new Error("Invalid review ID"); - } - if (!message || typeof message !== "string") { - throw new Error("Reply message is required"); + // Validate required parameters + if (!businessUnitId) { + throw new Error("Business Unit ID is required"); } - - // Sanitize and validate message length (Trustpilot limit is 5000 characters) - const sanitizedMessage = sanitizeInput(message, 5000); - if (sanitizedMessage.length === 0) { - throw new Error("Reply message cannot be empty after sanitization"); + if (!validateBusinessUnitId(businessUnitId)) { + throw new Error("Invalid business unit ID format"); } - const endpoint = buildUrl(ENDPOINTS.REPLY_TO_SERVICE_REVIEW, { + // Build the endpoint URL + const endpoint = buildUrl(ENDPOINTS.PRIVATE_PRODUCT_REVIEWS, { businessUnitId, - reviewId, - }); - const response = await this._makeRequest({ - endpoint, - method: "POST", - data: { - message: sanitizedMessage, - }, }); - return response; - }, - - // Product Review methods - async getProductReviews(options = {}) { - const endpoint = buildUrl(ENDPOINTS.PUBLIC_PRODUCT_REVIEWS, { - businessUnitId: options.businessUnitId, - }); - return this._getReviews({ - endpoint, - ...options, - }); - }, - async getProductReviewById({ reviewId }) { - if (!validateReviewId(reviewId)) { - throw new Error("Invalid review ID"); - } - - const endpoint = buildUrl(ENDPOINTS.PRIVATE_PRODUCT_REVIEW_BY_ID, { - reviewId, - }); - const response = await this._makeRequest({ - endpoint, - }); - return parseReview(response); - }, - - async replyToProductReview({ - reviewId, message, - }) { - if (!validateReviewId(reviewId)) { - throw new Error("Invalid review ID"); - } - if (!message || typeof message !== "string") { - throw new Error("Reply message is required"); - } - - // Sanitize and validate message length (Trustpilot limit is 5000 characters) - const sanitizedMessage = sanitizeInput(message, 5000); - if (sanitizedMessage.length === 0) { - throw new Error("Reply message cannot be empty after sanitization"); - } + // Prepare query parameters + const queryParams = { + sku, + state, + locale, + perPage, + page, + language, + }; - const endpoint = buildUrl(ENDPOINTS.REPLY_TO_PRODUCT_REVIEW, { - reviewId, - }); - const response = await this._makeRequest({ + // Make the API request + const response = await makeRequest($, this, { endpoint, - method: "POST", - data: { - message: sanitizedMessage, - }, + params: queryParams, }); - return response; - }, - // Conversation methods - async getConversations({ - limit = DEFAULT_LIMIT, - offset = 0, - sortBy = SORT_OPTIONS.CREATED_AT_DESC, - businessUnitId = null, - } = {}) { - const params = { - perPage: limit, - page: Math.floor(offset / limit) + 1, - orderBy: sortBy, + // Handle the correct response structure (productReviews, not reviews) + const reviews = response.productReviews?.map(parseProductReview) || []; + const pagination = { + total: response.total || 0, + page: queryParams.page || 1, + perPage: queryParams.perPage || 20, + hasMore: response.links?.some((l) => l.rel === "next") || false, }; - if (businessUnitId) { - params.businessUnitId = businessUnitId; - } - - const response = await this._makeRequestWithRetry({ - endpoint: ENDPOINTS.CONVERSATIONS, - params, - }); - return { - conversations: response.conversations || [], - pagination: { - total: response.pagination?.total || 0, - page: response.pagination?.page || 1, - perPage: response.pagination?.perPage || limit, - hasMore: response.pagination?.hasMore || false, + reviews, + pagination, + metadata: { + businessUnitId, + filters: queryParams, + requestTime: new Date().toISOString(), }, }; }, - - async getConversationById({ conversationId }) { - if (!conversationId) { - throw new Error("Invalid conversation ID"); - } - - const endpoint = buildUrl(ENDPOINTS.CONVERSATION_BY_ID, { - conversationId, - }); - const response = await this._makeRequest({ - endpoint, - }); - return response; - }, - - async replyToConversation({ - conversationId, message, - }) { - if (!conversationId) { - throw new Error("Invalid conversation ID"); - } - if (!message || typeof message !== "string") { - throw new Error("Reply message is required"); - } - - // Sanitize and validate message length (Trustpilot limit is 5000 characters) - const sanitizedMessage = sanitizeInput(message, 5000); - if (sanitizedMessage.length === 0) { - throw new Error("Reply message cannot be empty after sanitization"); - } - - const endpoint = buildUrl(ENDPOINTS.REPLY_TO_CONVERSATION, { - conversationId, - }); - const response = await this._makeRequest({ - endpoint, - method: "POST", - data: { - message: sanitizedMessage, - }, - }); - return response; - }, - - // Webhook methods - async createWebhook({ - url, events = [], businessUnitId = null, - }) { - if (!url) { - throw new Error("Webhook URL is required"); - } - if (!Array.isArray(events) || events.length === 0) { - throw new Error("At least one event must be specified"); - } - - const data = { - url, - events, - }; - - if (businessUnitId) { - data.businessUnitId = businessUnitId; - } - - const response = await this._makeRequest({ - endpoint: ENDPOINTS.WEBHOOKS, - method: "POST", - data, - }); - return response; - }, - - async deleteWebhook(webhookId) { - if (!webhookId) { - throw new Error("Webhook ID is required"); - } - - const endpoint = buildUrl(ENDPOINTS.WEBHOOK_BY_ID, { - webhookId, - }); - await this._makeRequest({ - endpoint, - method: "DELETE", - }); - }, - - async listWebhooks() { - const response = await this._makeRequest({ - endpoint: ENDPOINTS.WEBHOOKS, - }); - return response.webhooks || []; - }, - - // Utility methods - parseWebhookPayload(payload) { - return parseWebhookPayload(payload); - }, - - validateWebhookSignature(payload, signature, secret) { - // Trustpilot uses HMAC-SHA256 for webhook signature validation - // The signature is sent in the x-trustpilot-signature header - if (!signature || !secret) { - return false; - } - - const payloadString = typeof payload === "string" - ? payload - : JSON.stringify(payload); - - const expectedSignature = crypto - .createHmac("sha256", secret) - .update(payloadString) - .digest("hex"); - - // Constant time comparison to prevent timing attacks - return crypto.timingSafeEqual( - Buffer.from(signature), - Buffer.from(expectedSignature), - ); - }, - }, }; From e838ebe82c88725ba6a656ee3ba962fe45d4973c Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:33:10 -0700 Subject: [PATCH 30/52] Adding app scaffolding for peekalink --- components/peekalink/package.json | 15 +++++++++++++++ components/peekalink/peekalink.app.mjs | 11 +++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/peekalink/package.json create mode 100644 components/peekalink/peekalink.app.mjs diff --git a/components/peekalink/package.json b/components/peekalink/package.json new file mode 100644 index 0000000000000..9dae781e34614 --- /dev/null +++ b/components/peekalink/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/peekalink", + "version": "0.0.1", + "description": "Pipedream Peekalink Components", + "main": "peekalink.app.mjs", + "keywords": [ + "pipedream", + "peekalink" + ], + "homepage": "https://pipedream.com/apps/peekalink", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/components/peekalink/peekalink.app.mjs b/components/peekalink/peekalink.app.mjs new file mode 100644 index 0000000000000..4da517b7f0204 --- /dev/null +++ b/components/peekalink/peekalink.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "peekalink", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1fa2beb8c5996..8e80001d314e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10481,6 +10481,9 @@ importers: specifier: ^2.0.0 version: 2.0.0 + components/peekalink: + specifiers: {} + components/peerdom: dependencies: '@pipedream/platform': From 85bd98a6f5000dfda5be4e5413aa4b9de5ebc4b3 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 17 Sep 2025 18:05:43 -0300 Subject: [PATCH 31/52] 18314 twilio (#18350) * Update Twilio component versions and dependencies - Update Twilio Send Message action adding detailed description for 'from' prop and refactoring phone number validation logic. - Incremented action versions for several Twilio actions. * pnpm update --- components/peekalink/peekalink.app.mjs | 2 +- .../check-verification-token.mjs | 2 +- .../create-verification-service.mjs | 2 +- .../twilio/actions/delete-call/delete-call.mjs | 2 +- .../twilio/actions/delete-message/delete-message.mjs | 2 +- .../download-recording-media.mjs | 2 +- components/twilio/actions/get-call/get-call.mjs | 2 +- .../twilio/actions/get-message/get-message.mjs | 2 +- .../actions/get-transcripts/get-transcripts.mjs | 2 +- components/twilio/actions/list-calls/list-calls.mjs | 2 +- .../list-message-media/list-message-media.mjs | 2 +- .../twilio/actions/list-messages/list-messages.mjs | 2 +- .../actions/list-transcripts/list-transcripts.mjs | 2 +- .../actions/make-phone-call/make-phone-call.mjs | 2 +- .../phone-number-lookup/phone-number-lookup.mjs | 2 +- .../twilio/actions/send-message/send-message.mjs | 12 ++++-------- .../send-sms-verification/send-sms-verification.mjs | 2 +- components/twilio/package.json | 4 ++-- components/twilio/sources/new-call/new-call.mjs | 2 +- .../sources/new-incoming-sms/new-incoming-sms.mjs | 2 +- .../sources/new-phone-number/new-phone-number.mjs | 2 +- .../twilio/sources/new-recording/new-recording.mjs | 2 +- .../new-transcript-created.mjs | 2 +- pnpm-lock.yaml | 4 ++-- 24 files changed, 29 insertions(+), 33 deletions(-) diff --git a/components/peekalink/peekalink.app.mjs b/components/peekalink/peekalink.app.mjs index 4da517b7f0204..4f21d0e8d688f 100644 --- a/components/peekalink/peekalink.app.mjs +++ b/components/peekalink/peekalink.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/twilio/actions/check-verification-token/check-verification-token.mjs b/components/twilio/actions/check-verification-token/check-verification-token.mjs index 50b5c7d04f635..d3df840df9ab5 100644 --- a/components/twilio/actions/check-verification-token/check-verification-token.mjs +++ b/components/twilio/actions/check-verification-token/check-verification-token.mjs @@ -6,7 +6,7 @@ export default { name: "Check Verification Token", description: "Check if user-provided token is correct. [See the documentation](https://www.twilio.com/docs/verify/api)", type: "action", - version: "0.0.3", + version: "0.0.4", props: { app, serviceSid: { diff --git a/components/twilio/actions/create-verification-service/create-verification-service.mjs b/components/twilio/actions/create-verification-service/create-verification-service.mjs index a21260daa8d01..c662da6184440 100644 --- a/components/twilio/actions/create-verification-service/create-verification-service.mjs +++ b/components/twilio/actions/create-verification-service/create-verification-service.mjs @@ -5,7 +5,7 @@ export default { name: "Create Verification Service", description: "Create a verification service for sending SMS verifications. [See the documentation](https://www.twilio.com/docs/verify/api/service#create-a-verification-service)", type: "action", - version: "0.0.2", + version: "0.0.3", props: { twilio, friendlyName: { diff --git a/components/twilio/actions/delete-call/delete-call.mjs b/components/twilio/actions/delete-call/delete-call.mjs index b1c2253b0de8c..5151dea4e3143 100644 --- a/components/twilio/actions/delete-call/delete-call.mjs +++ b/components/twilio/actions/delete-call/delete-call.mjs @@ -4,7 +4,7 @@ export default { key: "twilio-delete-call", name: "Delete Call", description: "Remove a call record from your account. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#delete-a-call-resource)", - version: "0.1.4", + version: "0.1.5", type: "action", props: { twilio, diff --git a/components/twilio/actions/delete-message/delete-message.mjs b/components/twilio/actions/delete-message/delete-message.mjs index 75d98ecbb7286..7c68e6f98b588 100644 --- a/components/twilio/actions/delete-message/delete-message.mjs +++ b/components/twilio/actions/delete-message/delete-message.mjs @@ -4,7 +4,7 @@ export default { key: "twilio-delete-message", name: "Delete Message", description: "Delete a message record from your account. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#delete-a-message-resource)", - version: "0.1.4", + version: "0.1.5", type: "action", props: { twilio, diff --git a/components/twilio/actions/download-recording-media/download-recording-media.mjs b/components/twilio/actions/download-recording-media/download-recording-media.mjs index e530f22464cc0..5bfff1f21a833 100644 --- a/components/twilio/actions/download-recording-media/download-recording-media.mjs +++ b/components/twilio/actions/download-recording-media/download-recording-media.mjs @@ -8,7 +8,7 @@ export default { key: "twilio-download-recording-media", name: "Download Recording Media", description: "Download a recording media file. [See the documentation](https://www.twilio.com/docs/voice/api/recording#fetch-a-recording-media-file)", - version: "0.1.7", + version: "0.1.8", type: "action", props: { twilio, diff --git a/components/twilio/actions/get-call/get-call.mjs b/components/twilio/actions/get-call/get-call.mjs index a5c9c49f7eb8d..3cfde0021dfd8 100644 --- a/components/twilio/actions/get-call/get-call.mjs +++ b/components/twilio/actions/get-call/get-call.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-get-call", name: "Get Call", description: "Return call resource of an individual call. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#fetch-a-call-resource)", - version: "0.1.4", + version: "0.1.5", type: "action", props: { twilio, diff --git a/components/twilio/actions/get-message/get-message.mjs b/components/twilio/actions/get-message/get-message.mjs index f5f65eed531f2..0f123a9d56bb8 100644 --- a/components/twilio/actions/get-message/get-message.mjs +++ b/components/twilio/actions/get-message/get-message.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-get-message", name: "Get Message", description: "Return details of a message. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#fetch-a-message-resource)", - version: "0.1.4", + version: "0.1.5", type: "action", props: { twilio, diff --git a/components/twilio/actions/get-transcripts/get-transcripts.mjs b/components/twilio/actions/get-transcripts/get-transcripts.mjs index 8fa68dcc6061d..992e6406b5470 100644 --- a/components/twilio/actions/get-transcripts/get-transcripts.mjs +++ b/components/twilio/actions/get-transcripts/get-transcripts.mjs @@ -4,7 +4,7 @@ export default { key: "twilio-get-transcripts", name: "Get Transcripts", description: "Retrieves full transcripts for the specified transcript SIDs. [See the documentation](https://www.twilio.com/docs/voice/intelligence/api/transcript-sentence-resource#get-transcript-sentences)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { twilio, diff --git a/components/twilio/actions/list-calls/list-calls.mjs b/components/twilio/actions/list-calls/list-calls.mjs index 66276d614c32d..1ae0276b2e031 100644 --- a/components/twilio/actions/list-calls/list-calls.mjs +++ b/components/twilio/actions/list-calls/list-calls.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-list-calls", name: "List Calls", description: "Return a list of calls associated with your account. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#read-multiple-call-resources)", - version: "0.1.4", + version: "0.1.5", type: "action", props: { twilio, diff --git a/components/twilio/actions/list-message-media/list-message-media.mjs b/components/twilio/actions/list-message-media/list-message-media.mjs index dddef1db1ec6e..a2c0941053d21 100644 --- a/components/twilio/actions/list-message-media/list-message-media.mjs +++ b/components/twilio/actions/list-message-media/list-message-media.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-list-message-media", name: "List Message Media", description: "Return a list of media associated with your message. [See the documentation](https://www.twilio.com/docs/sms/api/media-resource#read-multiple-media-resources)", - version: "0.1.4", + version: "0.1.5", type: "action", props: { twilio, diff --git a/components/twilio/actions/list-messages/list-messages.mjs b/components/twilio/actions/list-messages/list-messages.mjs index 78da1e45289e5..c99c06a3aa919 100644 --- a/components/twilio/actions/list-messages/list-messages.mjs +++ b/components/twilio/actions/list-messages/list-messages.mjs @@ -6,7 +6,7 @@ export default { key: "twilio-list-messages", name: "List Messages", description: "Return a list of messages associated with your account. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#read-multiple-message-resources)", - version: "0.1.5", + version: "0.1.6", type: "action", props: { twilio, diff --git a/components/twilio/actions/list-transcripts/list-transcripts.mjs b/components/twilio/actions/list-transcripts/list-transcripts.mjs index 012970cf1740c..89e6c5a4320e1 100644 --- a/components/twilio/actions/list-transcripts/list-transcripts.mjs +++ b/components/twilio/actions/list-transcripts/list-transcripts.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-list-transcripts", name: "List Transcripts", description: "Return a list of transcripts. [See the documentation](https://www.twilio.com/docs/voice/intelligence/api/transcript-resource#fetch-multiple-transcripts)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { twilio, diff --git a/components/twilio/actions/make-phone-call/make-phone-call.mjs b/components/twilio/actions/make-phone-call/make-phone-call.mjs index 5ba8a59c2bb12..771ff28182f59 100644 --- a/components/twilio/actions/make-phone-call/make-phone-call.mjs +++ b/components/twilio/actions/make-phone-call/make-phone-call.mjs @@ -6,7 +6,7 @@ export default { key: "twilio-make-phone-call", name: "Make a Phone Call", description: "Make a phone call passing text, a URL, or an application that Twilio will use to handle the call. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#create-a-call-resource)", - version: "0.1.5", + version: "0.1.6", type: "action", props: { twilio, diff --git a/components/twilio/actions/phone-number-lookup/phone-number-lookup.mjs b/components/twilio/actions/phone-number-lookup/phone-number-lookup.mjs index 6867ea35e5b7b..e2f4d4ab9a830 100644 --- a/components/twilio/actions/phone-number-lookup/phone-number-lookup.mjs +++ b/components/twilio/actions/phone-number-lookup/phone-number-lookup.mjs @@ -5,7 +5,7 @@ export default { name: "Phone Number Lookup", description: "Lookup information about a phone number. [See the documentation](https://www.twilio.com/docs/lookup/v2-api/line-type-intelligence) for more information", type: "action", - version: "0.0.2", + version: "0.0.3", props: { app, sid: { diff --git a/components/twilio/actions/send-message/send-message.mjs b/components/twilio/actions/send-message/send-message.mjs index 57c495861d802..520f8d10733ac 100644 --- a/components/twilio/actions/send-message/send-message.mjs +++ b/components/twilio/actions/send-message/send-message.mjs @@ -1,13 +1,13 @@ import { phone } from "phone"; -import twilio from "../../twilio.app.mjs"; import { messageToString } from "../../common/utils.mjs"; +import twilio from "../../twilio.app.mjs"; export default { key: "twilio-send-message", name: "Send Message", description: "Send an SMS text with optional media files. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#create-a-message-resource)", type: "action", - version: "0.0.2", + version: "0.0.3", props: { twilio, from: { @@ -15,6 +15,7 @@ export default { twilio, "from", ], + description: "The sender's Twilio phone number (in [E.164](https://en.wikipedia.org/wiki/E.164) format), [alphanumeric sender ID](https://www.twilio.com/docs/sms/quickstart), [Wireless SIM](https://www.twilio.com/docs/iot/wireless/programmable-wireless-send-machine-machine-sms-commands), [short code](https://www.twilio.com/en-us/messaging/channels/sms/short-codes), or [channel address](https://www.twilio.com/docs/messaging/channels) (e.g., `whatsapp:+15554449999`). The value of the `from` parameter must be a sender that is hosted within Twilio and belongs to the Account creating the Message. If you are using `messaging_service_sid`, this parameter can be empty (Twilio assigns a from value `from` the Messaging Service's Sender Pool) or you can provide a specific sender from your Sender Pool", }, to: { propDefinition: [ @@ -45,14 +46,9 @@ export default { throw new Error(`Phone number ${this.to} could not be parsed as a valid number.`); } - const fromParsed = phone(this.from); - if (!fromParsed || !fromParsed.phoneNumber) { - throw new Error(`Phone number ${this.from} could not be parsed as a valid number.`); - } - const data = { to: toParsed.phoneNumber, - from: fromParsed.phoneNumber, + from: this.from, body: this.body, mediaUrl: this.mediaUrl, }; diff --git a/components/twilio/actions/send-sms-verification/send-sms-verification.mjs b/components/twilio/actions/send-sms-verification/send-sms-verification.mjs index 465c23a9af42c..981bd879849e4 100644 --- a/components/twilio/actions/send-sms-verification/send-sms-verification.mjs +++ b/components/twilio/actions/send-sms-verification/send-sms-verification.mjs @@ -5,7 +5,7 @@ export default { name: "Send SMS Verification", description: "Send an SMS verification to a phone number. [See the documentation](https://www.twilio.com/docs/verify/api)", type: "action", - version: "0.0.3", + version: "0.0.4", props: { app, serviceSid: { diff --git a/components/twilio/package.json b/components/twilio/package.json index 2e0d61e0176eb..d1ee444a020c0 100644 --- a/components/twilio/package.json +++ b/components/twilio/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/twilio", - "version": "0.6.1", + "version": "0.6.2", "description": "Pipedream Twilio Components", "main": "twilio.app.mjs", "keywords": [ @@ -10,7 +10,7 @@ "homepage": "https://pipedream.com/apps/twilio", "author": "Pipedream (https://pipedream.com/)", "dependencies": { - "@pipedream/platform": "^3.0.0", + "@pipedream/platform": "^3.1.0", "got": "^13.0.0", "phone": "^3.1.49", "stream": "^0.0.3", diff --git a/components/twilio/sources/new-call/new-call.mjs b/components/twilio/sources/new-call/new-call.mjs index 2036834890d80..70d4e80da8257 100644 --- a/components/twilio/sources/new-call/new-call.mjs +++ b/components/twilio/sources/new-call/new-call.mjs @@ -6,7 +6,7 @@ export default { key: "twilio-new-call", name: "New Call (Instant)", description: "Emit new event each time a call to the phone number is completed. Configures a webhook in Twilio, tied to a phone number.", - version: "0.1.5", + version: "0.1.6", type: "source", dedupe: "unique", methods: { diff --git a/components/twilio/sources/new-incoming-sms/new-incoming-sms.mjs b/components/twilio/sources/new-incoming-sms/new-incoming-sms.mjs index 8385831a82aae..8802ef3b0de7c 100644 --- a/components/twilio/sources/new-incoming-sms/new-incoming-sms.mjs +++ b/components/twilio/sources/new-incoming-sms/new-incoming-sms.mjs @@ -9,7 +9,7 @@ export default { key: "twilio-new-incoming-sms", name: "New Incoming SMS (Instant)", description: "Emit new event every time an SMS is sent to the phone number set. Configures a webhook in Twilio, tied to an incoming phone number.", - version: "0.1.5", + version: "0.1.6", type: "source", dedupe: "unique", props: { diff --git a/components/twilio/sources/new-phone-number/new-phone-number.mjs b/components/twilio/sources/new-phone-number/new-phone-number.mjs index 84354bf6a8406..4c0dc13df7dc8 100644 --- a/components/twilio/sources/new-phone-number/new-phone-number.mjs +++ b/components/twilio/sources/new-phone-number/new-phone-number.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-new-phone-number", name: "New Phone Number", description: "Emit new event when you add a new phone number to your account", - version: "0.1.6", + version: "0.1.7", type: "source", dedupe: "unique", methods: { diff --git a/components/twilio/sources/new-recording/new-recording.mjs b/components/twilio/sources/new-recording/new-recording.mjs index 32d00fae95610..c7704977d4a0a 100644 --- a/components/twilio/sources/new-recording/new-recording.mjs +++ b/components/twilio/sources/new-recording/new-recording.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-new-recording", name: "New Recording", description: "Emit new event when a new call recording is created", - version: "0.1.6", + version: "0.1.7", type: "source", dedupe: "unique", methods: { diff --git a/components/twilio/sources/new-transcript-created/new-transcript-created.mjs b/components/twilio/sources/new-transcript-created/new-transcript-created.mjs index 66a7882d67c79..d8216f9c0d3fc 100644 --- a/components/twilio/sources/new-transcript-created/new-transcript-created.mjs +++ b/components/twilio/sources/new-transcript-created/new-transcript-created.mjs @@ -5,7 +5,7 @@ export default { key: "twilio-new-transcript-created", name: "New Transcript Created", description: "Emit new event when a new call transcript is created", - version: "0.0.2", + version: "0.0.3", type: "source", dedupe: "unique", props: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e80001d314e6..39864b0b88c10 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14880,8 +14880,8 @@ importers: components/twilio: dependencies: '@pipedream/platform': - specifier: ^3.0.0 - version: 3.0.3 + specifier: ^3.1.0 + version: 3.1.0 got: specifier: ^13.0.0 version: 13.0.0 From 2dfb941c37f27ce31a53db29b4af81b933b8ef34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Falc=C3=A3o?= <48412907+GTFalcao@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:01:49 -0300 Subject: [PATCH 32/52] Updating LinkedIn API version (#18399) --- components/linkedin/actions/create-comment/create-comment.mjs | 2 +- .../create-image-post-organization.mjs | 2 +- .../actions/create-image-post-user/create-image-post-user.mjs | 2 +- .../actions/create-like-on-share/create-like-on-share.mjs | 2 +- .../create-text-post-organization.mjs | 2 +- .../actions/create-text-post-user/create-text-post-user.mjs | 2 +- components/linkedin/actions/delete-post/delete-post.mjs | 2 +- .../linkedin/actions/fetch-ad-account/fetch-ad-account.mjs | 2 +- .../get-current-member-profile/get-current-member-profile.mjs | 2 +- .../linkedin/actions/get-member-profile/get-member-profile.mjs | 2 +- .../get-multiple-member-profiles.mjs | 2 +- .../actions/get-org-member-access/get-org-member-access.mjs | 2 +- .../get-organization-access-control.mjs | 2 +- .../get-organization-administrators.mjs | 2 +- .../get-profile-picture-fields/get-profile-picture-fields.mjs | 2 +- .../retrieve-comments-on-comments.mjs | 2 +- .../retrieve-comments-shares/retrieve-comments-shares.mjs | 2 +- .../actions/search-organization/search-organization.mjs | 2 +- components/linkedin/common/constants.mjs | 2 +- components/linkedin/package.json | 2 +- .../new-organization-post-created.mjs | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/components/linkedin/actions/create-comment/create-comment.mjs b/components/linkedin/actions/create-comment/create-comment.mjs index 8e0a5e08ad667..fe1d01e16ee05 100644 --- a/components/linkedin/actions/create-comment/create-comment.mjs +++ b/components/linkedin/actions/create-comment/create-comment.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-create-comment", name: "Create Comment", description: "Create a comment on a share or user generated content post. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/network-update-social-actions#create-comment)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/create-image-post-organization/create-image-post-organization.mjs b/components/linkedin/actions/create-image-post-organization/create-image-post-organization.mjs index d45b93b93d907..2b59a166ba368 100644 --- a/components/linkedin/actions/create-image-post-organization/create-image-post-organization.mjs +++ b/components/linkedin/actions/create-image-post-organization/create-image-post-organization.mjs @@ -7,7 +7,7 @@ export default { key: "linkedin-create-image-post-organization", name: "Create Image Post (Organization)", description: "Create an image post on LinkedIn. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/images-api?view=li-lms-2023-09&tabs=http#uploading-an-image)", - version: "1.0.3", + version: "1.0.4", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/create-image-post-user/create-image-post-user.mjs b/components/linkedin/actions/create-image-post-user/create-image-post-user.mjs index d301e8677ec5c..b6c3e09209e98 100644 --- a/components/linkedin/actions/create-image-post-user/create-image-post-user.mjs +++ b/components/linkedin/actions/create-image-post-user/create-image-post-user.mjs @@ -7,7 +7,7 @@ export default { key: "linkedin-create-image-post-user", name: "Create Image Post (User)", description: "Create an image post on LinkedIn. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/images-api?view=li-lms-2023-09&tabs=http#uploading-an-image)", - version: "1.0.3", + version: "1.0.4", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/create-like-on-share/create-like-on-share.mjs b/components/linkedin/actions/create-like-on-share/create-like-on-share.mjs index 1d3703cf38a01..4cd358f851b6d 100644 --- a/components/linkedin/actions/create-like-on-share/create-like-on-share.mjs +++ b/components/linkedin/actions/create-like-on-share/create-like-on-share.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-create-like-on-share", name: "Create Like On Share", description: "Creates a like on a share. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/network-update-social-actions#create-a-like-on-a-share)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/create-text-post-organization/create-text-post-organization.mjs b/components/linkedin/actions/create-text-post-organization/create-text-post-organization.mjs index 5c12a813aef5b..2b5130f6a4054 100644 --- a/components/linkedin/actions/create-text-post-organization/create-text-post-organization.mjs +++ b/components/linkedin/actions/create-text-post-organization/create-text-post-organization.mjs @@ -5,7 +5,7 @@ export default { key: "linkedin-create-text-post-organization", name: "Create a Simple Post (Organization)", description: "Create post on LinkedIn using text, URL or article. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/posts-api?view=li-lms-2022-11&tabs=http#create-organic-posts) for more information", - version: "0.0.8", + version: "0.0.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/create-text-post-user/create-text-post-user.mjs b/components/linkedin/actions/create-text-post-user/create-text-post-user.mjs index 2ba4e1553c58d..68547829d1f62 100644 --- a/components/linkedin/actions/create-text-post-user/create-text-post-user.mjs +++ b/components/linkedin/actions/create-text-post-user/create-text-post-user.mjs @@ -5,7 +5,7 @@ export default { key: "linkedin-create-text-post-user", name: "Create a Simple Post (User)", description: "Create post on LinkedIn using text, URL or article. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/posts-api?view=li-lms-2022-11&tabs=http#create-organic-posts) for more information", - version: "0.0.8", + version: "0.0.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/delete-post/delete-post.mjs b/components/linkedin/actions/delete-post/delete-post.mjs index 0c49ee6e9d0e8..7b064b9324e31 100644 --- a/components/linkedin/actions/delete-post/delete-post.mjs +++ b/components/linkedin/actions/delete-post/delete-post.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-delete-post", name: "Delete Post", description: "Removes a post from user's wall. [See the docs](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api?tabs=http#delete-shares) for more information", - version: "0.0.8", + version: "0.0.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/fetch-ad-account/fetch-ad-account.mjs b/components/linkedin/actions/fetch-ad-account/fetch-ad-account.mjs index ecb3443dff1d3..c66cc7735db1c 100644 --- a/components/linkedin/actions/fetch-ad-account/fetch-ad-account.mjs +++ b/components/linkedin/actions/fetch-ad-account/fetch-ad-account.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-fetch-ad-account", name: "Fetch Ad Account", description: "Fetches an individual adAccount given its id. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/ads/account-structure/create-and-manage-accounts#fetch-ad-account)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/get-current-member-profile/get-current-member-profile.mjs b/components/linkedin/actions/get-current-member-profile/get-current-member-profile.mjs index 28cc879fa2b26..d744284935ce4 100644 --- a/components/linkedin/actions/get-current-member-profile/get-current-member-profile.mjs +++ b/components/linkedin/actions/get-current-member-profile/get-current-member-profile.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-get-current-member-profile", name: "Get Current Member Profile", description: "Gets the profile of the current authenticated member. [See the docs here](https://docs.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api#retrieve-current-members-profile)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/get-member-profile/get-member-profile.mjs b/components/linkedin/actions/get-member-profile/get-member-profile.mjs index 82e39aa9981d1..31edfb86f96b7 100644 --- a/components/linkedin/actions/get-member-profile/get-member-profile.mjs +++ b/components/linkedin/actions/get-member-profile/get-member-profile.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-get-member-profile", name: "Get Member Profile", description: "Gets another member's profile, given its person id. [See the docs here](https://docs.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api#retrieve-other-members-profile)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/get-multiple-member-profiles/get-multiple-member-profiles.mjs b/components/linkedin/actions/get-multiple-member-profiles/get-multiple-member-profiles.mjs index 3a05d11d07bcd..39091a9b0ed80 100644 --- a/components/linkedin/actions/get-multiple-member-profiles/get-multiple-member-profiles.mjs +++ b/components/linkedin/actions/get-multiple-member-profiles/get-multiple-member-profiles.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-get-multiple-member-profiles", name: "Get Multiple Member Profiles", description: "Gets multiple member profiles at once. [See the docs here](https://docs.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api#retrieve-other-members-profile)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/get-org-member-access/get-org-member-access.mjs b/components/linkedin/actions/get-org-member-access/get-org-member-access.mjs index 8dfadaad838c9..4e2c8689f9ff4 100644 --- a/components/linkedin/actions/get-org-member-access/get-org-member-access.mjs +++ b/components/linkedin/actions/get-org-member-access/get-org-member-access.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-get-org-member-access", name: "Get Member's Organization Access Control Information", description: "Gets the organization access control information of the current authenticated member. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/organization-access-control-by-role?view=li-lms-2025-01&tabs=http#find-a-members-organization-access-control-information)", - version: "1.0.3", + version: "1.0.4", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/get-organization-access-control/get-organization-access-control.mjs b/components/linkedin/actions/get-organization-access-control/get-organization-access-control.mjs index 65a36163d23ce..b018d009f3be0 100644 --- a/components/linkedin/actions/get-organization-access-control/get-organization-access-control.mjs +++ b/components/linkedin/actions/get-organization-access-control/get-organization-access-control.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-get-organization-access-control", name: "Gets Organization Access Control", description: "Gets a selected organization's access control information. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/organization-access-control-by-role?view=li-lms-2025-01&tabs=http#find-organization-access-control)", - version: "0.2.2", + version: "0.2.3", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/get-organization-administrators/get-organization-administrators.mjs b/components/linkedin/actions/get-organization-administrators/get-organization-administrators.mjs index 1438e18676f25..827b4b5207259 100644 --- a/components/linkedin/actions/get-organization-administrators/get-organization-administrators.mjs +++ b/components/linkedin/actions/get-organization-administrators/get-organization-administrators.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-get-organization-administrators", name: "Get Organization Administrators", description: "Gets the administrator members of a selected organization. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/organization-access-control-by-role?view=li-lms-2025-01&tabs=http#find-organization-administrators)", - version: "0.3.2", + version: "0.3.3", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/get-profile-picture-fields/get-profile-picture-fields.mjs b/components/linkedin/actions/get-profile-picture-fields/get-profile-picture-fields.mjs index f4a04a1600741..9e16f7167d7d2 100644 --- a/components/linkedin/actions/get-profile-picture-fields/get-profile-picture-fields.mjs +++ b/components/linkedin/actions/get-profile-picture-fields/get-profile-picture-fields.mjs @@ -5,7 +5,7 @@ export default { key: "linkedin-get-profile-picture-fields", name: "Get Profile Picture Fields", description: "Gets the authenticated user's profile picture data including display image and metadata. [See the documentation](https://learn.microsoft.com/en-us/linkedin/shared/references/v2/profile/profile-picture)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/retrieve-comments-on-comments/retrieve-comments-on-comments.mjs b/components/linkedin/actions/retrieve-comments-on-comments/retrieve-comments-on-comments.mjs index 15486e79970e1..f23b9abde0998 100644 --- a/components/linkedin/actions/retrieve-comments-on-comments/retrieve-comments-on-comments.mjs +++ b/components/linkedin/actions/retrieve-comments-on-comments/retrieve-comments-on-comments.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-retrieve-comments-on-comments", name: "Retrieves Comments on Comments", description: "Retrieves comments on comments, given the parent comment urn. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/network-update-social-actions#retrieve-comments-on-comments)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/retrieve-comments-shares/retrieve-comments-shares.mjs b/components/linkedin/actions/retrieve-comments-shares/retrieve-comments-shares.mjs index c778142ab70cd..1918cd3f89013 100644 --- a/components/linkedin/actions/retrieve-comments-shares/retrieve-comments-shares.mjs +++ b/components/linkedin/actions/retrieve-comments-shares/retrieve-comments-shares.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-retrieve-comments-shares", name: "Retrieve Comments On Shares", description: "Retrieve comments on shares given the share urn. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/network-update-social-actions#retrieve-comments-on-shares)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/actions/search-organization/search-organization.mjs b/components/linkedin/actions/search-organization/search-organization.mjs index 94a5a284dc753..3353d87190e73 100644 --- a/components/linkedin/actions/search-organization/search-organization.mjs +++ b/components/linkedin/actions/search-organization/search-organization.mjs @@ -4,7 +4,7 @@ export default { key: "linkedin-search-organization", name: "Search Organization", description: "Searches for an organization by vanity name or email domain. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/organizations/organization-lookup-api)", - version: "0.1.8", + version: "0.1.9", type: "action", props: { linkedin, diff --git a/components/linkedin/common/constants.mjs b/components/linkedin/common/constants.mjs index c42ecc2765d43..f4a2a169120a7 100644 --- a/components/linkedin/common/constants.mjs +++ b/components/linkedin/common/constants.mjs @@ -1,6 +1,6 @@ const VERSION_PATH = "rest"; const BASE_URL = "https://api.linkedin.com/"; -const VERSION_HEADER = "202409"; +const VERSION_HEADER = "202509"; const VISIBILITIES = [ { diff --git a/components/linkedin/package.json b/components/linkedin/package.json index 06593438c15cf..5cf3c4f27b04f 100644 --- a/components/linkedin/package.json +++ b/components/linkedin/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/linkedin", - "version": "1.2.1", + "version": "1.2.2", "description": "Pipedream Linkedin Components", "main": "linkedin.app.mjs", "keywords": [ diff --git a/components/linkedin/sources/new-organization-post-created/new-organization-post-created.mjs b/components/linkedin/sources/new-organization-post-created/new-organization-post-created.mjs index 3f617b10d01e7..6b9b8c0223da7 100644 --- a/components/linkedin/sources/new-organization-post-created/new-organization-post-created.mjs +++ b/components/linkedin/sources/new-organization-post-created/new-organization-post-created.mjs @@ -9,7 +9,7 @@ export default { name: "New Organization Post Created", description: "Emit new event when a new post is created by the organization. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api?view=li-lms-2024-09&tabs=curl#find-posts-by-authors).", type: "source", - version: "0.0.3", + version: "0.0.4", dedupe: "unique", props: { ...common.props, From ffa140cf59345af77b9393cd1e1b1c0342aed022 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Wed, 17 Sep 2025 22:48:48 -0400 Subject: [PATCH 33/52] Merging pull request #18394 --- components/hubspot/actions/list-forms/list-forms.mjs | 10 +++++----- components/hubspot/package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/hubspot/actions/list-forms/list-forms.mjs b/components/hubspot/actions/list-forms/list-forms.mjs index fb6fc608dbbec..9c12efed27e14 100644 --- a/components/hubspot/actions/list-forms/list-forms.mjs +++ b/components/hubspot/actions/list-forms/list-forms.mjs @@ -5,7 +5,7 @@ export default { name: "List Forms", description: "Retrieves a list of forms. [See the documentation](https://developers.hubspot.com/docs/reference/api/marketing/forms#get-%2Fmarketing%2Fv3%2Fforms%2F)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { hubspot, @@ -24,7 +24,7 @@ export default { }, }, async run({ $ }) { - const results = []; + const forms = []; let hasMore, count = 0; @@ -43,7 +43,7 @@ export default { break; } for (const item of results) { - results.push(item); + forms.push(item); count++; if (count >= this.maxResults) { break; @@ -55,10 +55,10 @@ export default { $.export( "$summary", - `Found ${results.length} form${results.length === 1 + `Found ${forms.length} form${forms.length === 1 ? "" : "s"}`, ); - return results; + return forms; }, }; diff --git a/components/hubspot/package.json b/components/hubspot/package.json index 9d6372eacca78..a3982d87f377c 100644 --- a/components/hubspot/package.json +++ b/components/hubspot/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/hubspot", - "version": "1.7.5", + "version": "1.7.6", "description": "Pipedream Hubspot Components", "main": "hubspot.app.mjs", "keywords": [ From 1884cf01555ca9fae75fcb300bef8db246d10676 Mon Sep 17 00:00:00 2001 From: Jorge Cortes Date: Wed, 17 Sep 2025 22:21:13 -0500 Subject: [PATCH 34/52] Databricks API - Jobs action components (#18371) --- .../cancel-all-runs/cancel-all-runs.mjs | 52 ++++ .../actions/cancel-run/cancel-run.mjs | 37 +++ .../create-endpoint/create-endpoint.mjs | 2 +- .../actions/create-job/create-job.mjs | 237 ++++++++++++++++++ .../create-sql-warehouse.mjs | 2 +- .../delete-endpoint/delete-endpoint.mjs | 2 +- .../actions/delete-job/delete-job.mjs | 37 +++ .../actions/delete-run/delete-run.mjs | 30 +++ .../delete-sql-warehouse.mjs | 2 +- .../edit-sql-warehouse/edit-sql-warehouse.mjs | 2 +- .../actions/export-run/export-run.mjs | 48 ++++ .../actions/get-endpoint/get-endpoint.mjs | 2 +- .../get-job-permissions.mjs | 33 +++ .../databricks/actions/get-job/get-job.mjs | 35 +++ .../actions/get-run-output/get-run-output.mjs | 2 +- .../databricks/actions/get-run/get-run.mjs | 51 ++++ .../get-sql-warehouse-config.mjs | 2 +- .../get-sql-warehouse-permissions.mjs | 2 +- .../get-sql-warehouse/get-sql-warehouse.mjs | 2 +- .../actions/list-endpoints/list-endpoints.mjs | 2 +- .../actions/list-jobs/list-jobs.mjs | 59 +++++ .../actions/list-runs/list-runs.mjs | 2 +- .../list-sql-warehouses.mjs | 2 +- .../actions/repair-run/repair-run.mjs | 67 +++++ .../actions/reset-job/reset-job.mjs | 45 ++++ .../actions/run-job-now/run-job-now.mjs | 2 +- .../set-job-permissions.mjs | 54 ++++ .../set-sql-warehouse-config.mjs | 2 +- .../set-sql-warehouse-permissions.mjs | 2 +- .../start-sql-warehouse.mjs | 2 +- .../stop-sql-warehouse/stop-sql-warehouse.mjs | 2 +- .../actions/update-job/update-job.mjs | 62 +++++ components/databricks/common/constants.mjs | 14 ++ components/databricks/common/utils.mjs | 5 + components/databricks/databricks.app.mjs | 190 ++++++++++++-- components/databricks/package.json | 2 +- 36 files changed, 1060 insertions(+), 34 deletions(-) create mode 100644 components/databricks/actions/cancel-all-runs/cancel-all-runs.mjs create mode 100644 components/databricks/actions/cancel-run/cancel-run.mjs create mode 100644 components/databricks/actions/create-job/create-job.mjs create mode 100644 components/databricks/actions/delete-job/delete-job.mjs create mode 100644 components/databricks/actions/delete-run/delete-run.mjs create mode 100644 components/databricks/actions/export-run/export-run.mjs create mode 100644 components/databricks/actions/get-job-permissions/get-job-permissions.mjs create mode 100644 components/databricks/actions/get-job/get-job.mjs create mode 100644 components/databricks/actions/get-run/get-run.mjs create mode 100644 components/databricks/actions/list-jobs/list-jobs.mjs create mode 100644 components/databricks/actions/repair-run/repair-run.mjs create mode 100644 components/databricks/actions/reset-job/reset-job.mjs create mode 100644 components/databricks/actions/set-job-permissions/set-job-permissions.mjs create mode 100644 components/databricks/actions/update-job/update-job.mjs diff --git a/components/databricks/actions/cancel-all-runs/cancel-all-runs.mjs b/components/databricks/actions/cancel-all-runs/cancel-all-runs.mjs new file mode 100644 index 0000000000000..592740cc949fd --- /dev/null +++ b/components/databricks/actions/cancel-all-runs/cancel-all-runs.mjs @@ -0,0 +1,52 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-cancel-all-runs", + name: "Cancel All Runs", + description: "Cancel all active runs for a job. The runs are canceled asynchronously, so it doesn't prevent new runs from being started. [See the documentation](https://docs.databricks.com/api/workspace/jobs/cancelallruns)", + version: "0.0.1", + type: "action", + props: { + app, + // eslint-disable-next-line pipedream/props-label, pipedream/props-description + info: { + type: "alert", + alertType: "info", + content: "Either a **Job** or **All Queued Runs** must be provided.", + }, + jobId: { + optional: true, + propDefinition: [ + app, + "jobId", + ], + }, + allQueuedRuns: { + type: "boolean", + label: "All Queued Runs", + description: "Optional boolean parameter to cancel all queued runs. If no **Job ID** is provided, all queued runs in the workspace are canceled.", + optional: true, + }, + }, + async run({ $ }) { + const { + app, + jobId, + allQueuedRuns, + } = this; + + await app.cancelAllRuns({ + $, + data: { + job_id: jobId, + all_queued_runs: allQueuedRuns, + }, + }); + + $.export("$summary", "Successfully initiated cancellation of all runs"); + + return { + success: true, + }; + }, +}; diff --git a/components/databricks/actions/cancel-run/cancel-run.mjs b/components/databricks/actions/cancel-run/cancel-run.mjs new file mode 100644 index 0000000000000..9af5f0fd4c76a --- /dev/null +++ b/components/databricks/actions/cancel-run/cancel-run.mjs @@ -0,0 +1,37 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-cancel-run", + name: "Cancel Run", + description: "Cancel a job run. The run is canceled asynchronously, so it may still be running when this request completes. [See the documentation](https://docs.databricks.com/api/workspace/jobs/cancelrun)", + version: "0.0.1", + type: "action", + props: { + app, + runId: { + propDefinition: [ + app, + "runId", + ], + }, + }, + async run({ $ }) { + const { + app, + runId, + } = this; + + await app.cancelRun({ + $, + data: { + run_id: runId, + }, + }); + + $.export("$summary", `Successfully initiated cancellation of run with ID \`${runId}\`.`); + + return { + success: true, + }; + }, +}; diff --git a/components/databricks/actions/create-endpoint/create-endpoint.mjs b/components/databricks/actions/create-endpoint/create-endpoint.mjs index 3777a7ca32c5e..33bf7ad4d7a8f 100644 --- a/components/databricks/actions/create-endpoint/create-endpoint.mjs +++ b/components/databricks/actions/create-endpoint/create-endpoint.mjs @@ -5,7 +5,7 @@ export default { key: "databricks-create-endpoint", name: "Create Endpoint", description: "Create a new vector search endpoint. [See the documentation](https://docs.databricks.com/api/workspace/vectorsearchendpoints/createendpoint)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { databricks, diff --git a/components/databricks/actions/create-job/create-job.mjs b/components/databricks/actions/create-job/create-job.mjs new file mode 100644 index 0000000000000..209cf119ac164 --- /dev/null +++ b/components/databricks/actions/create-job/create-job.mjs @@ -0,0 +1,237 @@ +import app from "../../databricks.app.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + key: "databricks-create-job", + name: "Create Job", + description: "Create a job. [See the documentation](https://docs.databricks.com/api/workspace/jobs/create)", + version: "0.0.1", + type: "action", + props: { + app, + tasks: { + type: "string[]", + label: "Tasks", + description: `A list of task specifications to be executed by this job. JSON string format. [See the API documentation](https://docs.databricks.com/api/workspace/jobs/create#tasks) for task specification details. + +**Example:** +\`\`\`json +[ + { + "notebook_task": { + "notebook_path": "/Workspace/Users/sharky@databricks.com/weather_ingest" + }, + "task_key": "weather_ocean_data" + } +] +\`\`\` + `, + }, + name: { + type: "string", + label: "Job Name", + description: "An optional name for the job", + optional: true, + }, + tags: { + type: "object", + label: "Tags", + description: "A map of tags associated with the job. These are forwarded to the cluster as cluster tags for jobs clusters, and are subject to the same limitations as cluster tags", + optional: true, + }, + jobClusters: { + type: "string[]", + label: "Job Clusters", + description: `A list of job cluster specifications that can be shared and reused by tasks of this job. JSON string format. [See the API documentation](https://docs.databricks.com/api/workspace/jobs/create#job_clusters) for job cluster specification details. + +**Example:** +\`\`\`json +[ + { + "job_cluster_key": "auto_scaling_cluster", + "new_cluster": { + "autoscale": { + "max_workers": 16, + "min_workers": 2 + }, + "node_type_id": null, + "spark_conf": { + "spark.speculation": true + }, + "spark_version": "7.3.x-scala2.12" + } + } +] +\`\`\` + `, + optional: true, + }, + emailNotifications: { + type: "string", + label: "Email Notifications", + description: `An optional set of email addresses to notify when runs of this job begin, complete, or when the job is deleted. Specify as a JSON object with keys for each notification type. [See the API documentation](https://docs.databricks.com/api/workspace/jobs/create#email_notifications) for details on each field. + +**Example:** +\`\`\`json +{ + "on_start": ["user1@example.com"], + "on_success": ["user2@example.com"], + "on_failure": ["user3@example.com"], + "on_duration_warning_threshold_exceeded": ["user4@example.com"], + "on_streaming_backlog_exceeded": ["user5@example.com"] +} +\`\`\` +`, + optional: true, + }, + webhookNotifications: { + type: "string", + label: "Webhook Notifications", + description: `A collection of system notification IDs to notify when runs of this job begin, complete, or encounter specific events. Specify as a JSON object with keys for each notification type. Each key accepts an array of objects with an \`id\` property (system notification ID). A maximum of 3 destinations can be specified for each property. + +Supported keys: +- \`on_start\`: Notified when the run starts. +- \`on_success\`: Notified when the run completes successfully. +- \`on_failure\`: Notified when the run fails. +- \`on_duration_warning_threshold_exceeded\`: Notified when the run duration exceeds the specified threshold. +- \`on_streaming_backlog_exceeded\`: Notified when streaming backlog thresholds are exceeded. + +[See the API documentation](https://docs.databricks.com/api/workspace/jobs/create#webhook_notifications) for details. + +**Example:** +\`\`\`json +{ + "on_success": [ + { "id": "https://eoiqkb8yzox6u2n.m.pipedream.net" } + ], + "on_failure": [ + { "id": "https://another-webhook-url.com/notify" } + ] +} +\`\`\` +`, + optional: true, + }, + timeoutSeconds: { + type: "integer", + label: "Timeout Seconds", + description: "An optional timeout applied to each run of this job. The default behavior is to have no timeout", + optional: true, + }, + schedule: { + type: "string", + label: "Schedule", + description: `An optional periodic schedule for this job, specified as a JSON object. By default, the job only runs when triggered manually or via the API. The schedule object must include: + +- \`quartz_cron_expression\` (**required**): A Cron expression using Quartz syntax that defines when the job runs. [See Cron Trigger details](https://docs.databricks.com/api/workspace/jobs/create#schedule). +- \`timezone_id\` (**required**): A Java timezone ID (e.g., "Europe/London") that determines the timezone for the schedule. [See Java TimeZone details](https://docs.databricks.com/api/workspace/jobs/create#schedule). +- \`pause_status\` (optional): Set to \`"UNPAUSED"\` (default) or \`"PAUSED"\` to control whether the schedule is active. + +**Example:** +\`\`\`json +{ + "quartz_cron_expression": "0 0 12 * * ?", + "timezone_id": "Asia/Ho_Chi_Minh", + "pause_status": "UNPAUSED" +} +\`\`\` +`, + optional: true, + }, + maxConcurrentRuns: { + type: "integer", + label: "Max Concurrent Runs", + description: "An optional maximum allowed number of concurrent runs of the job. Defaults to 1", + optional: true, + }, + gitSource: { + type: "string", + label: "Git Source", + description: `An optional specification for a remote Git repository containing the source code used by tasks. Provide as a JSON string. + +This enables version-controlled source code for notebook, dbt, Python script, and SQL File tasks. If \`git_source\` is set, these tasks retrieve files from the remote repository by default (can be overridden per task by setting \`source\` to \`WORKSPACE\`). **Note:** dbt and SQL File tasks require \`git_source\` to be defined. [See the API documentation](https://docs.databricks.com/api/workspace/jobs/create#git_source) for more details. + +**Fields:** +- \`git_url\` (**required**): URL of the repository to be cloned (e.g., "https://github.com/databricks/databricks-cli"). +- \`git_provider\` (**required**): Service hosting the repository. One of: \`gitHub\`, \`bitbucketCloud\`, \`azureDevOpsServices\`, \`gitHubEnterprise\`, \`bitbucketServer\`, \`gitLab\`, \`gitLabEnterpriseEdition\`, \`awsCodeCommit\`. +- \`git_branch\`: Name of the branch to check out (cannot be used with \`git_tag\` or \`git_commit\`). +- \`git_tag\`: Name of the tag to check out (cannot be used with \`git_branch\` or \`git_commit\`). +- \`git_commit\`: Commit hash to check out (cannot be used with \`git_branch\` or \`git_tag\`). + +**Example:** +\`\`\`json +{ + "git_url": "https://github.com/databricks/databricks-cli", + "git_provider": "gitHub", + "git_branch": "main" +} +\`\`\` +`, + optional: true, + }, + accessControlList: { + type: "string[]", + label: "Access Control List", + description: `A list of permissions to set on the job, specified as a JSON array of objects. Each object can define permissions for a user, group, or service principal. + +Each object may include: +- \`user_name\`: Name of the user. +- \`group_name\`: Name of the group. +- \`service_principal_name\`: Application ID of a service principal. +- \`permission_level\`: Permission level. One of: \`CAN_MANAGE\`, \`IS_OWNER\`, \`CAN_MANAGE_RUN\`, \`CAN_VIEW\`. + +**Example:** +\`\`\`json +[ + { + "permission_level": "IS_OWNER", + "user_name": "jorge.c@turing.com" + }, + { + "permission_level": "CAN_VIEW", + "group_name": "data-scientists" + } +] +\`\`\` +[See the API documentation](https://docs.databricks.com/api/workspace/jobs/create#access_control_list) for more details.`, + optional: true, + }, + }, + async run({ $ }) { + const { + app, + tasks, + name, + tags, + jobClusters, + emailNotifications, + webhookNotifications, + timeoutSeconds, + schedule, + maxConcurrentRuns, + gitSource, + accessControlList, + } = this; + + const response = await app.createJob({ + $, + data: { + name, + tags, + tasks: utils.parseJsonInput(tasks), + job_clusters: utils.parseJsonInput(jobClusters), + email_notifications: utils.parseJsonInput(emailNotifications), + webhook_notifications: utils.parseJsonInput(webhookNotifications), + timeout_seconds: timeoutSeconds, + schedule: utils.parseJsonInput(schedule), + max_concurrent_runs: maxConcurrentRuns, + git_source: utils.parseJsonInput(gitSource), + access_control_list: utils.parseJsonInput(accessControlList), + }, + }); + + $.export("$summary", `Successfully created job with ID \`${response.job_id}\``); + + return response; + }, +}; diff --git a/components/databricks/actions/create-sql-warehouse/create-sql-warehouse.mjs b/components/databricks/actions/create-sql-warehouse/create-sql-warehouse.mjs index d0552107d1101..b953d78090e61 100644 --- a/components/databricks/actions/create-sql-warehouse/create-sql-warehouse.mjs +++ b/components/databricks/actions/create-sql-warehouse/create-sql-warehouse.mjs @@ -7,7 +7,7 @@ export default { key: "databricks-create-sql-warehouse", name: "Create SQL Warehouse", description: "Creates a new SQL Warehouse in Databricks. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/create)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/delete-endpoint/delete-endpoint.mjs b/components/databricks/actions/delete-endpoint/delete-endpoint.mjs index 5ad2a8c43304f..4a95bb6f13e2d 100644 --- a/components/databricks/actions/delete-endpoint/delete-endpoint.mjs +++ b/components/databricks/actions/delete-endpoint/delete-endpoint.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-delete-endpoint", name: "Delete Endpoint", description: "Delete a vector search endpoint. [See the documentation](https://docs.databricks.com/api/workspace/vectorsearchendpoints/deleteendpoint)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { databricks, diff --git a/components/databricks/actions/delete-job/delete-job.mjs b/components/databricks/actions/delete-job/delete-job.mjs new file mode 100644 index 0000000000000..a5e55b716421b --- /dev/null +++ b/components/databricks/actions/delete-job/delete-job.mjs @@ -0,0 +1,37 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-delete-job", + name: "Delete Job", + description: "Delete a job. Deleted jobs cannot be recovered. [See the documentation](https://docs.databricks.com/api/workspace/jobs/delete)", + version: "0.0.1", + type: "action", + props: { + app, + jobId: { + propDefinition: [ + app, + "jobId", + ], + }, + }, + async run({ $ }) { + const { + app, + jobId, + } = this; + + await app.deleteJob({ + $, + data: { + job_id: jobId, + }, + }); + + $.export("$summary", `Successfully deleted job with ID \`${jobId}\`.`); + + return { + success: true, + }; + }, +}; diff --git a/components/databricks/actions/delete-run/delete-run.mjs b/components/databricks/actions/delete-run/delete-run.mjs new file mode 100644 index 0000000000000..2fbda0185965d --- /dev/null +++ b/components/databricks/actions/delete-run/delete-run.mjs @@ -0,0 +1,30 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-delete-run", + name: "Delete Run", + description: "Delete a non-active run. Returns an error if the run is active. [See the documentation](https://docs.databricks.com/api/workspace/jobs/deleterun)", + version: "0.0.1", + type: "action", + props: { + app, + runId: { + propDefinition: [ + app, + "runId", + ], + }, + }, + async run({ $ }) { + const response = await this.app.deleteRun({ + data: { + run_id: this.runId, + }, + $, + }); + + $.export("$summary", `Successfully deleted run with ID ${this.runId}.`); + + return response || {}; + }, +}; diff --git a/components/databricks/actions/delete-sql-warehouse/delete-sql-warehouse.mjs b/components/databricks/actions/delete-sql-warehouse/delete-sql-warehouse.mjs index 1004fe38fd410..47584608434df 100644 --- a/components/databricks/actions/delete-sql-warehouse/delete-sql-warehouse.mjs +++ b/components/databricks/actions/delete-sql-warehouse/delete-sql-warehouse.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-delete-sql-warehouse", name: "Delete SQL Warehouse", description: "Deletes a SQL Warehouse by ID. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/delete)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/edit-sql-warehouse/edit-sql-warehouse.mjs b/components/databricks/actions/edit-sql-warehouse/edit-sql-warehouse.mjs index ff28b9a5eea8f..293ee437f120a 100644 --- a/components/databricks/actions/edit-sql-warehouse/edit-sql-warehouse.mjs +++ b/components/databricks/actions/edit-sql-warehouse/edit-sql-warehouse.mjs @@ -7,7 +7,7 @@ export default { key: "databricks-edit-sql-warehouse", name: "Edit SQL Warehouse", description: "Edits the configuration of an existing SQL Warehouse. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/edit)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/export-run/export-run.mjs b/components/databricks/actions/export-run/export-run.mjs new file mode 100644 index 0000000000000..63fca03ae7303 --- /dev/null +++ b/components/databricks/actions/export-run/export-run.mjs @@ -0,0 +1,48 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-export-run", + name: "Export Run", + description: "Export and retrieve the job run task. [See the documentation](https://docs.databricks.com/api/workspace/jobs/exportrun)", + version: "0.0.1", + type: "action", + props: { + app, + runId: { + propDefinition: [ + app, + "runId", + ], + }, + viewsToExport: { + type: "string", + label: "Views to Export", + description: "Which views to export. Defaults to `CODE`", + optional: true, + options: [ + "CODE", + "DASHBOARDS", + "ALL", + ], + }, + }, + async run({ $ }) { + const { + app, + runId, + viewsToExport, + } = this; + + const response = await app.exportRun({ + $, + params: { + run_id: runId, + views_to_export: viewsToExport, + }, + }); + + $.export("$summary", `Successfully exported run with ID \`${runId}\`.`); + + return response; + }, +}; diff --git a/components/databricks/actions/get-endpoint/get-endpoint.mjs b/components/databricks/actions/get-endpoint/get-endpoint.mjs index 99fd6b71abb96..1f494f4658be1 100644 --- a/components/databricks/actions/get-endpoint/get-endpoint.mjs +++ b/components/databricks/actions/get-endpoint/get-endpoint.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-get-endpoint", name: "Get Endpoint", description: "Get details of a specific vector search endpoint. [See the documentation](https://docs.databricks.com/api/workspace/vectorsearchendpoints/getendpoint)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { databricks, diff --git a/components/databricks/actions/get-job-permissions/get-job-permissions.mjs b/components/databricks/actions/get-job-permissions/get-job-permissions.mjs new file mode 100644 index 0000000000000..3c9bae4657b9d --- /dev/null +++ b/components/databricks/actions/get-job-permissions/get-job-permissions.mjs @@ -0,0 +1,33 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-get-job-permissions", + name: "Get Job Permissions", + description: "Get permissions of a job. [See the documentation](https://docs.databricks.com/api/workspace/jobs/getpermissions)", + version: "0.0.1", + type: "action", + props: { + app, + jobId: { + propDefinition: [ + app, + "jobId", + ], + }, + }, + async run({ $ }) { + const { + app, + jobId, + } = this; + + const response = await app.getJobPermissions({ + $, + jobId, + }); + + $.export("$summary", `Successfully retrieved permissions for job with ID \`${jobId}\`.`); + + return response; + }, +}; diff --git a/components/databricks/actions/get-job/get-job.mjs b/components/databricks/actions/get-job/get-job.mjs new file mode 100644 index 0000000000000..6e418684cdd14 --- /dev/null +++ b/components/databricks/actions/get-job/get-job.mjs @@ -0,0 +1,35 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-get-job", + name: "Get Job", + description: "Retrieves the details for a single job. [See the documentation](https://docs.databricks.com/api/workspace/jobs/get)", + version: "0.0.1", + type: "action", + props: { + app, + jobId: { + propDefinition: [ + app, + "jobId", + ], + }, + }, + async run({ $ }) { + const { + app, + jobId, + } = this; + + const response = await app.getJob({ + $, + params: { + job_id: jobId, + }, + }); + + $.export("$summary", `Successfully retrieved job with ID \`${response.job_id}\`.`); + + return response; + }, +}; diff --git a/components/databricks/actions/get-run-output/get-run-output.mjs b/components/databricks/actions/get-run-output/get-run-output.mjs index 2d2434c1c284b..c44b1001a7bfa 100644 --- a/components/databricks/actions/get-run-output/get-run-output.mjs +++ b/components/databricks/actions/get-run-output/get-run-output.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-get-run-output", name: "Get Run Output", description: "Retrieve the output and metadata of a single task run. [See the documentation](https://docs.databricks.com/en/workflows/jobs/jobs-2.0-api.html#runs-get-output)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { databricks, diff --git a/components/databricks/actions/get-run/get-run.mjs b/components/databricks/actions/get-run/get-run.mjs new file mode 100644 index 0000000000000..84d95be7c0d5c --- /dev/null +++ b/components/databricks/actions/get-run/get-run.mjs @@ -0,0 +1,51 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-get-run", + name: "Get Run", + description: "Retrieve the metadata of a run. [See the documentation](https://docs.databricks.com/api/workspace/jobs/getrun)", + version: "0.0.1", + type: "action", + props: { + app, + runId: { + propDefinition: [ + app, + "runId", + ], + }, + includeHistory: { + type: "boolean", + label: "Include History", + description: "Whether to include the repair history in the response", + optional: true, + }, + includeResolvedValues: { + type: "boolean", + label: "Include Resolved Values", + description: "Whether to include resolved parameter values in the response", + optional: true, + }, + }, + async run({ $ }) { + const { + app, + runId, + includeHistory, + includeResolvedValues, + } = this; + + const response = await app.getRun({ + $, + params: { + run_id: runId, + include_history: includeHistory, + include_resolved_values: includeResolvedValues, + }, + }); + + $.export("$summary", `Successfully retrieved run with ID \`${response.job_run_id}\`.`); + + return response; + }, +}; diff --git a/components/databricks/actions/get-sql-warehouse-config/get-sql-warehouse-config.mjs b/components/databricks/actions/get-sql-warehouse-config/get-sql-warehouse-config.mjs index 0cdfa6a1129dc..1fbdda709e71b 100644 --- a/components/databricks/actions/get-sql-warehouse-config/get-sql-warehouse-config.mjs +++ b/components/databricks/actions/get-sql-warehouse-config/get-sql-warehouse-config.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-get-sql-warehouse-config", name: "Get SQL Warehouse Config", description: "Retrieves the global configuration for SQL Warehouses. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/getworkspacewarehouseconfig)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/get-sql-warehouse-permissions/get-sql-warehouse-permissions.mjs b/components/databricks/actions/get-sql-warehouse-permissions/get-sql-warehouse-permissions.mjs index 8c3085c52cd73..4d76f5bb41c74 100644 --- a/components/databricks/actions/get-sql-warehouse-permissions/get-sql-warehouse-permissions.mjs +++ b/components/databricks/actions/get-sql-warehouse-permissions/get-sql-warehouse-permissions.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-get-sql-warehouse-permissions", name: "Get SQL Warehouse Permissions", description: "Retrieves the permissions for a specific SQL Warehouse. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/getpermissions)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/get-sql-warehouse/get-sql-warehouse.mjs b/components/databricks/actions/get-sql-warehouse/get-sql-warehouse.mjs index 8476e09bb8a65..28d131c05c8f1 100644 --- a/components/databricks/actions/get-sql-warehouse/get-sql-warehouse.mjs +++ b/components/databricks/actions/get-sql-warehouse/get-sql-warehouse.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-get-sql-warehouse", name: "Get SQL Warehouse", description: "Retrieves details for a specific SQL Warehouse. [See docs](https://docs.databricks.com/api/workspace/warehouses/get)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/list-endpoints/list-endpoints.mjs b/components/databricks/actions/list-endpoints/list-endpoints.mjs index ed06bdebf9710..c0fe92e1672e6 100644 --- a/components/databricks/actions/list-endpoints/list-endpoints.mjs +++ b/components/databricks/actions/list-endpoints/list-endpoints.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-list-endpoints", name: "List Endpoints", description: "List all vector search endpoints. [See the documentation](https://docs.databricks.com/api/workspace/vectorsearchendpoints/listendpoints)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { databricks, diff --git a/components/databricks/actions/list-jobs/list-jobs.mjs b/components/databricks/actions/list-jobs/list-jobs.mjs new file mode 100644 index 0000000000000..9f60a6ea0224b --- /dev/null +++ b/components/databricks/actions/list-jobs/list-jobs.mjs @@ -0,0 +1,59 @@ +import app from "../../databricks.app.mjs"; +import constants from "../../common/constants.mjs"; + +export default { + key: "databricks-list-jobs", + name: "List Jobs", + description: "List all jobs using automatic pagination. [See the documentation](https://docs.databricks.com/api/workspace/jobs/list)", + version: "0.0.1", + type: "action", + props: { + app, + expandTasks: { + type: "boolean", + label: "Expand Tasks", + description: "Whether to include task and cluster details in the response", + optional: true, + }, + name: { + type: "string", + label: "Job Name", + description: "Optional name to filter on", + optional: true, + }, + maxRequests: { + type: "integer", + label: "Max Requests", + description: "Maximum number of API requests to make when paginating", + optional: true, + min: 1, + max: 10, + }, + }, + async run({ $ }) { + const { + app, + expandTasks, + name, + maxRequests, + } = this; + + const jobs = await app.paginate({ + requestor: app.listJobs, + maxRequests, + resultsKey: "jobs", + requestorArgs: { + $, + params: { + expand_tasks: expandTasks, + name, + limit: constants.DEFAULT_LIMIT, + }, + }, + }); + + $.export("$summary", `Successfully retrieved \`${jobs.length}\` job(s)`); + + return jobs; + }, +}; diff --git a/components/databricks/actions/list-runs/list-runs.mjs b/components/databricks/actions/list-runs/list-runs.mjs index 534eee7649c1b..d2d7fe17cd3f3 100644 --- a/components/databricks/actions/list-runs/list-runs.mjs +++ b/components/databricks/actions/list-runs/list-runs.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-list-runs", name: "List Runs", description: "Lists all runs available to the user. [See the documentation](https://docs.databricks.com/en/workflows/jobs/jobs-2.0-api.html#runs-list)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { databricks, diff --git a/components/databricks/actions/list-sql-warehouses/list-sql-warehouses.mjs b/components/databricks/actions/list-sql-warehouses/list-sql-warehouses.mjs index f83290f306ca4..356622572a9a9 100644 --- a/components/databricks/actions/list-sql-warehouses/list-sql-warehouses.mjs +++ b/components/databricks/actions/list-sql-warehouses/list-sql-warehouses.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-list-sql-warehouses", name: "List SQL Warehouses", description: "Lists all SQL Warehouses available in the Databricks workspace. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/list)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/repair-run/repair-run.mjs b/components/databricks/actions/repair-run/repair-run.mjs new file mode 100644 index 0000000000000..e5f9234fdf800 --- /dev/null +++ b/components/databricks/actions/repair-run/repair-run.mjs @@ -0,0 +1,67 @@ +import app from "../../databricks.app.mjs"; + +export default { + key: "databricks-repair-run", + name: "Repair Run", + description: "Re-run one or more tasks. [See the documentation](https://docs.databricks.com/api/workspace/jobs/repairrun)", + version: "0.0.1", + type: "action", + props: { + app, + // eslint-disable-next-line pipedream/props-label, pipedream/props-description + info: { + type: "alert", + alertType: "info", + content: "Either a **Rerun Tasks** or **Rerun All Failed Tasks** must be provided.", + }, + runId: { + propDefinition: [ + app, + "runId", + ], + }, + rerunTasks: { + type: "string[]", + label: "Rerun Tasks", + description: "The task keys of the task runs to repair", + optional: true, + }, + rerunAllFailedTasks: { + type: "boolean", + label: "Rerun All Failed Tasks", + description: "If true, repair all failed tasks. Only one of rerun_tasks or rerun_all_failed_tasks can be used", + optional: true, + }, + pipelineParamsFullRefresh: { + type: "boolean", + label: "Pipeline Params - Full Refresh", + description: "Controls whether the pipeline should perform a full refresh", + optional: true, + }, + }, + async run({ $ }) { + const { + app, + runId, + rerunTasks, + rerunAllFailedTasks, + pipelineParamsFullRefresh, + } = this; + + const response = await app.repairRun({ + $, + data: { + run_id: runId, + rerun_tasks: rerunTasks, + rerun_all_failed_tasks: rerunAllFailedTasks, + pipeline_params: { + full_refresh: pipelineParamsFullRefresh, + }, + }, + }); + + $.export("$summary", `Successfully initiated repair of run with ID \`${response.repair_id}\`.`); + + return response; + }, +}; diff --git a/components/databricks/actions/reset-job/reset-job.mjs b/components/databricks/actions/reset-job/reset-job.mjs new file mode 100644 index 0000000000000..cf6acbc2af856 --- /dev/null +++ b/components/databricks/actions/reset-job/reset-job.mjs @@ -0,0 +1,45 @@ +import app from "../../databricks.app.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + key: "databricks-reset-job", + name: "Reset Job", + description: "Overwrite all settings for the given job. [See the documentation](https://docs.databricks.com/api/workspace/jobs/reset)", + version: "0.0.1", + type: "action", + props: { + app, + jobId: { + propDefinition: [ + app, + "jobId", + ], + }, + newSettings: { + type: "string", + label: "New Settings", + description: "The new settings for the job. JSON string format with the complete job specification. [See the documentation](https://docs.databricks.com/api/workspace/jobs/reset#new_settings)", + }, + }, + async run({ $ }) { + const { + app, + jobId, + newSettings, + } = this; + + await app.resetJob({ + $, + data: { + job_id: jobId, + new_settings: utils.parseJsonInput(newSettings), + }, + }); + + $.export("$summary", `Successfully reset job with ID \`${jobId}\`.`); + + return { + success: true, + }; + }, +}; diff --git a/components/databricks/actions/run-job-now/run-job-now.mjs b/components/databricks/actions/run-job-now/run-job-now.mjs index 046f6dfb6c8bb..4318cb98d9e8a 100644 --- a/components/databricks/actions/run-job-now/run-job-now.mjs +++ b/components/databricks/actions/run-job-now/run-job-now.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-run-job-now", name: "Run Job Now", description: "Run a job now and return the id of the triggered run. [See the documentation](https://docs.databricks.com/en/workflows/jobs/jobs-2.0-api.html#runs-list)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { databricks, diff --git a/components/databricks/actions/set-job-permissions/set-job-permissions.mjs b/components/databricks/actions/set-job-permissions/set-job-permissions.mjs new file mode 100644 index 0000000000000..adf2897ec8faf --- /dev/null +++ b/components/databricks/actions/set-job-permissions/set-job-permissions.mjs @@ -0,0 +1,54 @@ +import app from "../../databricks.app.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + key: "databricks-set-job-permissions", + name: "Set Job Permissions", + description: "Set permissions on a job. [See the documentation](https://docs.databricks.com/api/workspace/jobs/setpermissions)", + version: "0.0.1", + type: "action", + props: { + app, + jobId: { + propDefinition: [ + app, + "jobId", + ], + }, + accessControlList: { + type: "string[]", + label: "Access Control List", + description: `List of permissions to set on the job. JSON string format with array of permission objects. [See the documentation](https://docs.databricks.com/api/workspace/jobs/setpermissions#access_control_list) + +**Example:** +\`\`\`json +[ + { + "permission_level": "IS_OWNER", + "user_name": "user@example.com" + } +] +\`\`\` +`, + }, + }, + async run({ $ }) { + const { + app, + jobId, + accessControlList, + } = this; + + const response = await app.setJobPermissions({ + $, + jobId, + data: { + access_control_list: utils.parseJsonInput(accessControlList), + }, + }); + + $.export("$summary", `Successfully set permissions for job with ID \`${jobId}\`.`); + + return response; + }, +}; diff --git a/components/databricks/actions/set-sql-warehouse-config/set-sql-warehouse-config.mjs b/components/databricks/actions/set-sql-warehouse-config/set-sql-warehouse-config.mjs index dddc5e9f40ddf..6c9d4a7b98e6e 100644 --- a/components/databricks/actions/set-sql-warehouse-config/set-sql-warehouse-config.mjs +++ b/components/databricks/actions/set-sql-warehouse-config/set-sql-warehouse-config.mjs @@ -6,7 +6,7 @@ export default { key: "databricks-set-sql-warehouse-config", name: "Set SQL Warehouse Config", description: "Updates the global configuration for SQL Warehouses. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/setworkspacewarehouseconfig)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/set-sql-warehouse-permissions/set-sql-warehouse-permissions.mjs b/components/databricks/actions/set-sql-warehouse-permissions/set-sql-warehouse-permissions.mjs index ff609e74645f5..202d1677dd5a9 100644 --- a/components/databricks/actions/set-sql-warehouse-permissions/set-sql-warehouse-permissions.mjs +++ b/components/databricks/actions/set-sql-warehouse-permissions/set-sql-warehouse-permissions.mjs @@ -6,7 +6,7 @@ export default { key: "databricks-set-sql-warehouse-permissions", name: "Set SQL Warehouse Permissions", description: "Updates the permissions for a specific SQL Warehouse. [See docs](https://docs.databricks.com/api/workspace/warehouses/setpermissions)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/start-sql-warehouse/start-sql-warehouse.mjs b/components/databricks/actions/start-sql-warehouse/start-sql-warehouse.mjs index 41b127c62a4d7..669a593323040 100644 --- a/components/databricks/actions/start-sql-warehouse/start-sql-warehouse.mjs +++ b/components/databricks/actions/start-sql-warehouse/start-sql-warehouse.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-start-sql-warehouse", name: "Start SQL Warehouse", description: "Starts a SQL Warehouse by ID. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/start)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/stop-sql-warehouse/stop-sql-warehouse.mjs b/components/databricks/actions/stop-sql-warehouse/stop-sql-warehouse.mjs index cffe2875a1540..0117fca5d801d 100644 --- a/components/databricks/actions/stop-sql-warehouse/stop-sql-warehouse.mjs +++ b/components/databricks/actions/stop-sql-warehouse/stop-sql-warehouse.mjs @@ -4,7 +4,7 @@ export default { key: "databricks-stop-sql-warehouse", name: "Stop SQL Warehouse", description: "Stops a SQL Warehouse by ID. [See the documentation](https://docs.databricks.com/api/workspace/warehouses/stop)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { databricks, diff --git a/components/databricks/actions/update-job/update-job.mjs b/components/databricks/actions/update-job/update-job.mjs new file mode 100644 index 0000000000000..6d6afec50bb7f --- /dev/null +++ b/components/databricks/actions/update-job/update-job.mjs @@ -0,0 +1,62 @@ +import app from "../../databricks.app.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + key: "databricks-update-job", + name: "Update Job", + description: "Update an existing job. Only the fields that are provided will be updated. [See the documentation](https://docs.databricks.com/api/workspace/jobs/update)", + version: "0.0.1", + type: "action", + props: { + app, + jobId: { + propDefinition: [ + app, + "jobId", + ], + }, + newSettings: { + type: "string", + label: "New Settings", + description: `The updated job settings. JSON string format with only the fields you want to update. [See the API documentation](https://docs.databricks.com/api/workspace/jobs/update#new_settings) + +**Example:** +\`\`\`json +{ + "name": "New Job Name" +} +\`\`\` + `, + optional: true, + }, + fieldsToRemove: { + type: "string[]", + label: "Fields to Remove", + description: "List of field paths to remove from the job settings. [See the API documentation](https://docs.databricks.com/api/workspace/jobs/update#fields_to_remove)", + optional: true, + }, + }, + async run({ $ }) { + const { + app, + jobId, + newSettings, + fieldsToRemove, + } = this; + + await app.updateJob({ + $, + data: { + job_id: jobId, + new_settings: utils.parseJsonInput(newSettings), + fields_to_remove: utils.parseJsonInput(fieldsToRemove), + }, + }); + + $.export("$summary", `Successfully updated job with ID \`${jobId}\`.`); + + return { + success: true, + }; + }, +}; diff --git a/components/databricks/common/constants.mjs b/components/databricks/common/constants.mjs index 4b53df7a27a86..620a90edbd8aa 100644 --- a/components/databricks/common/constants.mjs +++ b/components/databricks/common/constants.mjs @@ -1,3 +1,13 @@ +const DOMAIN_PLACEHOLDER = "{domain}"; +const BASE_URL = `https://${DOMAIN_PLACEHOLDER}.cloud.databricks.com`; + +const VERSION_PATH = { + V2_0: "/api/2.0", + V2_2: "/api/2.2", +}; + +const DEFAULT_LIMIT = 100; + export const CLUSTER_SIZES = [ "2X-Small", "X-Small", @@ -12,4 +22,8 @@ export const CLUSTER_SIZES = [ export default { CLUSTER_SIZES, + DOMAIN_PLACEHOLDER, + BASE_URL, + VERSION_PATH, + DEFAULT_LIMIT, }; diff --git a/components/databricks/common/utils.mjs b/components/databricks/common/utils.mjs index 40bdddb456371..cd0868241d928 100644 --- a/components/databricks/common/utils.mjs +++ b/components/databricks/common/utils.mjs @@ -28,4 +28,9 @@ const parseObject = (obj) => { export default { parseObject, + parseJsonInput: (value) => { + return value + ? parseObject(value) + : undefined; + }, }; diff --git a/components/databricks/databricks.app.mjs b/components/databricks/databricks.app.mjs index 8e8e317268b14..d4f941e5c922c 100644 --- a/components/databricks/databricks.app.mjs +++ b/components/databricks/databricks.app.mjs @@ -1,4 +1,5 @@ import { axios } from "@pipedream/platform"; +import constants from "./common/constants.mjs"; export default { type: "app", @@ -8,14 +9,30 @@ export default { type: "string", label: "Job", description: "Identifier of a job", - async options() { - const { jobs } = await this.listJobs(); - return jobs?.map(({ + async options({ prevContext }) { + if (prevContext.pageToken === null) { + return []; + } + const { + jobs, next_page_token: pageToken, + } = await this.listJobs({ + params: { + page_token: prevContext.pageToken, + limit: constants.DEFAULT_LIMIT, + }, + }); + const options = jobs?.map(({ job_id: value, settings, }) => ({ value, - label: settings.name, + label: settings?.name || value, })) || []; + return { + options, + context: { + pageToken: pageToken || null, + }, + }; }, }, runId: { @@ -82,9 +99,9 @@ export default { }, }, methods: { - - _baseUrl() { - return `https://${this.$auth.domain}.cloud.databricks.com/api/2.0`; + getUrl(path, versionPath = constants.VERSION_PATH.V2_0) { + const baseUrl = constants.BASE_URL.replace(constants.DOMAIN_PLACEHOLDER, this.$auth.domain); + return `${baseUrl}${versionPath}${path}`; }, _headers() { return { @@ -92,38 +109,142 @@ export default { }; }, _makeRequest({ - $ = this, - path, - ...args - }) { + $ = this, path, versionPath, ...args + } = {}) { return axios($, { - url: `${this._baseUrl()}${path}`, + url: this.getUrl(path, versionPath), headers: this._headers(), ...args, }); }, + createJob(args = {}) { + return this._makeRequest({ + path: "/jobs/create", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, listJobs(args = {}) { return this._makeRequest({ path: "/jobs/list", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + getJob(args = {}) { + return this._makeRequest({ + path: "/jobs/get", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + resetJob(args = {}) { + return this._makeRequest({ + path: "/jobs/reset", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + updateJob(args = {}) { + return this._makeRequest({ + path: "/jobs/update", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + deleteJob(args = {}) { + return this._makeRequest({ + path: "/jobs/delete", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + runJobNow(args = {}) { + return this._makeRequest({ + path: "/jobs/run-now", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + getRun(args = {}) { + return this._makeRequest({ + path: "/jobs/runs/get", + versionPath: constants.VERSION_PATH.V2_2, ...args, }); }, listRuns(args = {}) { return this._makeRequest({ path: "/jobs/runs/list", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + cancelRun(args = {}) { + return this._makeRequest({ + path: "/jobs/runs/cancel", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + cancelAllRuns(args = {}) { + return this._makeRequest({ + path: "/jobs/runs/cancel-all", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, ...args, }); }, getRunOutput(args = {}) { return this._makeRequest({ path: "/jobs/runs/get-output", + versionPath: constants.VERSION_PATH.V2_2, ...args, }); }, - runJobNow(args = {}) { + deleteRun(args = {}) { return this._makeRequest({ - path: "/jobs/run-now", + path: "/jobs/runs/delete", method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + repairRun(args = {}) { + return this._makeRequest({ + path: "/jobs/runs/repair", + method: "POST", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + exportRun(args = {}) { + return this._makeRequest({ + path: "/jobs/runs/export", + versionPath: constants.VERSION_PATH.V2_2, + ...args, + }); + }, + getJobPermissions({ + jobId, ...args + }) { + return this._makeRequest({ + path: `/permissions/jobs/${jobId}`, + ...args, + }); + }, + setJobPermissions({ + jobId, ...args + }) { + return this._makeRequest({ + path: `/permissions/jobs/${jobId}`, + method: "PUT", ...args, }); }, @@ -241,7 +362,6 @@ export default { ...args, }); }, - setSQLWarehousePermissions({ warehouseId, ...args }) { @@ -251,5 +371,45 @@ export default { ...args, }); }, + async paginate({ + requestor, requestorArgs = {}, + maxRequests = 3, resultsKey = "jobs", + }) { + const allResults = []; + let requestCount = 0; + let nextPageToken = null; + let hasMore = true; + + while (hasMore && requestCount < maxRequests) { + try { + const response = await requestor({ + ...requestorArgs, + params: { + ...requestorArgs.params, + page_token: nextPageToken, + }, + }); + + requestCount++; + + const results = response[resultsKey] || []; + + allResults.push(...results); + + nextPageToken = response.next_page_token; + hasMore = !!nextPageToken; + + if (results.length === 0) { + hasMore = false; + } + + } catch (error) { + console.error(`Pagination error on request ${requestCount}:`, error); + throw error; + } + } + + return allResults; + }, }, }; diff --git a/components/databricks/package.json b/components/databricks/package.json index d399a1889095f..c82b72576579b 100644 --- a/components/databricks/package.json +++ b/components/databricks/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/databricks", - "version": "0.3.0", + "version": "0.4.0", "description": "Pipedream Databricks Components", "main": "databricks.app.mjs", "keywords": [ From 4e0aa1d4643b243d82739b580c16ebbb619790ff Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Thu, 18 Sep 2025 10:38:04 -0400 Subject: [PATCH 35/52] Notion property building improvements (#18381) * validate property types * versions --- .../actions/append-block/append-block.mjs | 2 +- .../actions/common/base-page-builder.mjs | 3 +- .../complete-file-upload.mjs | 2 +- .../create-database/create-database.mjs | 2 +- .../create-file-upload/create-file-upload.mjs | 2 +- .../create-page-from-database.mjs | 2 +- .../actions/create-page/create-page.mjs | 2 +- .../actions/delete-block/delete-block.mjs | 2 +- .../actions/duplicate-page/duplicate-page.mjs | 2 +- .../list-file-uploads/list-file-uploads.mjs | 2 +- .../retrieve-file-upload.mjs | 2 +- .../send-file-upload/send-file-upload.mjs | 2 +- .../actions/update-block/update-block.mjs | 2 +- .../update-database/update-database.mjs | 2 +- .../actions/update-page/update-page.mjs | 2 +- .../notion/common/notion-page-properties.mjs | 96 +++++++++++++------ components/notion/package.json | 2 +- 17 files changed, 85 insertions(+), 44 deletions(-) diff --git a/components/notion/actions/append-block/append-block.mjs b/components/notion/actions/append-block/append-block.mjs index 98491e5140c67..9ca8f7696dd55 100644 --- a/components/notion/actions/append-block/append-block.mjs +++ b/components/notion/actions/append-block/append-block.mjs @@ -7,7 +7,7 @@ export default { name: "Append Block to Parent", description: "Append new and/or existing blocks to the specified parent. [See the documentation](https://developers.notion.com/reference/patch-block-children)", - version: "0.3.9", + version: "0.3.10", type: "action", props: { notion, diff --git a/components/notion/actions/common/base-page-builder.mjs b/components/notion/actions/common/base-page-builder.mjs index 2345e63759f15..b7ac7cfa6ebdc 100644 --- a/components/notion/actions/common/base-page-builder.mjs +++ b/components/notion/actions/common/base-page-builder.mjs @@ -87,6 +87,7 @@ export default { type: properties[property]?.type ?? property, label: properties[property]?.id || property, value: this[property] || this.properties?.[property], + name: properties[property]?.name || property, })); }, /** @@ -107,7 +108,7 @@ export default { try { notionProperties[property.label] = notionProperty?.convertToNotion(property); } catch { - throw new ConfigurationError(`Error converting property with label \`${property.label}\` to Notion format. Must be of type \`${NOTION_CONVERTER[property.type]?.type}\`.`); + throw new ConfigurationError(`Error converting property \`${property.name}\` to Notion format. Must be of type \`${NOTION_CONVERTER[property.type]?.type}\`.`); } } } diff --git a/components/notion/actions/complete-file-upload/complete-file-upload.mjs b/components/notion/actions/complete-file-upload/complete-file-upload.mjs index e34426e8e0999..876296b2491f1 100644 --- a/components/notion/actions/complete-file-upload/complete-file-upload.mjs +++ b/components/notion/actions/complete-file-upload/complete-file-upload.mjs @@ -6,7 +6,7 @@ export default { key: "notion-complete-file-upload", name: "Complete File Upload", description: "Use this action to finalize a `mode=multi_part` file upload after all of the parts have been sent successfully. [See the documentation](https://developers.notion.com/reference/complete-a-file-upload)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { notion, diff --git a/components/notion/actions/create-database/create-database.mjs b/components/notion/actions/create-database/create-database.mjs index cf75b649ac8db..40dd875659b35 100644 --- a/components/notion/actions/create-database/create-database.mjs +++ b/components/notion/actions/create-database/create-database.mjs @@ -7,7 +7,7 @@ export default { key: "notion-create-database", name: "Create Database", description: "Create a database and its initial data source. [See the documentation](https://developers.notion.com/reference/database-create)", - version: "0.1.1", + version: "0.1.2", type: "action", props: { notion, diff --git a/components/notion/actions/create-file-upload/create-file-upload.mjs b/components/notion/actions/create-file-upload/create-file-upload.mjs index ab0b03e21b23f..90f26f41472f2 100644 --- a/components/notion/actions/create-file-upload/create-file-upload.mjs +++ b/components/notion/actions/create-file-upload/create-file-upload.mjs @@ -6,7 +6,7 @@ export default { key: "notion-create-file-upload", name: "Create File Upload", description: "Create a file upload. [See the documentation](https://developers.notion.com/reference/create-a-file-upload)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { notion, diff --git a/components/notion/actions/create-page-from-database/create-page-from-database.mjs b/components/notion/actions/create-page-from-database/create-page-from-database.mjs index afa080bc6473b..48546ca5de419 100644 --- a/components/notion/actions/create-page-from-database/create-page-from-database.mjs +++ b/components/notion/actions/create-page-from-database/create-page-from-database.mjs @@ -8,7 +8,7 @@ export default { key: "notion-create-page-from-database", name: "Create Page from Data Source", description: "Create a page from a data source. [See the documentation](https://developers.notion.com/reference/post-page)", - version: "1.0.1", + version: "1.0.2", type: "action", props: { notion, diff --git a/components/notion/actions/create-page/create-page.mjs b/components/notion/actions/create-page/create-page.mjs index 032fe7977eb0c..a4c81767d418c 100644 --- a/components/notion/actions/create-page/create-page.mjs +++ b/components/notion/actions/create-page/create-page.mjs @@ -7,7 +7,7 @@ export default { key: "notion-create-page", name: "Create Page", description: "Create a page from a parent page. [See the documentation](https://developers.notion.com/reference/post-page)", - version: "0.2.22", + version: "0.2.23", type: "action", props: { notion, diff --git a/components/notion/actions/delete-block/delete-block.mjs b/components/notion/actions/delete-block/delete-block.mjs index 791c085f350e5..94f1818f36e32 100644 --- a/components/notion/actions/delete-block/delete-block.mjs +++ b/components/notion/actions/delete-block/delete-block.mjs @@ -6,7 +6,7 @@ export default { key: "notion-delete-block", name: "Delete Block", description: "Sets a Block object, including page blocks, to archived: true using the ID specified. [See the documentation](https://developers.notion.com/reference/delete-a-block)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { notion, diff --git a/components/notion/actions/duplicate-page/duplicate-page.mjs b/components/notion/actions/duplicate-page/duplicate-page.mjs index ede033c683b67..69144f464dc15 100644 --- a/components/notion/actions/duplicate-page/duplicate-page.mjs +++ b/components/notion/actions/duplicate-page/duplicate-page.mjs @@ -7,7 +7,7 @@ export default { key: "notion-duplicate-page", name: "Duplicate Page", description: "Create a new page copied from an existing page block. [See the documentation](https://developers.notion.com/reference/post-page)", - version: "0.0.19", + version: "0.0.20", type: "action", props: { notion, diff --git a/components/notion/actions/list-file-uploads/list-file-uploads.mjs b/components/notion/actions/list-file-uploads/list-file-uploads.mjs index 770c7fbfe35b4..ca58c024bf1e0 100644 --- a/components/notion/actions/list-file-uploads/list-file-uploads.mjs +++ b/components/notion/actions/list-file-uploads/list-file-uploads.mjs @@ -6,7 +6,7 @@ export default { key: "notion-list-file-uploads", name: "List File Uploads", description: "Use this action to list file uploads. [See the documentation](https://developers.notion.com/reference/list-file-uploads)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { notion, diff --git a/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs b/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs index 1308069faf600..ec3d500ddde58 100644 --- a/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs +++ b/components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs @@ -6,7 +6,7 @@ export default { key: "notion-retrieve-file-upload", name: "Retrieve File Upload", description: "Use this action to retrieve a file upload. [See the documentation](https://developers.notion.com/reference/retrieve-a-file-upload)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { notion, diff --git a/components/notion/actions/send-file-upload/send-file-upload.mjs b/components/notion/actions/send-file-upload/send-file-upload.mjs index 6d9747b689090..dccb0cf4d6614 100644 --- a/components/notion/actions/send-file-upload/send-file-upload.mjs +++ b/components/notion/actions/send-file-upload/send-file-upload.mjs @@ -8,7 +8,7 @@ export default { key: "notion-send-file-upload", name: "Send File Upload", description: "Send a file upload. [See the documentation](https://developers.notion.com/reference/send-a-file-upload)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { notion, diff --git a/components/notion/actions/update-block/update-block.mjs b/components/notion/actions/update-block/update-block.mjs index 89cddd64c9b11..6771492b975e3 100644 --- a/components/notion/actions/update-block/update-block.mjs +++ b/components/notion/actions/update-block/update-block.mjs @@ -7,7 +7,7 @@ export default { key: "notion-update-block", name: "Update Child Block", description: "Updates a child block object. [See the documentation](https://developers.notion.com/reference/update-a-block)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { notion, diff --git a/components/notion/actions/update-database/update-database.mjs b/components/notion/actions/update-database/update-database.mjs index d00b0cf03f562..907858efdf619 100644 --- a/components/notion/actions/update-database/update-database.mjs +++ b/components/notion/actions/update-database/update-database.mjs @@ -7,7 +7,7 @@ export default { key: "notion-update-database", name: "Update Data Source", description: "Update a data source. [See the documentation](https://developers.notion.com/reference/update-a-data-source)", - version: "1.0.1", + version: "1.0.2", type: "action", props: { notion, diff --git a/components/notion/actions/update-page/update-page.mjs b/components/notion/actions/update-page/update-page.mjs index 6f31a04b750ce..3bbdc9bd6e164 100644 --- a/components/notion/actions/update-page/update-page.mjs +++ b/components/notion/actions/update-page/update-page.mjs @@ -7,7 +7,7 @@ export default { key: "notion-update-page", name: "Update Page", description: "Update a page's property values. To append page content, use the *Append Block* action instead. [See the documentation](https://developers.notion.com/reference/patch-page)", - version: "2.0.1", + version: "2.0.2", type: "action", props: { notion, diff --git a/components/notion/common/notion-page-properties.mjs b/components/notion/common/notion-page-properties.mjs index 621e304c3e352..bbd0fa08aec23 100644 --- a/components/notion/common/notion-page-properties.mjs +++ b/components/notion/common/notion-page-properties.mjs @@ -13,43 +13,68 @@ const NOTION_PAGE_PROPERTIES = { type: "string", example: "New Beauty Title", options: () => undefined, - convertToNotion: (property) => ({ - title: utils.buildTextProperty(property.value), - }), + convertToNotion: (property) => { + if (typeof property.value !== "string") { + throw new Error; + } + return { + title: utils.buildTextProperty(property.value), + }; + }, }, rich_text: { type: "string", example: "A beauty text value", options: () => undefined, - convertToNotion: (property) => ({ - rich_text: utils.buildTextProperty(property.value), - }), + convertToNotion: (property) => { + if (typeof property.value !== "string") { + throw new Error; + } + return { + rich_text: utils.buildTextProperty(property.value), + }; + }, }, number: { type: "integer", example: "59", options: () => undefined, - convertToNotion: (property) => ({ - number: property.value, - }), + convertToNotion: (property) => { + if (isNaN(property.value)) { + throw new Error; + } + return { + number: property.value, + }; + }, }, status: { type: "string", options: (property) => property.status?.options.map((option) => option.name), - convertToNotion: (property) => ({ - status: { - name: property.value, - }, - }), + convertToNotion: (property) => { + if (typeof property.value !== "string") { + throw new Error; + } + return { + status: { + name: property.value, + }, + }; + }, }, select: { type: "string", options: (property) => property.select?.options.map((option) => option.name), - convertToNotion: (property) => ({ - select: { - name: property.value, - }, - }), + convertToNotion: (property) => { + if (typeof property.value !== "string") { + throw new Error; + } + return { + select: { + name: property.value, + }, + }; + }, }, multi_select: { type: "string[]", @@ -113,25 +138,40 @@ const NOTION_PAGE_PROPERTIES = { type: "string", example: "https://pipedream.com", options: () => undefined, - convertToNotion: (property) => ({ - url: property.value, - }), + convertToNotion: (property) => { + if (typeof property.value !== "string") { + throw new Error; + } + return { + url: property.value, + }; + }, }, email: { type: "string", example: "example@pipedream.com", options: () => undefined, - convertToNotion: (property) => ({ - email: property.value, - }), + convertToNotion: (property) => { + if (typeof property.value !== "string") { + throw new Error; + } + return { + email: property.value, + }; + }, }, phone_number: { type: "string", example: "999-999-9999", options: () => undefined, - convertToNotion: (property) => ({ - phone_number: property.value, - }), + convertToNotion: (property) => { + if (typeof property.value !== "string") { + throw new Error; + } + return { + phone_number: property.value, + }; + }, }, relation: { type: "string[]", diff --git a/components/notion/package.json b/components/notion/package.json index ba167d9dafbee..2d9b3e6dfb2dd 100644 --- a/components/notion/package.json +++ b/components/notion/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/notion", - "version": "1.0.1", + "version": "1.0.2", "description": "Pipedream Notion Components", "main": "notion.app.mjs", "keywords": [ From 5a236a9a2b4703a66cf73de47e6dbb3a08cf16f2 Mon Sep 17 00:00:00 2001 From: Andrew Chuang Date: Thu, 18 Sep 2025 14:44:53 -0400 Subject: [PATCH 36/52] Google Business - add debug log (#18407) * add debug log * bump versions --- components/google_my_business/package.json | 2 +- components/google_my_business/sources/common.ts | 1 + .../sources/new-post-created/new-post-created.ts | 2 +- .../new-review-created-multiple-locations.ts | 2 +- .../sources/new-review-created/new-review-created.ts | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/components/google_my_business/package.json b/components/google_my_business/package.json index a5e75a73c25f1..f76dffc66416e 100644 --- a/components/google_my_business/package.json +++ b/components/google_my_business/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/google_my_business", - "version": "0.2.1", + "version": "0.2.2", "description": "Pipedream Google My Business Components", "main": "dist/app/google_my_business.app.mjs", "keywords": [ diff --git a/components/google_my_business/sources/common.ts b/components/google_my_business/sources/common.ts index 0ab25a5f159ce..46e93ef75459c 100644 --- a/components/google_my_business/sources/common.ts +++ b/components/google_my_business/sources/common.ts @@ -53,6 +53,7 @@ export default { const currentRun: number = Date.now(); const lastRun: Date = this.getLastRun(); const items: EntityWithCreateTime[] = await this.getItems(); + console.log("Number of reviews: ", items.length); this.setLastRun(currentRun); const filteredItems = (lastRun diff --git a/components/google_my_business/sources/new-post-created/new-post-created.ts b/components/google_my_business/sources/new-post-created/new-post-created.ts index 4e2ac9a9f436d..2e21f3a45e6d0 100644 --- a/components/google_my_business/sources/new-post-created/new-post-created.ts +++ b/components/google_my_business/sources/new-post-created/new-post-created.ts @@ -10,7 +10,7 @@ export default defineSource({ key: "google_my_business-new-post-created", name: "New Post Created", description: `Emit new event for each new local post on a location [See the documentation](${DOCS_LINK})`, - version: "0.0.5", + version: "0.0.6", type: "source", dedupe: "unique", methods: { diff --git a/components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts b/components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts index 53bf8255ca218..e557c52e9eaaa 100644 --- a/components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts +++ b/components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts @@ -13,7 +13,7 @@ export default defineSource({ key: "google_my_business-new-review-created-multiple-locations", name: "New Review Created (Multiple Locations)", description: `Emit new event for each new review on any of the selected locations [See the documentation](${DOCS_LINK})`, - version: "0.0.2", + version: "0.0.3", type: "source", dedupe: "unique", props: { diff --git a/components/google_my_business/sources/new-review-created/new-review-created.ts b/components/google_my_business/sources/new-review-created/new-review-created.ts index 27e7dca54f05b..2460080b98663 100644 --- a/components/google_my_business/sources/new-review-created/new-review-created.ts +++ b/components/google_my_business/sources/new-review-created/new-review-created.ts @@ -10,7 +10,7 @@ export default defineSource({ key: "google_my_business-new-review-created", name: "New Review Created", description: `Emit new event for each new review on a location [See the documentation](${DOCS_LINK})`, - version: "0.0.5", + version: "0.0.6", type: "source", dedupe: "unique", methods: { From 52c9a9496b8728fb4ff0589337c83995fb806f4f Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Thu, 18 Sep 2025 16:17:24 -0400 Subject: [PATCH 37/52] Notion API Key - update @pipedream/notion version (#18409) * update @pipedream/notion dependency version * pnpm-lock.yaml --- .../actions/append-block/append-block.mjs | 2 +- .../actions/create-comment/create-comment.mjs | 2 +- .../create-page-from-database.mjs | 2 +- .../actions/create-page/create-page.mjs | 2 +- .../actions/duplicate-page/duplicate-page.mjs | 2 +- .../actions/query-database/query-database.mjs | 2 +- .../actions/retrieve-block/retrieve-block.mjs | 2 +- .../retrieve-database-content.mjs | 2 +- .../retrieve-database-schema.mjs | 2 +- .../retrieve-page-property-item.mjs | 2 +- .../actions/retrieve-page/retrieve-page.mjs | 2 +- .../notion_api_key/actions/search/search.mjs | 2 +- .../actions/update-page/update-page.mjs | 2 +- components/notion_api_key/package.json | 4 +- .../new-comment-created.mjs | 2 +- .../sources/new-database/new-database.mjs | 2 +- .../sources/new-page/new-page.mjs | 2 +- .../page-or-subpage-updated.mjs | 2 +- .../updated-page-id/updated-page-id.mjs | 2 +- .../sources/updated-page/updated-page.mjs | 2 +- pnpm-lock.yaml | 41 ++++++++----------- 21 files changed, 38 insertions(+), 45 deletions(-) diff --git a/components/notion_api_key/actions/append-block/append-block.mjs b/components/notion_api_key/actions/append-block/append-block.mjs index 7434240d5234b..a701214eebe86 100644 --- a/components/notion_api_key/actions/append-block/append-block.mjs +++ b/components/notion_api_key/actions/append-block/append-block.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-append-block", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/create-comment/create-comment.mjs b/components/notion_api_key/actions/create-comment/create-comment.mjs index 8ee72bcd4e47e..5d169d6f7dffc 100644 --- a/components/notion_api_key/actions/create-comment/create-comment.mjs +++ b/components/notion_api_key/actions/create-comment/create-comment.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-create-comment", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/create-page-from-database/create-page-from-database.mjs b/components/notion_api_key/actions/create-page-from-database/create-page-from-database.mjs index ca9218a4f8db1..92836864abec1 100644 --- a/components/notion_api_key/actions/create-page-from-database/create-page-from-database.mjs +++ b/components/notion_api_key/actions/create-page-from-database/create-page-from-database.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-create-page-from-database", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/create-page/create-page.mjs b/components/notion_api_key/actions/create-page/create-page.mjs index 85ff2ca01bc57..3abb3dd4b235a 100644 --- a/components/notion_api_key/actions/create-page/create-page.mjs +++ b/components/notion_api_key/actions/create-page/create-page.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-create-page", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/duplicate-page/duplicate-page.mjs b/components/notion_api_key/actions/duplicate-page/duplicate-page.mjs index c0163425cd47c..83e56f8158717 100644 --- a/components/notion_api_key/actions/duplicate-page/duplicate-page.mjs +++ b/components/notion_api_key/actions/duplicate-page/duplicate-page.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-duplicate-page", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/query-database/query-database.mjs b/components/notion_api_key/actions/query-database/query-database.mjs index 2905fff8ed95a..1593fa1f71006 100644 --- a/components/notion_api_key/actions/query-database/query-database.mjs +++ b/components/notion_api_key/actions/query-database/query-database.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-query-database", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/retrieve-block/retrieve-block.mjs b/components/notion_api_key/actions/retrieve-block/retrieve-block.mjs index fdaa02c2090ab..77d8c8213fe14 100644 --- a/components/notion_api_key/actions/retrieve-block/retrieve-block.mjs +++ b/components/notion_api_key/actions/retrieve-block/retrieve-block.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-retrieve-block", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/retrieve-database-content/retrieve-database-content.mjs b/components/notion_api_key/actions/retrieve-database-content/retrieve-database-content.mjs index d83e9c349a406..b832451d9ad08 100644 --- a/components/notion_api_key/actions/retrieve-database-content/retrieve-database-content.mjs +++ b/components/notion_api_key/actions/retrieve-database-content/retrieve-database-content.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-retrieve-database-content", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/retrieve-database-schema/retrieve-database-schema.mjs b/components/notion_api_key/actions/retrieve-database-schema/retrieve-database-schema.mjs index 5bc480b46a1dc..3b2e0b0d17fc3 100644 --- a/components/notion_api_key/actions/retrieve-database-schema/retrieve-database-schema.mjs +++ b/components/notion_api_key/actions/retrieve-database-schema/retrieve-database-schema.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-retrieve-database-schema", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/retrieve-page-property-item/retrieve-page-property-item.mjs b/components/notion_api_key/actions/retrieve-page-property-item/retrieve-page-property-item.mjs index 613956407950c..ecb1bfea1a728 100644 --- a/components/notion_api_key/actions/retrieve-page-property-item/retrieve-page-property-item.mjs +++ b/components/notion_api_key/actions/retrieve-page-property-item/retrieve-page-property-item.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-retrieve-page-property-item", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/retrieve-page/retrieve-page.mjs b/components/notion_api_key/actions/retrieve-page/retrieve-page.mjs index 03303cc6ebf78..f596ec95495c9 100644 --- a/components/notion_api_key/actions/retrieve-page/retrieve-page.mjs +++ b/components/notion_api_key/actions/retrieve-page/retrieve-page.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-retrieve-page", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/search/search.mjs b/components/notion_api_key/actions/search/search.mjs index 94e1adb926288..dfa14b9edc223 100644 --- a/components/notion_api_key/actions/search/search.mjs +++ b/components/notion_api_key/actions/search/search.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-search", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/actions/update-page/update-page.mjs b/components/notion_api_key/actions/update-page/update-page.mjs index 3dc6e95a1fd33..c04a523fa2fb6 100644 --- a/components/notion_api_key/actions/update-page/update-page.mjs +++ b/components/notion_api_key/actions/update-page/update-page.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-update-page", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/package.json b/components/notion_api_key/package.json index d91da39f9466c..b8e4f03a9b0ae 100644 --- a/components/notion_api_key/package.json +++ b/components/notion_api_key/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/notion_api_key", - "version": "0.1.2", + "version": "0.1.3", "description": "Pipedream Notion (API Key) Components", "main": "notion_api_key.app.mjs", "keywords": [ @@ -14,6 +14,6 @@ }, "dependencies": { "@notionhq/client": "4.0.2", - "@pipedream/notion": "^0.10.1" + "@pipedream/notion": "^1.0.2" } } diff --git a/components/notion_api_key/sources/new-comment-created/new-comment-created.mjs b/components/notion_api_key/sources/new-comment-created/new-comment-created.mjs index b07b6e7d065dc..94edc8fdd69ed 100644 --- a/components/notion_api_key/sources/new-comment-created/new-comment-created.mjs +++ b/components/notion_api_key/sources/new-comment-created/new-comment-created.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-new-comment-created", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/sources/new-database/new-database.mjs b/components/notion_api_key/sources/new-database/new-database.mjs index 1cd83ebed2e8f..1d21eaa0d847a 100644 --- a/components/notion_api_key/sources/new-database/new-database.mjs +++ b/components/notion_api_key/sources/new-database/new-database.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-new-database", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/sources/new-page/new-page.mjs b/components/notion_api_key/sources/new-page/new-page.mjs index f64a4a565aef2..226bc8bcfd18f 100644 --- a/components/notion_api_key/sources/new-page/new-page.mjs +++ b/components/notion_api_key/sources/new-page/new-page.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-new-page", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/sources/page-or-subpage-updated/page-or-subpage-updated.mjs b/components/notion_api_key/sources/page-or-subpage-updated/page-or-subpage-updated.mjs index 7f082dc994cad..1b4a138b39c11 100644 --- a/components/notion_api_key/sources/page-or-subpage-updated/page-or-subpage-updated.mjs +++ b/components/notion_api_key/sources/page-or-subpage-updated/page-or-subpage-updated.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-page-or-subpage-updated", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/sources/updated-page-id/updated-page-id.mjs b/components/notion_api_key/sources/updated-page-id/updated-page-id.mjs index 13d76a32ec28a..8b39dae131d94 100644 --- a/components/notion_api_key/sources/updated-page-id/updated-page-id.mjs +++ b/components/notion_api_key/sources/updated-page-id/updated-page-id.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-updated-page-id", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/components/notion_api_key/sources/updated-page/updated-page.mjs b/components/notion_api_key/sources/updated-page/updated-page.mjs index da72c60eb3683..bfdd7b53c91d0 100644 --- a/components/notion_api_key/sources/updated-page/updated-page.mjs +++ b/components/notion_api_key/sources/updated-page/updated-page.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "notion_api_key-updated-page", - version: "0.0.2", + version: "0.0.3", name, description, type, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 39864b0b88c10..478385d8cd97e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4628,8 +4628,7 @@ importers: components/ethereum: {} - components/etrusted: - specifiers: {} + components/etrusted: {} components/etsy: dependencies: @@ -7105,8 +7104,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/intelliflo_office: - specifiers: {} + components/intelliflo_office: {} components/intellihr: dependencies: @@ -7626,8 +7624,7 @@ importers: specifier: ^1.0.1 version: 1.0.1 - components/kordiam: - specifiers: {} + components/kordiam: {} components/koyeb: {} @@ -9605,8 +9602,8 @@ importers: specifier: 4.0.2 version: 4.0.2 '@pipedream/notion': - specifier: ^0.10.1 - version: 0.10.1 + specifier: ^1.0.2 + version: 1.0.2 components/nozbe_teams: {} @@ -10481,8 +10478,7 @@ importers: specifier: ^2.0.0 version: 2.0.0 - components/peekalink: - specifiers: {} + components/peekalink: {} components/peerdom: dependencies: @@ -12281,8 +12277,7 @@ importers: specifier: ^3.0.3 version: 3.0.3 - components/rundeck: - specifiers: {} + components/rundeck: {} components/runpod: {} @@ -14432,8 +14427,7 @@ importers: specifier: ^1.6.5 version: 1.6.6 - components/thoughtspot: - specifiers: {} + components/thoughtspot: {} components/threads: dependencies: @@ -14466,8 +14460,7 @@ importers: specifier: ^1.0.1 version: 1.0.1 - components/ticketsauce: - specifiers: {} + components/ticketsauce: {} components/ticktick: dependencies: @@ -20214,8 +20207,8 @@ packages: '@pipedream/notiff_io@0.1.0': resolution: {integrity: sha512-jgt5JJGxI9SM6chDeQpxbaS/NSuUUxhe/PeAXRdZKx28Gp0QCxW7egIImC3pqQ9aMSubaeygRyR0ELhKhmbtPg==} - '@pipedream/notion@0.10.1': - resolution: {integrity: sha512-3P3zvFMIHur5BaoFAkAo3t5hPoblDNxYrSWw1UdicTGtWMne43Oo9+qOm7NAeQDEN5I1sHDLprKv2aMM2beB7w==} + '@pipedream/notion@1.0.2': + resolution: {integrity: sha512-qVMpoUOus3E4oYtrPoHq0jciipxY4Y9bOxqaiv6uyUbxOKC5QaVvOIRgge5E++uR7Bf46NepwwTcW7wujktUrw==} '@pipedream/platform@0.10.0': resolution: {integrity: sha512-N3F/xVfBZQXc9wl+2/4E8U9Zma1rxpvylK6Gtw8Ofmiwjnmnvs+2SNjEpIXBPUeL+wxEkofSGOq7bkqt1hqwDg==} @@ -30940,22 +30933,22 @@ packages: superagent@3.8.1: resolution: {integrity: sha512-VMBFLYgFuRdfeNQSMLbxGSLfmXL/xc+OO+BZp41Za/NRDBet/BNbkRJrYzCUu0u4GU0i/ml2dtT8b9qgkw9z6Q==} engines: {node: '>= 4.0'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net superagent@4.1.0: resolution: {integrity: sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==} engines: {node: '>= 6.0'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net superagent@5.3.1: resolution: {integrity: sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==} engines: {node: '>= 7.0.0'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net superagent@7.1.6: resolution: {integrity: sha512-gZkVCQR1gy/oUXr+kxJMLDjla434KmSOKbx5iGD30Ql+AkJQ/YlPKECJy2nhqOsHLjGHzoDTXNSjhnvWhzKk7g==} engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net supports-color@10.0.0: resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==} @@ -38331,9 +38324,9 @@ snapshots: transitivePeerDependencies: - debug - '@pipedream/notion@0.10.1': + '@pipedream/notion@1.0.2': dependencies: - '@notionhq/client': 4.0.2 + '@notionhq/client': 5.0.0 '@pipedream/platform': 3.1.0 '@tryfabric/martian': 1.2.4 lodash-es: 4.17.21 From 5e65398dd4a553a5bdd3e3db834ad5f03bb8f0c6 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Thu, 18 Sep 2025 13:33:09 -0700 Subject: [PATCH 38/52] Adding app scaffolding for reduct_video --- components/reduct_video/package.json | 15 +++++++++++++++ components/reduct_video/reduct_video.app.mjs | 11 +++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/reduct_video/package.json create mode 100644 components/reduct_video/reduct_video.app.mjs diff --git a/components/reduct_video/package.json b/components/reduct_video/package.json new file mode 100644 index 0000000000000..77de970f39147 --- /dev/null +++ b/components/reduct_video/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/reduct_video", + "version": "0.0.1", + "description": "Pipedream Reduct.Video Components", + "main": "reduct_video.app.mjs", + "keywords": [ + "pipedream", + "reduct_video" + ], + "homepage": "https://pipedream.com/apps/reduct_video", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/components/reduct_video/reduct_video.app.mjs b/components/reduct_video/reduct_video.app.mjs new file mode 100644 index 0000000000000..9a2367bb8911c --- /dev/null +++ b/components/reduct_video/reduct_video.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "reduct_video", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 478385d8cd97e..a47c1b3321948 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11730,6 +11730,9 @@ importers: components/redmine: {} + components/reduct_video: + specifiers: {} + components/referral_rocket: {} components/referralhero: From 7073397eea98ce130494bdf28e26048c437e8008 Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Fri, 19 Sep 2025 00:33:09 -0700 Subject: [PATCH 39/52] Adding app scaffolding for shopware --- components/shopware/package.json | 15 +++++++++++++++ components/shopware/shopware.app.mjs | 11 +++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/shopware/package.json create mode 100644 components/shopware/shopware.app.mjs diff --git a/components/shopware/package.json b/components/shopware/package.json new file mode 100644 index 0000000000000..cf6c437862624 --- /dev/null +++ b/components/shopware/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/shopware", + "version": "0.0.1", + "description": "Pipedream Shopware Components", + "main": "shopware.app.mjs", + "keywords": [ + "pipedream", + "shopware" + ], + "homepage": "https://pipedream.com/apps/shopware", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/components/shopware/shopware.app.mjs b/components/shopware/shopware.app.mjs new file mode 100644 index 0000000000000..7110a7ea838de --- /dev/null +++ b/components/shopware/shopware.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "shopware", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a47c1b3321948..0075043be40e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13035,6 +13035,9 @@ importers: specifier: 1.6.0 version: 1.6.0 + components/shopware: + specifiers: {} + components/short: dependencies: '@pipedream/platform': From 61539b7b9d1058c168948706d0b5bb4998a913ad Mon Sep 17 00:00:00 2001 From: danhsiung <35384182+danhsiung@users.noreply.github.com> Date: Fri, 19 Sep 2025 00:33:15 -0700 Subject: [PATCH 40/52] Adding app scaffolding for instamojo --- components/instamojo/instamojo.app.mjs | 11 +++++++++++ components/instamojo/package.json | 15 +++++++++++++++ pnpm-lock.yaml | 3 +++ 3 files changed, 29 insertions(+) create mode 100644 components/instamojo/instamojo.app.mjs create mode 100644 components/instamojo/package.json diff --git a/components/instamojo/instamojo.app.mjs b/components/instamojo/instamojo.app.mjs new file mode 100644 index 0000000000000..84211cac23b06 --- /dev/null +++ b/components/instamojo/instamojo.app.mjs @@ -0,0 +1,11 @@ +export default { + type: "app", + app: "instamojo", + propDefinitions: {}, + methods: { + // this.$auth contains connected account data + authKeys() { + console.log(Object.keys(this.$auth)); + }, + }, +}; \ No newline at end of file diff --git a/components/instamojo/package.json b/components/instamojo/package.json new file mode 100644 index 0000000000000..82fd13fe83978 --- /dev/null +++ b/components/instamojo/package.json @@ -0,0 +1,15 @@ +{ + "name": "@pipedream/instamojo", + "version": "0.0.1", + "description": "Pipedream Instamojo Components", + "main": "instamojo.app.mjs", + "keywords": [ + "pipedream", + "instamojo" + ], + "homepage": "https://pipedream.com/apps/instamojo", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0075043be40e0..0b06542d2495a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7082,6 +7082,9 @@ importers: specifier: ^1.5.1 version: 1.6.6 + components/instamojo: + specifiers: {} + components/instant: {} components/instantly: From 2863b951612c189d86976e0d6b3667322bba4135 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Fri, 19 Sep 2025 10:37:19 -0400 Subject: [PATCH 41/52] Hubspot - bug fix to sources w/ property changes (#18379) * updates * versions --- components/hubspot/sources/common/common.mjs | 7 +++++-- .../delete-blog-article.mjs | 2 +- .../new-company-property-change.mjs | 18 +++++++++++------- .../new-contact-added-to-list.mjs | 2 +- .../new-contact-property-change.mjs | 3 ++- .../new-custom-object-property-change.mjs | 3 ++- .../new-deal-in-stage/new-deal-in-stage.mjs | 2 +- .../new-deal-property-change.mjs | 3 ++- .../new-email-event/new-email-event.mjs | 2 +- .../new-email-subscriptions-timeline.mjs | 2 +- .../sources/new-engagement/new-engagement.mjs | 2 +- .../hubspot/sources/new-event/new-event.mjs | 2 +- .../new-form-submission.mjs | 2 +- .../hubspot/sources/new-note/new-note.mjs | 4 ++-- .../new-or-updated-blog-article.mjs | 2 +- .../new-or-updated-company.mjs | 2 +- .../new-or-updated-contact.mjs | 2 +- .../new-or-updated-crm-object.mjs | 2 +- .../new-or-updated-custom-object.mjs | 2 +- .../new-or-updated-deal.mjs | 2 +- .../new-or-updated-line-item.mjs | 2 +- .../new-or-updated-product.mjs | 2 +- .../new-social-media-message.mjs | 2 +- .../hubspot/sources/new-task/new-task.mjs | 3 ++- .../new-ticket-property-change.mjs | 3 ++- .../hubspot/sources/new-ticket/new-ticket.mjs | 2 +- 26 files changed, 46 insertions(+), 34 deletions(-) diff --git a/components/hubspot/sources/common/common.mjs b/components/hubspot/sources/common/common.mjs index 54136ed079537..0cb85be397b60 100644 --- a/components/hubspot/sources/common/common.mjs +++ b/components/hubspot/sources/common/common.mjs @@ -140,8 +140,10 @@ export default { } } }, - async getPaginatedItems(resourceFn, params) { + async getPaginatedItems(resourceFn, params, after = null) { const items = []; + const maxPages = 10; + let page = 0; do { const { results, paging, @@ -149,10 +151,11 @@ export default { items.push(...results); if (paging) { params.after = paging.next.after; + page++; } else { delete params.after; } - } while (params.after); + } while (params.after && after && page < maxPages); return items; }, emitEvent(result) { diff --git a/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs b/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs index 48ccc0c1db985..dfd57c0b66ad4 100644 --- a/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs +++ b/components/hubspot/sources/delete-blog-article/delete-blog-article.mjs @@ -6,7 +6,7 @@ export default { key: "hubspot-delete-blog-article", name: "Deleted Blog Posts", description: "Emit new event for each deleted blog post.", - version: "0.0.32", + version: "0.0.33", dedupe: "unique", type: "source", methods: { diff --git a/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs b/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs index 70fb11014298b..d0981b47579ff 100644 --- a/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs +++ b/components/hubspot/sources/new-company-property-change/new-company-property-change.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-company-property-change", name: "New Company Property Change", description: "Emit new event when a specified property is provided or updated on a company. [See the documentation](https://developers.hubspot.com/docs/api/crm/companies)", - version: "0.0.25", + version: "0.0.26", dedupe: "unique", type: "source", props: { @@ -46,7 +46,7 @@ export default { return !updatedAfter || this.getTs(company) > updatedAfter; }, getParams(after) { - return { + const params = { object: "companies", data: { limit: DEFAULT_LIMIT, @@ -66,16 +66,19 @@ export default { propertyName: this.property, operator: "HAS_PROPERTY", }, - { - propertyName: "hs_lastmodifieddate", - operator: "GTE", - value: after, - }, ], }, ], }, }; + if (after) { + params.data.filterGroups[0].filters.push({ + propertyName: "hs_lastmodifieddate", + operator: "GTE", + value: after, + }); + } + return params; }, batchGetCompanies(inputs) { return this.hubspot.batchGetObjects({ @@ -104,6 +107,7 @@ export default { const updatedCompanies = await this.getPaginatedItems( this.hubspot.searchCRM, params, + after, ); if (!updatedCompanies.length) { diff --git a/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs b/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs index a874851adaf6d..719f41c674b9d 100644 --- a/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs +++ b/components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs @@ -12,7 +12,7 @@ export default { name: "New Contact Added to List", description: "Emit new event when a contact is added to a HubSpot list. [See the documentation](https://developers.hubspot.com/docs/reference/api/crm/lists#get-%2Fcrm%2Fv3%2Flists%2F%7Blistid%7D%2Fmemberships%2Fjoin-order)", - version: "0.0.4", + version: "0.0.5", type: "source", dedupe: "unique", props: { diff --git a/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs b/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs index f225bf151ee11..1f772c7fa9833 100644 --- a/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs +++ b/components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-contact-property-change", name: "New Contact Property Change", description: "Emit new event when a specified property is provided or updated on a contact. [See the documentation](https://developers.hubspot.com/docs/api/crm/contacts)", - version: "0.0.27", + version: "0.0.28", dedupe: "unique", type: "source", props: { @@ -106,6 +106,7 @@ export default { const updatedContacts = await this.getPaginatedItems( this.hubspot.searchCRM, params, + after, ); if (!updatedContacts.length) { diff --git a/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs b/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs index aa7f7986f3903..afd2fac5e75b9 100644 --- a/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs +++ b/components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs @@ -7,7 +7,7 @@ export default { name: "New Custom Object Property Change", description: "Emit new event when a specified property is provided or updated on a custom object.", - version: "0.0.17", + version: "0.0.18", dedupe: "unique", type: "source", props: { @@ -113,6 +113,7 @@ export default { const updatedObjects = await this.getPaginatedItems( this.hubspot.searchCRM, params, + after, ); if (!updatedObjects.length) { diff --git a/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs b/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs index be8bfad6873c7..8a1ae62e89231 100644 --- a/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs +++ b/components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs @@ -11,7 +11,7 @@ export default { key: "hubspot-new-deal-in-stage", name: "New Deal In Stage", description: "Emit new event for each new deal in a stage.", - version: "0.0.38", + version: "0.0.39", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs b/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs index 2801324f0e3ed..902a87c91c433 100644 --- a/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs +++ b/components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-deal-property-change", name: "New Deal Property Change", description: "Emit new event when a specified property is provided or updated on a deal. [See the documentation](https://developers.hubspot.com/docs/api/crm/deals)", - version: "0.0.26", + version: "0.0.27", dedupe: "unique", type: "source", props: { @@ -104,6 +104,7 @@ export default { const updatedDeals = await this.getPaginatedItems( this.hubspot.searchCRM, params, + after, ); if (!updatedDeals.length) { diff --git a/components/hubspot/sources/new-email-event/new-email-event.mjs b/components/hubspot/sources/new-email-event/new-email-event.mjs index 19b73dc3a36eb..4123cb5dfc758 100644 --- a/components/hubspot/sources/new-email-event/new-email-event.mjs +++ b/components/hubspot/sources/new-email-event/new-email-event.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-email-event", name: "New Email Event", description: "Emit new event for each new Hubspot email event.", - version: "0.0.35", + version: "0.0.36", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs b/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs index f2592e70dd788..2453b3226a42c 100644 --- a/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs +++ b/components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs @@ -6,7 +6,7 @@ export default { key: "hubspot-new-email-subscriptions-timeline", name: "New Email Subscriptions Timeline", description: "Emit new event when a new email timeline subscription is added for the portal.", - version: "0.0.32", + version: "0.0.33", dedupe: "unique", type: "source", methods: { diff --git a/components/hubspot/sources/new-engagement/new-engagement.mjs b/components/hubspot/sources/new-engagement/new-engagement.mjs index 806286bb36296..21be9136dff46 100644 --- a/components/hubspot/sources/new-engagement/new-engagement.mjs +++ b/components/hubspot/sources/new-engagement/new-engagement.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-engagement", name: "New Engagement", description: "Emit new event for each new engagement created. This action returns a maximum of 5000 records at a time, make sure you set a correct time range so you don't miss any events", - version: "0.0.37", + version: "0.0.38", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-event/new-event.mjs b/components/hubspot/sources/new-event/new-event.mjs index ac746ed42c069..a587a10f05ca4 100644 --- a/components/hubspot/sources/new-event/new-event.mjs +++ b/components/hubspot/sources/new-event/new-event.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-event", name: "New Events", description: "Emit new event for each new Hubspot event. Note: Only available for Marketing Hub Enterprise, Sales Hub Enterprise, Service Hub Enterprise, or CMS Hub Enterprise accounts", - version: "0.0.36", + version: "0.0.37", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-form-submission/new-form-submission.mjs b/components/hubspot/sources/new-form-submission/new-form-submission.mjs index bad33385f2683..808c8d3186559 100644 --- a/components/hubspot/sources/new-form-submission/new-form-submission.mjs +++ b/components/hubspot/sources/new-form-submission/new-form-submission.mjs @@ -6,7 +6,7 @@ export default { key: "hubspot-new-form-submission", name: "New Form Submission", description: "Emit new event for each new submission of a form.", - version: "0.0.37", + version: "0.0.38", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-note/new-note.mjs b/components/hubspot/sources/new-note/new-note.mjs index 3e40904c1d473..719e7553ddc0e 100644 --- a/components/hubspot/sources/new-note/new-note.mjs +++ b/components/hubspot/sources/new-note/new-note.mjs @@ -8,7 +8,7 @@ export default { key: "hubspot-new-note", name: "New Note Created", description: "Emit new event for each new note created. [See the documentation](https://developers.hubspot.com/docs/reference/api/crm/engagements/notes#get-%2Fcrm%2Fv3%2Fobjects%2Fnotes)", - version: "1.0.13", + version: "1.0.14", type: "source", dedupe: "unique", methods: { @@ -49,7 +49,7 @@ export default { }; }, async processResults(after, params) { - const notes = await this.getPaginatedItems(this.hubspot.listNotes.bind(this), params); + const notes = await this.getPaginatedItems(this.hubspot.listNotes.bind(this), params, after); await this.processEvents(notes, after); }, }, diff --git a/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs b/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs index b149d10e99c2d..360e1845bf66c 100644 --- a/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs +++ b/components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-or-updated-blog-article", name: "New or Updated Blog Post", description: "Emit new event for each new or updated blog post in Hubspot.", - version: "0.0.19", + version: "0.0.20", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs b/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs index c3267b264a40c..393c668d6bacd 100644 --- a/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs +++ b/components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-company", name: "New or Updated Company", description: "Emit new event for each new or updated company in Hubspot.", - version: "0.0.19", + version: "0.0.20", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs b/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs index 48951286d95f8..424dc2779bf72 100644 --- a/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs +++ b/components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-contact", name: "New or Updated Contact", description: "Emit new event for each new or updated contact in Hubspot.", - version: "0.0.20", + version: "0.0.21", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs b/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs index d66f56d5987f2..3f94a2a14ff5a 100644 --- a/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs +++ b/components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-or-updated-crm-object", name: "New or Updated CRM Object", description: "Emit new event each time a CRM Object of the specified object type is updated.", - version: "0.0.32", + version: "0.0.33", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs b/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs index 2f55c41b5b929..710da770b1b9b 100644 --- a/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs +++ b/components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs @@ -7,7 +7,7 @@ export default { key: "hubspot-new-or-updated-custom-object", name: "New or Updated Custom Object", description: "Emit new event each time a Custom Object of the specified schema is updated.", - version: "0.0.21", + version: "0.0.22", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs b/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs index 934bbacaae581..2626a04fb069e 100644 --- a/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs +++ b/components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-deal", name: "New or Updated Deal", description: "Emit new event for each new or updated deal in Hubspot", - version: "0.0.19", + version: "0.0.20", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs b/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs index b80c4fc070532..36900843e30e0 100644 --- a/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs +++ b/components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-line-item", name: "New or Updated Line Item", description: "Emit new event for each new line item added or updated in Hubspot.", - version: "0.0.19", + version: "0.0.20", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs b/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs index ff29b1b9c307e..b701fdeda52e1 100644 --- a/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs +++ b/components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-or-updated-product", name: "New or Updated Product", description: "Emit new event for each new or updated product in Hubspot.", - version: "0.0.19", + version: "0.0.20", dedupe: "unique", type: "source", props: { diff --git a/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs b/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs index e06559327c640..12523f93d734b 100644 --- a/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs +++ b/components/hubspot/sources/new-social-media-message/new-social-media-message.mjs @@ -7,7 +7,7 @@ export default { name: "New Social Media Message", description: "Emit new event when a message is posted from HubSpot to the specified social media channel. Note: Only available for Marketing Hub Enterprise accounts", - version: "0.0.32", + version: "0.0.33", type: "source", dedupe: "unique", props: { diff --git a/components/hubspot/sources/new-task/new-task.mjs b/components/hubspot/sources/new-task/new-task.mjs index d938018a75fa4..46b646dbd6612 100644 --- a/components/hubspot/sources/new-task/new-task.mjs +++ b/components/hubspot/sources/new-task/new-task.mjs @@ -9,7 +9,7 @@ export default { name: "New Task Created", description: "Emit new event for each new task created. [See the documentation](https://developers.hubspot.com/docs/reference/api/crm/engagements/tasks#get-%2Fcrm%2Fv3%2Fobjects%2Ftasks)", - version: "1.0.13", + version: "1.0.14", type: "source", dedupe: "unique", methods: { @@ -55,6 +55,7 @@ export default { const tasks = await this.getPaginatedItems( this.hubspot.listTasks.bind(this), params, + after, ); await this.processEvents(tasks, after); }, diff --git a/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs b/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs index b38d27db8ae0e..b24fb3515ee17 100644 --- a/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs +++ b/components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs @@ -8,7 +8,7 @@ export default { name: "New Ticket Property Change", description: "Emit new event when a specified property is provided or updated on a ticket. [See the documentation](https://developers.hubspot.com/docs/api/crm/tickets)", - version: "0.0.26", + version: "0.0.27", dedupe: "unique", type: "source", props: { @@ -108,6 +108,7 @@ export default { const updatedTickets = await this.getPaginatedItems( this.hubspot.searchCRM, params, + after, ); if (!updatedTickets.length) { diff --git a/components/hubspot/sources/new-ticket/new-ticket.mjs b/components/hubspot/sources/new-ticket/new-ticket.mjs index 2a51e25a0f857..2a4e2cfe6b215 100644 --- a/components/hubspot/sources/new-ticket/new-ticket.mjs +++ b/components/hubspot/sources/new-ticket/new-ticket.mjs @@ -10,7 +10,7 @@ export default { key: "hubspot-new-ticket", name: "New Ticket", description: "Emit new event for each new ticket created.", - version: "0.0.32", + version: "0.0.33", dedupe: "unique", type: "source", props: { From d15d706bb8e224104f4f9f100312b71a8826b460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Falc=C3=A3o?= <48412907+GTFalcao@users.noreply.github.com> Date: Sat, 20 Sep 2025 14:16:15 -0300 Subject: [PATCH 42/52] Google sheets type fix (#18411) * Fixing worksheetId prop type from string to integer * Version bumps --------- Co-authored-by: Leo Vu --- components/google_sheets/actions/add-column/add-column.mjs | 2 +- .../actions/add-multiple-rows/add-multiple-rows.mjs | 2 +- .../google_sheets/actions/add-single-row/add-single-row.mjs | 2 +- components/google_sheets/actions/clear-cell/clear-cell.mjs | 2 +- components/google_sheets/actions/clear-rows/clear-rows.mjs | 2 +- .../google_sheets/actions/copy-worksheet/copy-worksheet.mjs | 2 +- .../actions/create-spreadsheet/create-spreadsheet.mjs | 2 +- .../google_sheets/actions/create-worksheet/create-worksheet.mjs | 2 +- components/google_sheets/actions/delete-rows/delete-rows.mjs | 2 +- .../google_sheets/actions/delete-worksheet/delete-worksheet.mjs | 2 +- components/google_sheets/actions/find-row/find-row.mjs | 2 +- components/google_sheets/actions/get-cell/get-cell.mjs | 2 +- .../actions/get-spreadsheet-by-id/get-spreadsheet-by-id.mjs | 2 +- .../actions/get-values-in-range/get-values-in-range.mjs | 2 +- .../actions/insert-anchored-note/insert-anchored-note.mjs | 2 +- .../google_sheets/actions/insert-comment/insert-comment.mjs | 2 +- .../google_sheets/actions/list-worksheets/list-worksheets.mjs | 2 +- components/google_sheets/actions/update-cell/update-cell.mjs | 2 +- .../actions/update-multiple-rows/update-multiple-rows.mjs | 2 +- components/google_sheets/actions/update-row/update-row.mjs | 2 +- components/google_sheets/actions/upsert-row/upsert-row.mjs | 2 +- components/google_sheets/google_sheets.app.mjs | 2 +- components/google_sheets/package.json | 2 +- components/google_sheets/sources/common/new-row-added.mjs | 2 +- components/google_sheets/sources/common/new-updates.mjs | 2 +- components/google_sheets/sources/new-comment/new-comment.mjs | 2 +- .../sources/new-row-added-polling/new-row-added-polling.mjs | 2 +- .../google_sheets/sources/new-row-added/new-row-added.mjs | 2 +- components/google_sheets/sources/new-updates/new-updates.mjs | 2 +- .../google_sheets/sources/new-worksheet/new-worksheet.mjs | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/components/google_sheets/actions/add-column/add-column.mjs b/components/google_sheets/actions/add-column/add-column.mjs index 67e581b61c0f4..bc98c14dc6ca8 100644 --- a/components/google_sheets/actions/add-column/add-column.mjs +++ b/components/google_sheets/actions/add-column/add-column.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-add-column", name: "Create Column", description: "Create a new column in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/add-multiple-rows/add-multiple-rows.mjs b/components/google_sheets/actions/add-multiple-rows/add-multiple-rows.mjs index 2c2bbc43e1ced..69fd0c35307a1 100644 --- a/components/google_sheets/actions/add-multiple-rows/add-multiple-rows.mjs +++ b/components/google_sheets/actions/add-multiple-rows/add-multiple-rows.mjs @@ -11,7 +11,7 @@ export default { key: "google_sheets-add-multiple-rows", name: "Add Multiple Rows", description: "Add multiple rows of data to a Google Sheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)", - version: "0.2.13", + version: "0.2.14", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/add-single-row/add-single-row.mjs b/components/google_sheets/actions/add-single-row/add-single-row.mjs index baeb265aa1cc9..6d6b3a56a56e3 100644 --- a/components/google_sheets/actions/add-single-row/add-single-row.mjs +++ b/components/google_sheets/actions/add-single-row/add-single-row.mjs @@ -10,7 +10,7 @@ export default { key: "google_sheets-add-single-row", name: "Add Single Row", description: "Add a single row of data to Google Sheets. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)", - version: "2.1.15", + version: "2.1.16", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/clear-cell/clear-cell.mjs b/components/google_sheets/actions/clear-cell/clear-cell.mjs index 08878621c8e86..7eb6ec39a8d68 100644 --- a/components/google_sheets/actions/clear-cell/clear-cell.mjs +++ b/components/google_sheets/actions/clear-cell/clear-cell.mjs @@ -7,7 +7,7 @@ export default { key: "google_sheets-clear-cell", name: "Clear Cell", description: "Delete the content of a specific cell in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/clear)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/clear-rows/clear-rows.mjs b/components/google_sheets/actions/clear-rows/clear-rows.mjs index bdcbb7cd51cd8..a873cd0131a22 100644 --- a/components/google_sheets/actions/clear-rows/clear-rows.mjs +++ b/components/google_sheets/actions/clear-rows/clear-rows.mjs @@ -7,7 +7,7 @@ export default { key: "google_sheets-clear-rows", name: "Clear Rows", description: "Delete the content of a row or rows in a spreadsheet. Deleted rows will appear as blank rows. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/clear)", - version: "0.1.12", + version: "0.1.13", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/copy-worksheet/copy-worksheet.mjs b/components/google_sheets/actions/copy-worksheet/copy-worksheet.mjs index ffa0a91d96414..23f04994108e1 100644 --- a/components/google_sheets/actions/copy-worksheet/copy-worksheet.mjs +++ b/components/google_sheets/actions/copy-worksheet/copy-worksheet.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-copy-worksheet", name: "Copy Worksheet", description: "Copy an existing worksheet to another Google Sheets file. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.sheets/copyTo)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/create-spreadsheet/create-spreadsheet.mjs b/components/google_sheets/actions/create-spreadsheet/create-spreadsheet.mjs index 95c53fdd70c81..9c1d8805f0aff 100644 --- a/components/google_sheets/actions/create-spreadsheet/create-spreadsheet.mjs +++ b/components/google_sheets/actions/create-spreadsheet/create-spreadsheet.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-create-spreadsheet", name: "Create Spreadsheet", description: "Create a blank spreadsheet or duplicate an existing spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create)", - version: "0.1.12", + version: "0.1.13", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/create-worksheet/create-worksheet.mjs b/components/google_sheets/actions/create-worksheet/create-worksheet.mjs index d6ff8ae250c07..82202c09cf848 100644 --- a/components/google_sheets/actions/create-worksheet/create-worksheet.mjs +++ b/components/google_sheets/actions/create-worksheet/create-worksheet.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-create-worksheet", name: "Create Worksheet", description: "Create a blank worksheet with a title. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/delete-rows/delete-rows.mjs b/components/google_sheets/actions/delete-rows/delete-rows.mjs index a1c22b8b63d3c..5262dd3bef0d9 100644 --- a/components/google_sheets/actions/delete-rows/delete-rows.mjs +++ b/components/google_sheets/actions/delete-rows/delete-rows.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-delete-rows", name: "Delete Rows", description: "Deletes the specified rows from a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#deletedimensionrequest)", - version: "0.0.10", + version: "0.0.11", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/delete-worksheet/delete-worksheet.mjs b/components/google_sheets/actions/delete-worksheet/delete-worksheet.mjs index 6aa1cd9d9a2cd..d1e8c9589b6c9 100644 --- a/components/google_sheets/actions/delete-worksheet/delete-worksheet.mjs +++ b/components/google_sheets/actions/delete-worksheet/delete-worksheet.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-delete-worksheet", name: "Delete Worksheet", description: "Delete a specific worksheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/find-row/find-row.mjs b/components/google_sheets/actions/find-row/find-row.mjs index c0a433179d103..4bc2989641122 100644 --- a/components/google_sheets/actions/find-row/find-row.mjs +++ b/components/google_sheets/actions/find-row/find-row.mjs @@ -7,7 +7,7 @@ export default { key: "google_sheets-find-row", name: "Find Row", description: "Find one or more rows by a column and value. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get)", - version: "0.2.13", + version: "0.2.14", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/get-cell/get-cell.mjs b/components/google_sheets/actions/get-cell/get-cell.mjs index 47a70a50d97f6..c4104294c47fa 100644 --- a/components/google_sheets/actions/get-cell/get-cell.mjs +++ b/components/google_sheets/actions/get-cell/get-cell.mjs @@ -7,7 +7,7 @@ export default { key: "google_sheets-get-cell", name: "Get Cell", description: "Fetch the contents of a specific cell in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get)", - version: "0.1.12", + version: "0.1.13", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/get-spreadsheet-by-id/get-spreadsheet-by-id.mjs b/components/google_sheets/actions/get-spreadsheet-by-id/get-spreadsheet-by-id.mjs index abec362f30593..0bb68b9926f60 100644 --- a/components/google_sheets/actions/get-spreadsheet-by-id/get-spreadsheet-by-id.mjs +++ b/components/google_sheets/actions/get-spreadsheet-by-id/get-spreadsheet-by-id.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-get-spreadsheet-by-id", name: "Get Spreadsheet by ID", description: "Returns the spreadsheet at the given ID. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/get) for more information", - version: "0.1.11", + version: "0.1.12", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/get-values-in-range/get-values-in-range.mjs b/components/google_sheets/actions/get-values-in-range/get-values-in-range.mjs index dcfcce33eaf57..c99317f9099b0 100644 --- a/components/google_sheets/actions/get-values-in-range/get-values-in-range.mjs +++ b/components/google_sheets/actions/get-values-in-range/get-values-in-range.mjs @@ -7,7 +7,7 @@ export default { key: "google_sheets-get-values-in-range", name: "Get Values in Range", description: "Get all values or values from a range of cells using A1 notation. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get)", - version: "0.1.12", + version: "0.1.13", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/insert-anchored-note/insert-anchored-note.mjs b/components/google_sheets/actions/insert-anchored-note/insert-anchored-note.mjs index 4ff04baebf68c..9e8d1f65d331f 100644 --- a/components/google_sheets/actions/insert-anchored-note/insert-anchored-note.mjs +++ b/components/google_sheets/actions/insert-anchored-note/insert-anchored-note.mjs @@ -5,7 +5,7 @@ export default { key: "google_sheets-insert-anchored-note", name: "Insert an Anchored Note", description: "Insert a note on a spreadsheet cell. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/batchUpdate)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { app, diff --git a/components/google_sheets/actions/insert-comment/insert-comment.mjs b/components/google_sheets/actions/insert-comment/insert-comment.mjs index 25048e3f68db7..3eb41bf835f91 100644 --- a/components/google_sheets/actions/insert-comment/insert-comment.mjs +++ b/components/google_sheets/actions/insert-comment/insert-comment.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-insert-comment", name: "Insert Comment", description: "Insert a comment into a spreadsheet. [See the documentation](https://developers.google.com/drive/api/v3/reference/comments/create)", - version: "0.1.11", + version: "0.1.12", type: "action", props: { app, diff --git a/components/google_sheets/actions/list-worksheets/list-worksheets.mjs b/components/google_sheets/actions/list-worksheets/list-worksheets.mjs index 6eb6e2e4750ef..ce5819a4c4010 100644 --- a/components/google_sheets/actions/list-worksheets/list-worksheets.mjs +++ b/components/google_sheets/actions/list-worksheets/list-worksheets.mjs @@ -4,7 +4,7 @@ export default { key: "google_sheets-list-worksheets", name: "List Worksheets", description: "Get a list of all worksheets in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/get)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/update-cell/update-cell.mjs b/components/google_sheets/actions/update-cell/update-cell.mjs index 2b8ab560726b3..9cf48c7e7d08b 100644 --- a/components/google_sheets/actions/update-cell/update-cell.mjs +++ b/components/google_sheets/actions/update-cell/update-cell.mjs @@ -7,7 +7,7 @@ export default { key: "google_sheets-update-cell", name: "Update Cell", description: "Update a cell in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update)", - version: "0.1.12", + version: "0.1.13", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/update-multiple-rows/update-multiple-rows.mjs b/components/google_sheets/actions/update-multiple-rows/update-multiple-rows.mjs index f332bd89cd9b5..018d76c7e5f85 100644 --- a/components/google_sheets/actions/update-multiple-rows/update-multiple-rows.mjs +++ b/components/google_sheets/actions/update-multiple-rows/update-multiple-rows.mjs @@ -9,7 +9,7 @@ export default { key: "google_sheets-update-multiple-rows", name: "Update Multiple Rows", description: "Update multiple rows in a spreadsheet defined by a range. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update)", - version: "0.1.12", + version: "0.1.13", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/update-row/update-row.mjs b/components/google_sheets/actions/update-row/update-row.mjs index 36330cccc3f9d..415741265c470 100644 --- a/components/google_sheets/actions/update-row/update-row.mjs +++ b/components/google_sheets/actions/update-row/update-row.mjs @@ -10,7 +10,7 @@ export default { key: "google_sheets-update-row", name: "Update Row", description: "Update a row in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { googleSheets, diff --git a/components/google_sheets/actions/upsert-row/upsert-row.mjs b/components/google_sheets/actions/upsert-row/upsert-row.mjs index 5477aef4e41e0..a86c6eaa8c6e1 100644 --- a/components/google_sheets/actions/upsert-row/upsert-row.mjs +++ b/components/google_sheets/actions/upsert-row/upsert-row.mjs @@ -24,7 +24,7 @@ export default { key: "google_sheets-upsert-row", name: "Upsert Row", description: "Upsert a row of data in a Google Sheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)", - version: "0.1.14", + version: "0.1.15", type: "action", props: { googleSheets, diff --git a/components/google_sheets/google_sheets.app.mjs b/components/google_sheets/google_sheets.app.mjs index a9340b649eec8..97529a2ed542f 100644 --- a/components/google_sheets/google_sheets.app.mjs +++ b/components/google_sheets/google_sheets.app.mjs @@ -71,7 +71,7 @@ export default { }, }, worksheetIDs: { - type: "string", + type: "integer", label: "Worksheet ID", description: "Select a worksheet or provide a worksheet ID", async options({ sheetId }) { diff --git a/components/google_sheets/package.json b/components/google_sheets/package.json index 6ea2b0e9f3d36..c000d421d0880 100644 --- a/components/google_sheets/package.json +++ b/components/google_sheets/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/google_sheets", - "version": "0.8.10", + "version": "0.8.11", "description": "Pipedream Google_sheets Components", "main": "google_sheets.app.mjs", "keywords": [ diff --git a/components/google_sheets/sources/common/new-row-added.mjs b/components/google_sheets/sources/common/new-row-added.mjs index b2f7b2c78160e..c1c674d273733 100644 --- a/components/google_sheets/sources/common/new-row-added.mjs +++ b/components/google_sheets/sources/common/new-row-added.mjs @@ -16,7 +16,7 @@ export default { sheetId: c.sheetID, }), ], - type: "string[]", + type: "integer[]", label: "Worksheet ID(s)", description: "Select one or more worksheet(s), or provide an array of worksheet IDs.", }, diff --git a/components/google_sheets/sources/common/new-updates.mjs b/components/google_sheets/sources/common/new-updates.mjs index b8543d225644e..a3834c9ab74fb 100644 --- a/components/google_sheets/sources/common/new-updates.mjs +++ b/components/google_sheets/sources/common/new-updates.mjs @@ -16,7 +16,7 @@ export default { sheetId: c.sheetID, }), ], - type: "string[]", + type: "integer[]", label: "Worksheet ID(s)", description: "Select one or more worksheet(s), or provide an array of worksheet IDs.", }, diff --git a/components/google_sheets/sources/new-comment/new-comment.mjs b/components/google_sheets/sources/new-comment/new-comment.mjs index 1f96c4b59de21..48bef4d8c2e2e 100644 --- a/components/google_sheets/sources/new-comment/new-comment.mjs +++ b/components/google_sheets/sources/new-comment/new-comment.mjs @@ -6,7 +6,7 @@ export default { key: "google_sheets-new-comment", name: "New Comment (Instant)", description: "Emit new event each time a comment is added to a spreadsheet.", - version: "0.0.9", + version: "0.0.10", dedupe: "unique", type: "source", methods: { diff --git a/components/google_sheets/sources/new-row-added-polling/new-row-added-polling.mjs b/components/google_sheets/sources/new-row-added-polling/new-row-added-polling.mjs index 4e1a3c0f0eb0f..313c57171aa17 100644 --- a/components/google_sheets/sources/new-row-added-polling/new-row-added-polling.mjs +++ b/components/google_sheets/sources/new-row-added-polling/new-row-added-polling.mjs @@ -8,7 +8,7 @@ export default { key: "google_sheets-new-row-added-polling", name: "New Row Added", description: "Emit new event each time a row or rows are added to the bottom of a spreadsheet.", - version: "0.0.8", + version: "0.0.9", dedupe: "unique", type: "source", props: { diff --git a/components/google_sheets/sources/new-row-added/new-row-added.mjs b/components/google_sheets/sources/new-row-added/new-row-added.mjs index 085fb9711bf6b..3355fcd29a722 100644 --- a/components/google_sheets/sources/new-row-added/new-row-added.mjs +++ b/components/google_sheets/sources/new-row-added/new-row-added.mjs @@ -8,7 +8,7 @@ export default { key: "google_sheets-new-row-added", name: "New Row Added (Instant)", description: "Emit new event each time a row or rows are added to the bottom of a spreadsheet.", - version: "0.1.16", + version: "0.1.17", dedupe: "unique", type: "source", props: { diff --git a/components/google_sheets/sources/new-updates/new-updates.mjs b/components/google_sheets/sources/new-updates/new-updates.mjs index 48c4c97dec37a..78ab4dcabdb87 100644 --- a/components/google_sheets/sources/new-updates/new-updates.mjs +++ b/components/google_sheets/sources/new-updates/new-updates.mjs @@ -9,7 +9,7 @@ export default { type: "source", name: "New Updates (Instant)", description: "Emit new event each time a row or cell is updated in a spreadsheet.", - version: "0.2.11", + version: "0.2.12", dedupe: "unique", props: { ...httpBase.props, diff --git a/components/google_sheets/sources/new-worksheet/new-worksheet.mjs b/components/google_sheets/sources/new-worksheet/new-worksheet.mjs index 06609dc7f3e51..002fc923d357a 100644 --- a/components/google_sheets/sources/new-worksheet/new-worksheet.mjs +++ b/components/google_sheets/sources/new-worksheet/new-worksheet.mjs @@ -9,7 +9,7 @@ export default { type: "source", name: "New Worksheet (Instant)", description: "Emit new event each time a new worksheet is created in a spreadsheet.", - version: "0.1.14", + version: "0.1.15", dedupe: "unique", hooks: { ...httpBase.hooks, From 1721bbfebd2e5906e473dd92a58b6a4111e071b0 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Sat, 20 Sep 2025 22:32:15 -0400 Subject: [PATCH 43/52] Merging pull request #18393 * new components * remove console.log * versions * update --- .../create-a-text-file/create-a-text-file.mjs | 2 +- .../actions/create-folder/create-folder.mjs | 2 +- .../create-or-append-to-a-text-file.mjs | 2 +- .../create-update-share-link.mjs | 11 +++- .../delete-file-folder/delete-file-folder.mjs | 2 +- .../download-file-to-tmp.mjs | 2 +- .../get-shared-link-file.mjs | 32 ++++++++++ .../get-shared-link-metadata.mjs | 32 ++++++++++ .../list-file-folders-in-a-folder.mjs | 2 +- .../list-file-revisions.mjs | 2 +- .../list-shared-links/list-shared-links.mjs | 50 +++++++++++++++ .../move-file-folder/move-file-folder.mjs | 2 +- .../rename-file-folder/rename-file-folder.mjs | 2 +- .../actions/restore-a-file/restore-a-file.mjs | 2 +- .../search-files-folders.mjs | 2 +- .../actions/upload-file/upload-file.mjs | 2 +- .../upload-multiple-files.mjs | 2 +- components/dropbox/common/consts.mjs | 3 - components/dropbox/dropbox.app.mjs | 61 ++++++++++++++++++- components/dropbox/package.json | 2 +- .../sources/all-updates/all-updates.mjs | 2 +- .../dropbox/sources/new-file/new-file.mjs | 2 +- .../dropbox/sources/new-folder/new-folder.mjs | 2 +- 23 files changed, 200 insertions(+), 23 deletions(-) create mode 100644 components/dropbox/actions/get-shared-link-file/get-shared-link-file.mjs create mode 100644 components/dropbox/actions/get-shared-link-metadata/get-shared-link-metadata.mjs create mode 100644 components/dropbox/actions/list-shared-links/list-shared-links.mjs diff --git a/components/dropbox/actions/create-a-text-file/create-a-text-file.mjs b/components/dropbox/actions/create-a-text-file/create-a-text-file.mjs index e46715b168958..951a896c9b3dd 100644 --- a/components/dropbox/actions/create-a-text-file/create-a-text-file.mjs +++ b/components/dropbox/actions/create-a-text-file/create-a-text-file.mjs @@ -4,7 +4,7 @@ export default { name: "Create a Text File", description: "Creates a brand new text file from plain text content you specify. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)", key: "dropbox-create-a-text-file", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/create-folder/create-folder.mjs b/components/dropbox/actions/create-folder/create-folder.mjs index 289b9a040fbc2..e92451db9a631 100644 --- a/components/dropbox/actions/create-folder/create-folder.mjs +++ b/components/dropbox/actions/create-folder/create-folder.mjs @@ -4,7 +4,7 @@ export default { name: "Create folder", description: "Create a Folder. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesCreateFolderV2__anchor)", key: "dropbox-create-folder", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/create-or-append-to-a-text-file/create-or-append-to-a-text-file.mjs b/components/dropbox/actions/create-or-append-to-a-text-file/create-or-append-to-a-text-file.mjs index 5a65d54eddaf2..48fca85804eb3 100644 --- a/components/dropbox/actions/create-or-append-to-a-text-file/create-or-append-to-a-text-file.mjs +++ b/components/dropbox/actions/create-or-append-to-a-text-file/create-or-append-to-a-text-file.mjs @@ -4,7 +4,7 @@ export default { name: "Create or Append to a Text File", description: "Adds a new line to an existing text file, or creates a file if it doesn't exist. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)", key: "dropbox-create-or-append-to-a-text-file", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/create-update-share-link/create-update-share-link.mjs b/components/dropbox/actions/create-update-share-link/create-update-share-link.mjs index ba83351f5e9ee..4656f0c91cbcd 100644 --- a/components/dropbox/actions/create-update-share-link/create-update-share-link.mjs +++ b/components/dropbox/actions/create-update-share-link/create-update-share-link.mjs @@ -5,7 +5,7 @@ export default { name: "Create/Update a Share Link", description: "Creates or updates a public share link to the file or folder (It allows you to share the file or folder with anyone). [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#sharingCreateSharedLinkWithSettings__anchor)", key: "dropbox-create-update-share-link", - version: "0.0.11", + version: "0.0.12", type: "action", props: { ...common.props, @@ -66,6 +66,13 @@ export default { optional: true, options: consts.CREATE_SHARED_LINK_ACCESS_OPTIONS, }; + props.audience = { + type: "string", + label: "Audience", + description: "The audience for the shared link", + optional: true, + options: consts.CREATE_SHARED_LINK_AUDIENCE_OPTIONS, + }; } return props; @@ -84,6 +91,7 @@ export default { linkPassword, expires, access, + audience, } = this; const accountType = await this.getCurrentAccount(); @@ -107,6 +115,7 @@ export default { expires, access, allow_download: allowDownload, + audience, }, }); $.export("$summary", `Shared link for "${path?.label || path}" successfully created`); diff --git a/components/dropbox/actions/delete-file-folder/delete-file-folder.mjs b/components/dropbox/actions/delete-file-folder/delete-file-folder.mjs index 9f145826ed36e..f255cf802675f 100644 --- a/components/dropbox/actions/delete-file-folder/delete-file-folder.mjs +++ b/components/dropbox/actions/delete-file-folder/delete-file-folder.mjs @@ -4,7 +4,7 @@ export default { name: "Delete a File/Folder", description: "Permanently removes a file/folder from the server. [See documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesDeleteV2__anchor)", key: "dropbox-delete-file-folder", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/download-file-to-tmp/download-file-to-tmp.mjs b/components/dropbox/actions/download-file-to-tmp/download-file-to-tmp.mjs index dd0c327998062..f43d5c52c6cff 100644 --- a/components/dropbox/actions/download-file-to-tmp/download-file-to-tmp.mjs +++ b/components/dropbox/actions/download-file-to-tmp/download-file-to-tmp.mjs @@ -9,7 +9,7 @@ export default { name: "Download File to TMP", description: "Download a specific file to the temporary directory. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesDownload__anchor).", key: "dropbox-download-file-to-tmp", - version: "0.0.8", + version: "0.0.9", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/get-shared-link-file/get-shared-link-file.mjs b/components/dropbox/actions/get-shared-link-file/get-shared-link-file.mjs new file mode 100644 index 0000000000000..11044b1234cd9 --- /dev/null +++ b/components/dropbox/actions/get-shared-link-file/get-shared-link-file.mjs @@ -0,0 +1,32 @@ +import dropbox from "../../dropbox.app.mjs"; + +export default { + name: "Get Shared Link File", + description: "Get a file from a shared link. [See the documentation](https://www.dropbox.com/developers/documentation/http/documentation#sharing-get_shared_link_file)", + key: "dropbox-get-shared-link-file", + version: "0.0.1", + type: "action", + props: { + dropbox, + sharedLinkUrl: { + propDefinition: [ + dropbox, + "sharedLinkUrl", + ], + }, + linkPassword: { + propDefinition: [ + dropbox, + "linkPassword", + ], + }, + }, + async run({ $ }) { + const { result } = await this.dropbox.getSharedLinkFile({ + url: this.sharedLinkUrl, + link_password: this.linkPassword, + }); + $.export("$summary", "Successfully retrieved shared link file"); + return result; + }, +}; diff --git a/components/dropbox/actions/get-shared-link-metadata/get-shared-link-metadata.mjs b/components/dropbox/actions/get-shared-link-metadata/get-shared-link-metadata.mjs new file mode 100644 index 0000000000000..486b256e0f86b --- /dev/null +++ b/components/dropbox/actions/get-shared-link-metadata/get-shared-link-metadata.mjs @@ -0,0 +1,32 @@ +import dropbox from "../../dropbox.app.mjs"; + +export default { + name: "Get Shared Link Metadata", + description: "Retrieves the shared link metadata for a given shared link. [See the documentation](https://www.dropbox.com/developers/documentation/http/documentation#sharing-get_shared_link_metadata)", + key: "dropbox-get-shared-link-metadata", + version: "0.0.1", + type: "action", + props: { + dropbox, + sharedLinkUrl: { + propDefinition: [ + dropbox, + "sharedLinkUrl", + ], + }, + linkPassword: { + propDefinition: [ + dropbox, + "linkPassword", + ], + }, + }, + async run({ $ }) { + const { result } = await this.dropbox.getSharedLinkMetadata({ + url: this.sharedLinkUrl, + link_password: this.linkPassword, + }); + $.export("$summary", "Successfully retrieved shared link metadata"); + return result; + }, +}; diff --git a/components/dropbox/actions/list-file-folders-in-a-folder/list-file-folders-in-a-folder.mjs b/components/dropbox/actions/list-file-folders-in-a-folder/list-file-folders-in-a-folder.mjs index dbccae8d5ea29..b64d1d92b3fcd 100644 --- a/components/dropbox/actions/list-file-folders-in-a-folder/list-file-folders-in-a-folder.mjs +++ b/components/dropbox/actions/list-file-folders-in-a-folder/list-file-folders-in-a-folder.mjs @@ -4,7 +4,7 @@ export default { name: "List All Files/Subfolders in a Folder", description: "Retrieves a list of files or subfolders in a specified folder [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesListFolder__anchor)", key: "dropbox-list-file-folders-in-a-folder", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/list-file-revisions/list-file-revisions.mjs b/components/dropbox/actions/list-file-revisions/list-file-revisions.mjs index 84e7257ba8027..26a6fe87ada33 100644 --- a/components/dropbox/actions/list-file-revisions/list-file-revisions.mjs +++ b/components/dropbox/actions/list-file-revisions/list-file-revisions.mjs @@ -5,7 +5,7 @@ export default { name: "List File Revisions", description: "Retrieves a list of file revisions needed to recover previous content. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesListRevisions__anchor)", key: "dropbox-list-file-revisions", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/list-shared-links/list-shared-links.mjs b/components/dropbox/actions/list-shared-links/list-shared-links.mjs new file mode 100644 index 0000000000000..e51917b2215de --- /dev/null +++ b/components/dropbox/actions/list-shared-links/list-shared-links.mjs @@ -0,0 +1,50 @@ +import dropbox from "../../dropbox.app.mjs"; + +export default { + key: "dropbox-list-shared-links", + name: "List Shared Links", + description: "Retrieves a list of shared links for a given path. [See the documentation](https://www.dropbox.com/developers/documentation/http/documentation#sharing-list_shared_links)", + version: "0.0.1", + type: "action", + props: { + dropbox, + path: { + propDefinition: [ + dropbox, + "path", + () => ({ + initialOptions: [], + filter: ({ metadata: { metadata: { [".tag"]: type } } }) => [ + "file", + "folder", + ].includes(type), + }), + ], + optional: true, + description: "Type the file or folder name to search for it in the user's Dropbox", + }, + }, + async run({ $ }) { + const sharedLinks = []; + let hasMore; + const args = { + path: this.path?.value || this.path, + }; + + do { + const { + result: { + links, cursor, has_more, + }, + } = await this.dropbox.listSharedLinks(args); + sharedLinks.push(...links); + args.cursor = cursor; + hasMore = has_more; + } while (hasMore); + + $.export("$summary", `Successfully retrieved ${sharedLinks.length} shared link${sharedLinks.length === 1 + ? "" + : "s"}.`); + return sharedLinks; + }, +}; diff --git a/components/dropbox/actions/move-file-folder/move-file-folder.mjs b/components/dropbox/actions/move-file-folder/move-file-folder.mjs index 5dfb2422b2cb2..e79c25e419c4a 100644 --- a/components/dropbox/actions/move-file-folder/move-file-folder.mjs +++ b/components/dropbox/actions/move-file-folder/move-file-folder.mjs @@ -4,7 +4,7 @@ export default { name: "Move a File/Folder", description: "Moves a file or folder to a different location in the user's Dropbox [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesMoveV2__anchor)", key: "dropbox-move-file-folder", - version: "0.0.12", + version: "0.0.13", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/rename-file-folder/rename-file-folder.mjs b/components/dropbox/actions/rename-file-folder/rename-file-folder.mjs index 49b15eb31a2d1..ee200686863dd 100644 --- a/components/dropbox/actions/rename-file-folder/rename-file-folder.mjs +++ b/components/dropbox/actions/rename-file-folder/rename-file-folder.mjs @@ -4,7 +4,7 @@ export default { name: "Rename a File/Folder", description: "Renames a file or folder in the user's Dropbox [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesMoveV2__anchor)", key: "dropbox-rename-file-folder", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/restore-a-file/restore-a-file.mjs b/components/dropbox/actions/restore-a-file/restore-a-file.mjs index ff883ba865881..8a7713d499f98 100644 --- a/components/dropbox/actions/restore-a-file/restore-a-file.mjs +++ b/components/dropbox/actions/restore-a-file/restore-a-file.mjs @@ -4,7 +4,7 @@ export default { name: "Restore a File", description: "Restores a previous file version. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesRestore__anchor)", key: "dropbox-restore-a-file", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/search-files-folders/search-files-folders.mjs b/components/dropbox/actions/search-files-folders/search-files-folders.mjs index 37b32ed1c4723..de05a63b75f64 100644 --- a/components/dropbox/actions/search-files-folders/search-files-folders.mjs +++ b/components/dropbox/actions/search-files-folders/search-files-folders.mjs @@ -6,7 +6,7 @@ export default { name: "Search files and folders", description: "Searches for files and folders by name. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesSearchV2__anchor)", key: "dropbox-search-files-folders", - version: "0.0.11", + version: "0.0.12", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/upload-file/upload-file.mjs b/components/dropbox/actions/upload-file/upload-file.mjs index 748bd976b3e93..6e66a8aa0ff38 100644 --- a/components/dropbox/actions/upload-file/upload-file.mjs +++ b/components/dropbox/actions/upload-file/upload-file.mjs @@ -6,7 +6,7 @@ export default { name: "Upload a File", description: "Uploads a file to a selected folder. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)", key: "dropbox-upload-file", - version: "1.0.1", + version: "1.0.2", type: "action", props: { dropbox, diff --git a/components/dropbox/actions/upload-multiple-files/upload-multiple-files.mjs b/components/dropbox/actions/upload-multiple-files/upload-multiple-files.mjs index 04ea58f50da97..1993adb8828af 100644 --- a/components/dropbox/actions/upload-multiple-files/upload-multiple-files.mjs +++ b/components/dropbox/actions/upload-multiple-files/upload-multiple-files.mjs @@ -8,7 +8,7 @@ export default { name: "Upload Multiple Files", description: "Uploads multiple file to a selected folder. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)", key: "dropbox-upload-multiple-files", - version: "1.0.1", + version: "1.0.2", type: "action", props: { dropbox, diff --git a/components/dropbox/common/consts.mjs b/components/dropbox/common/consts.mjs index 0edd17b699b4f..3e16c214b14fb 100644 --- a/components/dropbox/common/consts.mjs +++ b/components/dropbox/common/consts.mjs @@ -28,9 +28,6 @@ export default { "public", "team", "no_one", - "password", - "members", - "other", ], CREATE_SHARED_LINK_ACCESS_OPTIONS: [ { diff --git a/components/dropbox/dropbox.app.mjs b/components/dropbox/dropbox.app.mjs index 21271a7e83933..ee5e40a85068a 100644 --- a/components/dropbox/dropbox.app.mjs +++ b/components/dropbox/dropbox.app.mjs @@ -96,6 +96,38 @@ export default { } }, }, + sharedLinkUrl: { + type: "string", + label: "Shared Link URL", + description: "The URL of a shared link", + async options({ prevContext }) { + const { + result: { + links, cursor, + }, + } = await this.listSharedLinks({ + cursor: prevContext?.cursor, + }); + const options = links?.map(({ + url: value, name: label, + }) => ({ + value, + label: `${label} - ${value}`, + })) || []; + return { + options, + context: { + cursor, + }, + }; + }, + }, + linkPassword: { + type: "string", + label: "Link Password", + description: "The password required to access the shared link", + optional: true, + }, fileRevision: { type: "string", label: "Revision", @@ -363,11 +395,12 @@ export default { const links = await dpx.sharingListSharedLinks({ path: args.path, }); - if (links.result?.links.length > 0) { + const link = links.result?.links.find((l) => l.path_lower === args.path); + if (link) { return await dpx.sharingModifySharedLinkSettings({ ...args, path: undefined, - url: links.result?.links[0].url, + url: link.url, remove_expiration: isEmpty(args.remove_expiration) ? false : args.remove_expiration, @@ -382,6 +415,30 @@ export default { this.normalizeError(err); } }, + async listSharedLinks(args) { + try { + const dpx = await this.sdk(); + return await dpx.sharingListSharedLinks(args); + } catch (err) { + this.normalizeError(err); + } + }, + async getSharedLinkMetadata(args) { + try { + const dpx = await this.sdk(); + return await dpx.sharingGetSharedLinkMetadata(args); + } catch (err) { + this.normalizeError(err); + } + }, + async getSharedLinkFile(args) { + try { + const dpx = await this.sdk(); + return await dpx.sharingGetSharedLinkFile(args); + } catch (err) { + this.normalizeError(err); + } + }, async deleteFileFolder(args) { try { const dpx = await this.sdk(); diff --git a/components/dropbox/package.json b/components/dropbox/package.json index 76a49336c1dcf..7d3ad1ec7817e 100644 --- a/components/dropbox/package.json +++ b/components/dropbox/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/dropbox", - "version": "1.0.1", + "version": "1.1.0", "description": "Pipedream Dropbox Components", "main": "dropbox.app.mjs", "keywords": [ diff --git a/components/dropbox/sources/all-updates/all-updates.mjs b/components/dropbox/sources/all-updates/all-updates.mjs index 1405f9b083d75..520902690631d 100644 --- a/components/dropbox/sources/all-updates/all-updates.mjs +++ b/components/dropbox/sources/all-updates/all-updates.mjs @@ -7,7 +7,7 @@ export default { type: "source", key: "dropbox-all-updates", name: "New or Modified File or Folder", - version: "0.0.18", + version: "0.0.19", description: "Emit new event when a file or folder is added or modified. Make sure the number of files/folders in the watched folder does not exceed 4000.", props: { ...common.props, diff --git a/components/dropbox/sources/new-file/new-file.mjs b/components/dropbox/sources/new-file/new-file.mjs index 8d45236bf468f..edc10c61d4006 100644 --- a/components/dropbox/sources/new-file/new-file.mjs +++ b/components/dropbox/sources/new-file/new-file.mjs @@ -7,7 +7,7 @@ export default { type: "source", key: "dropbox-new-file", name: "New File", - version: "0.0.19", + version: "0.0.20", description: "Emit new event when a new file is added to your account or a specific folder. Make sure the number of files/folders in the watched folder does not exceed 4000.", props: { ...common.props, diff --git a/components/dropbox/sources/new-folder/new-folder.mjs b/components/dropbox/sources/new-folder/new-folder.mjs index 39a2cc9ebd0c2..8744c60e0bf0d 100644 --- a/components/dropbox/sources/new-folder/new-folder.mjs +++ b/components/dropbox/sources/new-folder/new-folder.mjs @@ -7,7 +7,7 @@ export default { type: "source", key: "dropbox-new-folder", name: "New Folder", - version: "0.0.18", + version: "0.0.19", description: "Emit new event when a new folder is created. Make sure the number of files/folders in the watched folder does not exceed 4000.", hooks: { async activate() { From 0185460d261fdc4c04ebbba7b215a146d18af997 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Sat, 20 Sep 2025 22:45:29 -0400 Subject: [PATCH 44/52] Merging pull request #18408 * 403 error message * versions * update --- .../actions/add-label-to-email/add-label-to-email.mjs | 2 +- .../actions/approve-workflow/approve-workflow.mjs | 2 +- .../actions/create-contact/create-contact.mjs | 2 +- .../actions/create-draft-email/create-draft-email.mjs | 2 +- .../download-attachment/download-attachment.mjs | 2 +- .../actions/find-contacts/find-contacts.mjs | 2 +- .../actions/find-email/find-email.mjs | 2 +- .../find-shared-folder-email.mjs | 2 +- .../actions/list-contacts/list-contacts.mjs | 2 +- .../actions/list-folders/list-folders.mjs | 2 +- .../actions/list-labels/list-labels.mjs | 2 +- .../move-email-to-folder/move-email-to-folder.mjs | 2 +- .../remove-label-from-email.mjs | 2 +- .../actions/reply-to-email/reply-to-email.mjs | 2 +- .../actions/send-email/send-email.mjs | 2 +- .../actions/update-contact/update-contact.mjs | 2 +- components/microsoft_outlook/microsoft_outlook.app.mjs | 10 ++++++++-- components/microsoft_outlook/package.json | 2 +- .../new-attachment-received.mjs | 2 +- .../sources/new-contact/new-contact.mjs | 2 +- .../new-email-in-shared-folder.mjs | 2 +- .../microsoft_outlook/sources/new-email/new-email.mjs | 2 +- 22 files changed, 29 insertions(+), 23 deletions(-) diff --git a/components/microsoft_outlook/actions/add-label-to-email/add-label-to-email.mjs b/components/microsoft_outlook/actions/add-label-to-email/add-label-to-email.mjs index 1b5388d57aca4..98ba1f2fe901e 100644 --- a/components/microsoft_outlook/actions/add-label-to-email/add-label-to-email.mjs +++ b/components/microsoft_outlook/actions/add-label-to-email/add-label-to-email.mjs @@ -5,7 +5,7 @@ export default { key: "microsoft_outlook-add-label-to-email", name: "Add Label to Email", description: "Adds a label/category to an email in Microsoft Outlook. [See the documentation](https://learn.microsoft.com/en-us/graph/api/message-update)", - version: "0.0.9", + version: "0.0.10", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/approve-workflow/approve-workflow.mjs b/components/microsoft_outlook/actions/approve-workflow/approve-workflow.mjs index 33ffd0b4f1d5b..78e5f1519bd02 100644 --- a/components/microsoft_outlook/actions/approve-workflow/approve-workflow.mjs +++ b/components/microsoft_outlook/actions/approve-workflow/approve-workflow.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-approve-workflow", name: "Approve Workflow", description: "Suspend the workflow until approved by email. [See the documentation](https://pipedream.com/docs/code/nodejs/rerun#flowsuspend)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/create-contact/create-contact.mjs b/components/microsoft_outlook/actions/create-contact/create-contact.mjs index 2cc43a2379f7b..461788aac20ee 100644 --- a/components/microsoft_outlook/actions/create-contact/create-contact.mjs +++ b/components/microsoft_outlook/actions/create-contact/create-contact.mjs @@ -3,7 +3,7 @@ import microsoftOutlook from "../../microsoft_outlook.app.mjs"; export default { type: "action", key: "microsoft_outlook-create-contact", - version: "0.0.16", + version: "0.0.17", name: "Create Contact", description: "Add a contact to the root Contacts folder, [See the documentation](https://docs.microsoft.com/en-us/graph/api/user-post-contacts)", props: { diff --git a/components/microsoft_outlook/actions/create-draft-email/create-draft-email.mjs b/components/microsoft_outlook/actions/create-draft-email/create-draft-email.mjs index e6a24ae3624fb..980a76541c272 100644 --- a/components/microsoft_outlook/actions/create-draft-email/create-draft-email.mjs +++ b/components/microsoft_outlook/actions/create-draft-email/create-draft-email.mjs @@ -4,7 +4,7 @@ import microsoftOutlook from "../../microsoft_outlook.app.mjs"; export default { type: "action", key: "microsoft_outlook-create-draft-email", - version: "0.0.16", + version: "0.0.17", name: "Create Draft Email", description: "Create a draft email, [See the documentation](https://docs.microsoft.com/en-us/graph/api/user-post-messages)", props: { diff --git a/components/microsoft_outlook/actions/download-attachment/download-attachment.mjs b/components/microsoft_outlook/actions/download-attachment/download-attachment.mjs index 69521d0e54a7e..a81058b67fbf7 100644 --- a/components/microsoft_outlook/actions/download-attachment/download-attachment.mjs +++ b/components/microsoft_outlook/actions/download-attachment/download-attachment.mjs @@ -6,7 +6,7 @@ export default { key: "microsoft_outlook-download-attachment", name: "Download Attachment", description: "Downloads an attachment to the /tmp directory. [See the documentation](https://learn.microsoft.com/en-us/graph/api/attachment-get?view=graph-rest-1.0&tabs=http)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/find-contacts/find-contacts.mjs b/components/microsoft_outlook/actions/find-contacts/find-contacts.mjs index 9a1dcf3b2c392..77f5248e4fe99 100644 --- a/components/microsoft_outlook/actions/find-contacts/find-contacts.mjs +++ b/components/microsoft_outlook/actions/find-contacts/find-contacts.mjs @@ -3,7 +3,7 @@ import microsoftOutlook from "../../microsoft_outlook.app.mjs"; export default { type: "action", key: "microsoft_outlook-find-contacts", - version: "0.0.16", + version: "0.0.17", name: "Find Contacts", description: "Finds contacts with the given search string. [See the documentation](https://docs.microsoft.com/en-us/graph/api/user-list-contacts)", props: { diff --git a/components/microsoft_outlook/actions/find-email/find-email.mjs b/components/microsoft_outlook/actions/find-email/find-email.mjs index aeea67144769f..9e3c8355dde76 100644 --- a/components/microsoft_outlook/actions/find-email/find-email.mjs +++ b/components/microsoft_outlook/actions/find-email/find-email.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-find-email", name: "Find Email", description: "Search for an email in Microsoft Outlook. [See the documentation](https://learn.microsoft.com/en-us/graph/api/user-list-messages)", - version: "0.0.10", + version: "0.0.11", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/find-shared-folder-email/find-shared-folder-email.mjs b/components/microsoft_outlook/actions/find-shared-folder-email/find-shared-folder-email.mjs index 2c949c68127a4..4efa91d26b6b5 100644 --- a/components/microsoft_outlook/actions/find-shared-folder-email/find-shared-folder-email.mjs +++ b/components/microsoft_outlook/actions/find-shared-folder-email/find-shared-folder-email.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-find-shared-folder-email", name: "Find Shared Folder Email", description: "Search for an email in a shared folder in Microsoft Outlook. [See the documentation](https://learn.microsoft.com/en-us/graph/api/user-list-messages)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/list-contacts/list-contacts.mjs b/components/microsoft_outlook/actions/list-contacts/list-contacts.mjs index b3afca19c79af..02591eeb6310c 100644 --- a/components/microsoft_outlook/actions/list-contacts/list-contacts.mjs +++ b/components/microsoft_outlook/actions/list-contacts/list-contacts.mjs @@ -3,7 +3,7 @@ import microsoftOutlook from "../../microsoft_outlook.app.mjs"; export default { type: "action", key: "microsoft_outlook-list-contacts", - version: "0.0.16", + version: "0.0.17", name: "List Contacts", description: "Get a contact collection from the default contacts folder, [See the documentation](https://docs.microsoft.com/en-us/graph/api/user-list-contacts)", props: { diff --git a/components/microsoft_outlook/actions/list-folders/list-folders.mjs b/components/microsoft_outlook/actions/list-folders/list-folders.mjs index 20deaa00a752f..156a5f291ae50 100644 --- a/components/microsoft_outlook/actions/list-folders/list-folders.mjs +++ b/components/microsoft_outlook/actions/list-folders/list-folders.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-list-folders", name: "List Folders", description: "Retrieves a list of all folders in Microsoft Outlook. [See the documentation](https://learn.microsoft.com/en-us/graph/api/user-list-mailfolders)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/list-labels/list-labels.mjs b/components/microsoft_outlook/actions/list-labels/list-labels.mjs index 9810d07bb1e1c..2ba3bff5dfa21 100644 --- a/components/microsoft_outlook/actions/list-labels/list-labels.mjs +++ b/components/microsoft_outlook/actions/list-labels/list-labels.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-list-labels", name: "List Labels", description: "Get all the labels/categories that have been defined for a user. [See the documentation](https://learn.microsoft.com/en-us/graph/api/outlookuser-list-mastercategories)", - version: "0.0.9", + version: "0.0.10", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/move-email-to-folder/move-email-to-folder.mjs b/components/microsoft_outlook/actions/move-email-to-folder/move-email-to-folder.mjs index 43d75cda78ff5..027773ac6b688 100644 --- a/components/microsoft_outlook/actions/move-email-to-folder/move-email-to-folder.mjs +++ b/components/microsoft_outlook/actions/move-email-to-folder/move-email-to-folder.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-move-email-to-folder", name: "Move Email to Folder", description: "Moves an email to the specified folder in Microsoft Outlook. [See the documentation](https://learn.microsoft.com/en-us/graph/api/message-move)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/remove-label-from-email/remove-label-from-email.mjs b/components/microsoft_outlook/actions/remove-label-from-email/remove-label-from-email.mjs index 5cb184df4ba10..4fdce895af1c7 100644 --- a/components/microsoft_outlook/actions/remove-label-from-email/remove-label-from-email.mjs +++ b/components/microsoft_outlook/actions/remove-label-from-email/remove-label-from-email.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-remove-label-from-email", name: "Remove Label from Email", description: "Removes a label/category from an email in Microsoft Outlook. [See the documentation](https://learn.microsoft.com/en-us/graph/api/message-update)", - version: "0.0.9", + version: "0.0.10", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/reply-to-email/reply-to-email.mjs b/components/microsoft_outlook/actions/reply-to-email/reply-to-email.mjs index e44b02e4e4ebf..18f20d16ad0ec 100644 --- a/components/microsoft_outlook/actions/reply-to-email/reply-to-email.mjs +++ b/components/microsoft_outlook/actions/reply-to-email/reply-to-email.mjs @@ -4,7 +4,7 @@ export default { key: "microsoft_outlook-reply-to-email", name: "Reply to Email", description: "Reply to an email in Microsoft Outlook. [See the documentation](https://learn.microsoft.com/en-us/graph/api/message-reply)", - version: "0.0.6", + version: "0.0.7", type: "action", props: { microsoftOutlook, diff --git a/components/microsoft_outlook/actions/send-email/send-email.mjs b/components/microsoft_outlook/actions/send-email/send-email.mjs index 46ce0a5f3e9fa..505a34a327069 100644 --- a/components/microsoft_outlook/actions/send-email/send-email.mjs +++ b/components/microsoft_outlook/actions/send-email/send-email.mjs @@ -4,7 +4,7 @@ import microsoftOutlook from "../../microsoft_outlook.app.mjs"; export default { type: "action", key: "microsoft_outlook-send-email", - version: "0.0.17", + version: "0.0.18", name: "Send Email", description: "Send an email to one or multiple recipients, [See the docs](https://docs.microsoft.com/en-us/graph/api/user-sendmail)", props: { diff --git a/components/microsoft_outlook/actions/update-contact/update-contact.mjs b/components/microsoft_outlook/actions/update-contact/update-contact.mjs index 09967ffdba29e..28f5240a5b245 100644 --- a/components/microsoft_outlook/actions/update-contact/update-contact.mjs +++ b/components/microsoft_outlook/actions/update-contact/update-contact.mjs @@ -3,7 +3,7 @@ import microsoftOutlook from "../../microsoft_outlook.app.mjs"; export default { type: "action", key: "microsoft_outlook-update-contact", - version: "0.0.16", + version: "0.0.17", name: "Update Contact", description: "Update an existing contact, [See the docs](https://docs.microsoft.com/en-us/graph/api/user-post-contacts)", props: { diff --git a/components/microsoft_outlook/microsoft_outlook.app.mjs b/components/microsoft_outlook/microsoft_outlook.app.mjs index 44dd6fb7f8815..1ea4149372d8b 100644 --- a/components/microsoft_outlook/microsoft_outlook.app.mjs +++ b/components/microsoft_outlook/microsoft_outlook.app.mjs @@ -276,8 +276,14 @@ export default { headers: this._getHeaders(headers), ...otherConfig, }; - - return axios($ ?? this, config); + try { + return await axios($ ?? this, config); + } catch (error) { + if (error?.response?.status === 403) { + throw new Error("Insufficient permissions. Please verify that your Microsoft account has the necessary permissions to perform this operation."); + } + throw error; + } }, async createHook({ ...args } = {}) { const response = await this._makeRequest({ diff --git a/components/microsoft_outlook/package.json b/components/microsoft_outlook/package.json index 513a7d2754097..43afc41c2140a 100644 --- a/components/microsoft_outlook/package.json +++ b/components/microsoft_outlook/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/microsoft_outlook", - "version": "1.7.0", + "version": "1.7.1", "description": "Pipedream Microsoft Outlook Components", "main": "microsoft_outlook.app.mjs", "keywords": [ diff --git a/components/microsoft_outlook/sources/new-attachment-received/new-attachment-received.mjs b/components/microsoft_outlook/sources/new-attachment-received/new-attachment-received.mjs index e15bc37c27441..1192236a7a7fb 100644 --- a/components/microsoft_outlook/sources/new-attachment-received/new-attachment-received.mjs +++ b/components/microsoft_outlook/sources/new-attachment-received/new-attachment-received.mjs @@ -6,7 +6,7 @@ export default { key: "microsoft_outlook-new-attachment-received", name: "New Attachment Received (Instant)", description: "Emit new event when a new email containing one or more attachments arrives in a specified Microsoft Outlook folder.", - version: "0.1.0", + version: "0.1.1", type: "source", dedupe: "unique", props: { diff --git a/components/microsoft_outlook/sources/new-contact/new-contact.mjs b/components/microsoft_outlook/sources/new-contact/new-contact.mjs index 1f0a51c3f2991..60a9a9b693c10 100644 --- a/components/microsoft_outlook/sources/new-contact/new-contact.mjs +++ b/components/microsoft_outlook/sources/new-contact/new-contact.mjs @@ -5,7 +5,7 @@ export default { key: "microsoft_outlook-new-contact", name: "New Contact Event (Instant)", description: "Emit new event when a new Contact is created", - version: "0.0.17", + version: "0.0.18", type: "source", hooks: { ...common.hooks, diff --git a/components/microsoft_outlook/sources/new-email-in-shared-folder/new-email-in-shared-folder.mjs b/components/microsoft_outlook/sources/new-email-in-shared-folder/new-email-in-shared-folder.mjs index 097fbb229cc42..9198a10bf5f2f 100644 --- a/components/microsoft_outlook/sources/new-email-in-shared-folder/new-email-in-shared-folder.mjs +++ b/components/microsoft_outlook/sources/new-email-in-shared-folder/new-email-in-shared-folder.mjs @@ -6,7 +6,7 @@ export default { key: "microsoft_outlook-new-email-in-shared-folder", name: "New Email in Shared Folder Event", description: "Emit new event when an email is received in specified shared folders.", - version: "0.0.1", + version: "0.0.2", type: "source", dedupe: "unique", props: { diff --git a/components/microsoft_outlook/sources/new-email/new-email.mjs b/components/microsoft_outlook/sources/new-email/new-email.mjs index ba04a634d1781..a58c9bfd79985 100644 --- a/components/microsoft_outlook/sources/new-email/new-email.mjs +++ b/components/microsoft_outlook/sources/new-email/new-email.mjs @@ -7,7 +7,7 @@ export default { key: "microsoft_outlook-new-email", name: "New Email Event (Instant)", description: "Emit new event when an email is received in specified folders.", - version: "0.1.2", + version: "0.1.3", type: "source", dedupe: "unique", methods: { From 72c48a3b1731aca2d0cb0f2fcc8ee73a49089481 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Sun, 21 Sep 2025 01:50:46 -0400 Subject: [PATCH 45/52] Merging pull request #18419 --- components/azure_devops/azure_devops.app.mjs | 11 +++++++++-- components/azure_devops/package.json | 2 +- .../azure_devops/sources/new-event/new-event.mjs | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/components/azure_devops/azure_devops.app.mjs b/components/azure_devops/azure_devops.app.mjs index 69c475db2beec..c9cb72daba350 100644 --- a/components/azure_devops/azure_devops.app.mjs +++ b/components/azure_devops/azure_devops.app.mjs @@ -51,7 +51,7 @@ export default { _personalAccessToken() { return this.$auth.personal_access_token; }, - _makeRequest(args = {}) { + async _makeRequest(args = {}) { const { $ = this, url, @@ -68,7 +68,14 @@ export default { ? "&" : "?"; config.url += `api-version=${API_VERSION}`; - return axios($, config); + try { + return await axios($, config); + } catch (error) { + if (error.response?.status === 401 && !useOAuth) { + throw new ConfigurationError("Azure DevOps Personal Access Token is required for this operation. Please verify that your personal access token is correct."); + } + throw error; + } }, async listAccounts(args = {}) { const { value } = await this._makeRequest({ diff --git a/components/azure_devops/package.json b/components/azure_devops/package.json index 20c8438baac53..5754665d6f71c 100644 --- a/components/azure_devops/package.json +++ b/components/azure_devops/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/azure_devops", - "version": "0.1.0", + "version": "0.1.1", "description": "Pipedream Azure DevOps Components", "main": "azure_devops.app.mjs", "keywords": [ diff --git a/components/azure_devops/sources/new-event/new-event.mjs b/components/azure_devops/sources/new-event/new-event.mjs index adf24e764181b..1bc47db6b0c9a 100644 --- a/components/azure_devops/sources/new-event/new-event.mjs +++ b/components/azure_devops/sources/new-event/new-event.mjs @@ -2,7 +2,7 @@ import azureDevops from "../../azure_devops.app.mjs"; export default { name: "New Event (Instant)", - version: "0.0.3", + version: "0.0.4", key: "azure_devops-new-event", description: "Emit new event for the specified event type.", type: "source", From 8b4f66c664756598f905a519e3bb0682c975302f Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sun, 21 Sep 2025 13:40:09 -0700 Subject: [PATCH 46/52] Changes per PR Review --- components/leonardo_ai/README.md | 20 +---- .../actions/generate-image/generate-image.mjs | 53 ++++++------ .../generate-motion/generate-motion.mjs | 28 +++---- .../actions/unzoom-image/unzoom-image.mjs | 7 +- .../actions/upload-image/upload-image.mjs | 58 +++++++------ .../actions/upscale-image/upscale-image.mjs | 7 +- components/leonardo_ai/leonardo_ai.app.mjs | 82 +++++-------------- components/leonardo_ai/package.json | 22 ++--- 8 files changed, 102 insertions(+), 175 deletions(-) diff --git a/components/leonardo_ai/README.md b/components/leonardo_ai/README.md index 5443cf5ff1a06..d932d205f2e6e 100644 --- a/components/leonardo_ai/README.md +++ b/components/leonardo_ai/README.md @@ -2,15 +2,6 @@ [Leonardo AI](https://leonardo.ai) is an AI-powered image generation platform that allows you to create stunning images, videos, and 3D models using advanced machine learning models. -## Authentication - -To use this component, you'll need to: - -1. Sign up for a Leonardo AI account at [leonardo.ai](https://leonardo.ai) -2. Navigate to the API section in your account settings -3. Create an API key -4. Use this API key when connecting the Leonardo AI app in Pipedream - ## Actions ### Generate Image @@ -42,11 +33,6 @@ Creates unzoom variations of existing images, expanding the scene beyond the ori ### Upload Image Uploads images to Leonardo AI for use in generations and variations. -**Key Features:** -- Support for image URLs -- Optional image naming -- Integration with other Leonardo AI actions - ### Upscale Image Increases the resolution of images using Leonardo AI's Universal Upscaler. @@ -99,11 +85,7 @@ For detailed information about Leonardo AI's API, visit the [official documentat ## Rate Limits -Leonardo AI has the following rate limits: -- Total requests: 1,000 per minute -- Image generation requests: 100 per minute -- Concurrent image generation jobs: 10 -- Concurrent model training jobs: 5 +See the official Leonardo AI documentation for current limits. ## Support diff --git a/components/leonardo_ai/actions/generate-image/generate-image.mjs b/components/leonardo_ai/actions/generate-image/generate-image.mjs index 91688c714c45c..e02082e5be33e 100644 --- a/components/leonardo_ai/actions/generate-image/generate-image.mjs +++ b/components/leonardo_ai/actions/generate-image/generate-image.mjs @@ -3,8 +3,8 @@ import app from "../../leonardo_ai.app.mjs"; export default { key: "leonardo_ai-generate-image", name: "Generate Image", - description: "Generates new images using Leonardo AI's image generation API.", - version: "0.0.5", + description: "Generates new images using Leonardo AI's image generation API. [See the documentation](https://docs.leonardo.ai/reference/creategeneration)", + version: "0.0.1", type: "action", props: { app, @@ -18,7 +18,7 @@ export default { label: "Model", description: "The model to use for generation. Leave empty to use the default model.", async options() { - const models = await this.app.getPlatformModels({}); + const models = await this.app.getPlatformModels(); return models.map((model) => ({ label: model.name || model.id, value: model.id, @@ -30,39 +30,42 @@ export default { type: "integer", label: "Width", description: "Width of the generated image in pixels.", - default: 512, - min: 256, - max: 1024, + default: 1024, + min: 32, + max: 1536, }, height: { type: "integer", label: "Height", description: "Height of the generated image in pixels.", - default: 512, - min: 256, - max: 1024, + default: 768, + min: 32, + max: 1536, }, numImages: { type: "integer", label: "Number of Images", - description: "Number of images to generate (1-4).", + description: "Number of images to generate (1-8). If either width or height is over 768, must be between 1 and 4.", default: 1, min: 1, - max: 4, + max: 8, }, guidanceScale: { - type: "string", + type: "integer", label: "Guidance Scale", description: "How closely the model should follow the prompt. Must be between 1 and 20. Higher values = more adherence to prompt.", + default: 7, + min: 1, + max: 20, optional: true, }, numInferenceSteps: { type: "integer", label: "Inference Steps", description: "Number of denoising steps. More steps = higher quality but slower generation.", - default: 20, + default: 15, min: 10, - max: 50, + max: 60, optional: true, }, seed: { @@ -89,28 +92,20 @@ export default { width, height, num_images: numImages, + modelId, + guidance_scale: guidanceScale, + num_inference_steps: numInferenceSteps, + seed: seed }; - if (modelId) { - data.modelId = modelId; - } - if (guidanceScale) { - data.guidance_scale = parseFloat(guidanceScale); - } - if (numInferenceSteps) { - data.num_inference_steps = numInferenceSteps; - } - if (seed) { - data.seed = seed; - } - - const response = await this.app.post({ + const response = await this.app._makeRequest({ $, + method: "POST", path: "/generations", data, }); - $.export("$summary", `Successfully generated ${numImages} image(s) with prompt: "${prompt}"`); + $.export("$summary", `Successfully generated ${numImages} image(s)`); return response; }, }; diff --git a/components/leonardo_ai/actions/generate-motion/generate-motion.mjs b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs index c3bc27dbf0085..159987fee1154 100644 --- a/components/leonardo_ai/actions/generate-motion/generate-motion.mjs +++ b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs @@ -3,8 +3,8 @@ import app from "../../leonardo_ai.app.mjs"; export default { key: "leonardo_ai-generate-motion", name: "Generate Motion", - description: "Generates a motion (video) from the provided image using Leonardo AI's SVD Motion Generation API.", - version: "0.0.4", + description: "Generates a motion (video) from the provided image using Leonardo AI's SVD Motion Generation API. [See the documentation](https://docs.leonardo.ai/reference/createsvdmotiongeneration)", + version: "0.0.1", type: "action", props: { app, @@ -28,13 +28,13 @@ export default { isInitImage: { type: "boolean", label: "Is Init Image", - description: "If it is an init image uploaded by the user.", + description: "Whether the image being used is an init image uploaded by the user.", optional: true, }, isVariation: { type: "boolean", label: "Is Variation", - description: "If it is a variation image.", + description: "Whether the image being used is a variation image.", optional: true, }, }, @@ -49,23 +49,15 @@ export default { const data = { imageId, + motionStrength, + isPublic, + isInitImage, + isVariation, }; - if (motionStrength !== undefined) { - data.motionStrength = motionStrength; - } - if (isPublic !== undefined) { - data.isPublic = isPublic; - } - if (isInitImage !== undefined) { - data.isInitImage = isInitImage; - } - if (isVariation !== undefined) { - data.isVariation = isVariation; - } - - const response = await this.app.post({ + const response = await this.app._makeRequest({ $, + method: "POST", path: "/generations-motion-svd", data, }); diff --git a/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs b/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs index e15588b1a223f..f79db0dc52fb8 100644 --- a/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs +++ b/components/leonardo_ai/actions/unzoom-image/unzoom-image.mjs @@ -3,8 +3,8 @@ import app from "../../leonardo_ai.app.mjs"; export default { key: "leonardo_ai-unzoom-image", name: "Unzoom Image", - description: "Creates an unzoom variation for a generated or variation image using Leonardo AI's unzoom API.", - version: "0.0.2", + description: "Creates an unzoom variation for a generated or variation image using Leonardo AI's unzoom API. [See the documentation](https://docs.leonardo.ai/reference/createvariationunzoom)", + version: "0.0.1", type: "action", props: { app, @@ -31,8 +31,9 @@ export default { isVariation, }; - const response = await this.app.post({ + const response = await this.app._makeRequest({ $, + method: "POST", path: "/variations/unzoom", data, }); diff --git a/components/leonardo_ai/actions/upload-image/upload-image.mjs b/components/leonardo_ai/actions/upload-image/upload-image.mjs index 6edc7e98db2a9..edfaa122054d7 100644 --- a/components/leonardo_ai/actions/upload-image/upload-image.mjs +++ b/components/leonardo_ai/actions/upload-image/upload-image.mjs @@ -1,10 +1,12 @@ import app from "../../leonardo_ai.app.mjs"; +import FormData from "form-data"; +import { getFileStreamAndMetadata } from "@pipedream/platform"; export default { key: "leonardo_ai-upload-image", name: "Upload Image", - description: "Uploads a new image to Leonardo AI for use in generations and variations.", - version: "0.0.9", + description: "Uploads a new image to Leonardo AI for use in generations and variations. [See the documentation](https://docs.leonardo.ai/docs/how-to-upload-an-image-using-a-presigned-url)", + version: "0.0.1", type: "action", props: { app, @@ -31,34 +33,30 @@ export default { }, ], }, - file: { + filePath: { type: "string", - label: "File", - description: "The base64 encoded image file to upload.", + label: "File Path or URL", + description: "The file to upload. Provide either a file URL or a path to a file in the `/tmp` directory (for example, `/tmp/myImage.png`)", + }, + syncDir: { + type: "dir", + accessMode: "read", + sync: true, + optional: true, }, }, async run({ $ }) { const { extension, - file, + filePath, } = this; - console.log(extension); - // Convert base64 string to Buffer - const base64Data = file.replace(/^data:image\/[a-z]+;base64,/, ""); - const buffer = Buffer.from(base64Data, "base64"); - - // Create a File-like object from the buffer - const fileObject = { - buffer: buffer, - name: `image.${extension}`, - type: `image/${ - extension === "jpg" ? - "jpeg" - : extension - }`, - }; + // Get file stream from URL or /tmp based path + const { + stream, + metadata, + } = await getFileStreamAndMetadata(filePath); - // Step 1: Get the presigned URL and upload fields + // Step 1: Get the presigned URL, upload fields appended to formData const uploadResponse = await this.app.getUploadInitImage({ $, extension, @@ -66,17 +64,27 @@ export default { const { uploadInitImage } = uploadResponse; const fields = JSON.parse(uploadInitImage.fields); + const formData = new FormData(); + + //Important: Order of fields is sanctioned by Leonardo AI API. Fields should go first, then the file + for (const [label, value] of Object.entries(fields)) { + formData.append(label, value.toString()); + } + formData.append("file", stream, { + contentType: metadata.contentType, + knownLength: metadata.size, + filename: metadata.name, + }); const uploadUrl = uploadInitImage.url; // Step 2: Upload the file to the presigned URL const uploadResult = await this.app.uploadFileToPresignedUrl({ $, url: uploadUrl, - fields, - file: fileObject, + formData, }); - $.export("$summary", `Successfully uploaded image with extension: ${extension}`); + $.export("$summary", `Successfully uploaded image: ${metadata.name || filePath}`); return { uploadInitImage, uploadResult, diff --git a/components/leonardo_ai/actions/upscale-image/upscale-image.mjs b/components/leonardo_ai/actions/upscale-image/upscale-image.mjs index b83f10e62ba55..99485b213e335 100644 --- a/components/leonardo_ai/actions/upscale-image/upscale-image.mjs +++ b/components/leonardo_ai/actions/upscale-image/upscale-image.mjs @@ -3,8 +3,8 @@ import app from "../../leonardo_ai.app.mjs"; export default { key: "leonardo_ai-upscale-image", name: "Upscale Image", - description: "Creates a high-resolution upscale of the provided image using Leonardo AI's upscale API.", - version: "0.0.2", + description: "Creates a high-resolution upscale of the provided image using Leonardo AI's upscale API. [See the documentation](https://docs.leonardo.ai/reference/createvariationupscale)", + version: "0.0.1", type: "action", props: { app, @@ -21,8 +21,9 @@ export default { id: imageId, }; - const response = await this.app.post({ + const response = await this.app._makeRequest({ $, + method: "POST", path: "/variations/upscale", data, }); diff --git a/components/leonardo_ai/leonardo_ai.app.mjs b/components/leonardo_ai/leonardo_ai.app.mjs index 39f03a7eb45e8..6f8d78799cea3 100644 --- a/components/leonardo_ai/leonardo_ai.app.mjs +++ b/components/leonardo_ai/leonardo_ai.app.mjs @@ -17,48 +17,28 @@ export default { }; }, async _makeRequest({ - $ = this, path, ...opts + $ = this, + method = "GET", + path, + data, + ...opts }) { - return axios($, { - ...opts, + const { headers: userHeaders, ...rest } = opts; + const config = { + method, + ...rest, url: `${this._baseUrl()}${path}`, - headers: this._getHeaders(), - }); - }, - async post({ - $ = this, path, data, ...opts - }) { - return this._makeRequest({ - $, - path, - method: "POST", + headers: { + ...this._getHeaders(), + ...(userHeaders || {}), + }, data, - ...opts, - }); + }; + return await axios($, config); }, - async get({ - $ = this, path, ...opts - }) { - return this._makeRequest({ - $, - path, + async getPlatformModels() { + const data = await this._makeRequest({ method: "GET", - ...opts, - }); - }, - async delete({ - $ = this, path, ...opts - }) { - return this._makeRequest({ - $, - path, - method: "DELETE", - ...opts, - }); - }, - async getPlatformModels({ $ }) { - const data = await this.get({ - $, path: "/platformModels", }); return data.custom_models || []; @@ -66,8 +46,9 @@ export default { async getUploadInitImage({ $, extension, }) { - const data = await this.post({ + const data = await this._makeRequest({ $, + method: "POST", path: "/init-image", data: { extension, @@ -76,30 +57,8 @@ export default { return data; }, async uploadFileToPresignedUrl({ - $, url, fields, file, + $, url, formData, }) { - const formData = new FormData(); - - // Add all the fields from the presigned URL response - Object.entries(fields).forEach(([ - key, - value, - ]) => { - formData.append(key, value); - }); - - // Add the file - handle both File objects and File-like objects - if (file.buffer) { - // File-like object with buffer - formData.append("file", file.buffer, { - filename: file.name, - contentType: file.type, - }); - } else { - // Regular File object - formData.append("file", file); - } - const response = await axios($, { url, method: "POST", @@ -108,7 +67,6 @@ export default { ...formData.getHeaders(), }, }); - return response; }, }, diff --git a/components/leonardo_ai/package.json b/components/leonardo_ai/package.json index 98a8f1f402537..1a19e553d99a1 100644 --- a/components/leonardo_ai/package.json +++ b/components/leonardo_ai/package.json @@ -1,29 +1,19 @@ { "name": "@pipedream/leonardo_ai", - "version": "0.0.2", - "description": "Pipedream Leonardo AI Components - Generate images, videos, and 3D models with AI", + "version": "0.1.0", + "description": "Pipedream Leonardo AI Components", "main": "leonardo_ai.app.mjs", "keywords": [ "pipedream", - "leonardo_ai", - "ai", - "image-generation", - "video-generation", - "upscaling", - "machine-learning" + "leonardo_ai" ], "homepage": "https://pipedream.com/apps/leonardo_ai", "author": "Pipedream (https://pipedream.com/)", - "license": "MIT", "publishConfig": { "access": "public" }, - "repository": { - "type": "git", - "url": "https://github.com/PipedreamHQ/pipedream.git", - "directory": "components/leonardo_ai" - }, - "bugs": { - "url": "https://github.com/PipedreamHQ/pipedream/issues" + "dependencies": { + "@pipedream/platform": "^3.1.0", + "form-data": "^4.0.4" } } From 3260986264a449c2b46ff757e4165b4d1f402b1a Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sun, 21 Sep 2025 13:45:08 -0700 Subject: [PATCH 47/52] Removes leonardo_ai_actions.mdc not indented for merging --- .../actions/leonardo_ai_actions.mdc | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 components/leonardo_ai/actions/leonardo_ai_actions.mdc diff --git a/components/leonardo_ai/actions/leonardo_ai_actions.mdc b/components/leonardo_ai/actions/leonardo_ai_actions.mdc deleted file mode 100644 index bc133ed4f4f49..0000000000000 --- a/components/leonardo_ai/actions/leonardo_ai_actions.mdc +++ /dev/null @@ -1,26 +0,0 @@ ---- -alwaysApply: true ---- -leonardo-ai -URLs -https://docs.leonardo.ai/reference -Actions -generate-motion -Prompt -Generates a motion (video) from the provided image (any type). - -generate-image -Prompt -Generates new images. - -unzoom-image -Prompt -Creates an unzoom variation for a generated or variation image. - -upload-image -Prompt -Uploads a new image. - -upscale-image -Prompt -Creates a high-resolution upscale (Universal Upscaler) of the provided image (any type). \ No newline at end of file From 7a6774bd42547ec4b7e59f75e9eaf251f09ae5af Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sun, 21 Sep 2025 14:30:47 -0700 Subject: [PATCH 48/52] synced lockfile after install --- pnpm-lock.yaml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0b06542d2495a..3a943f97e753e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7082,8 +7082,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/instamojo: - specifiers: {} + components/instamojo: {} components/instant: {} @@ -7867,7 +7866,14 @@ importers: specifier: ^0.3.2 version: 0.3.2 - components/leonardo_ai: {} + components/leonardo_ai: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 + form-data: + specifier: ^4.0.4 + version: 4.0.4 components/lessaccounting: {} @@ -11733,8 +11739,7 @@ importers: components/redmine: {} - components/reduct_video: - specifiers: {} + components/reduct_video: {} components/referral_rocket: {} @@ -13038,8 +13043,7 @@ importers: specifier: 1.6.0 version: 1.6.0 - components/shopware: - specifiers: {} + components/shopware: {} components/short: dependencies: @@ -38934,8 +38938,6 @@ snapshots: '@putout/operator-filesystem': 5.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3)) '@putout/operator-json': 2.2.0 putout: 36.13.1(eslint@8.57.1)(typescript@5.6.3) - transitivePeerDependencies: - - supports-color '@putout/operator-regexp@1.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3))': dependencies: From d2d0b88e427c4968b257b87596663b4e323db708 Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sun, 21 Sep 2025 18:59:47 -0700 Subject: [PATCH 49/52] fully lock form-data for leonardo_ai --- pnpm-lock.yaml | 166 ++++++------------------------------------------- 1 file changed, 19 insertions(+), 147 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a943f97e753e..5401e2f93fcee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -107,7 +107,7 @@ importers: version: 4.0.0 ts-jest: specifier: ^29.1.1 - version: 29.2.5(@babel/core@8.0.0-alpha.13)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-alpha.13))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3) tsc-esm-fix: specifier: ^2.18.0 version: 2.20.27 @@ -16855,7 +16855,7 @@ importers: version: 3.1.7 ts-jest: specifier: ^29.2.5 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2) tsup: specifier: ^8.3.6 version: 8.3.6(@microsoft/api-extractor@7.47.12(@types/node@20.17.30))(jiti@2.4.2)(postcss@8.5.6)(tsx@4.19.4)(typescript@5.7.2)(yaml@2.8.0) @@ -34918,7 +34918,7 @@ snapshots: '@babel/traverse': 7.25.9 '@babel/types': 7.26.0 convert-source-map: 2.0.0 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -35189,45 +35189,21 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -35238,34 +35214,16 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -35276,89 +35234,41 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@8.0.0-alpha.13)': - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/helper-plugin-utils': 7.25.9 - optional: true - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -36413,7 +36323,7 @@ snapshots: '@eslint/eslintrc@3.2.0': dependencies: ajv: 6.12.6 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -38938,6 +38848,8 @@ snapshots: '@putout/operator-filesystem': 5.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3)) '@putout/operator-json': 2.2.0 putout: 36.13.1(eslint@8.57.1)(typescript@5.6.3) + transitivePeerDependencies: + - supports-color '@putout/operator-regexp@1.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3))': dependencies: @@ -41168,7 +41080,7 @@ snapshots: '@typescript-eslint/types': 8.15.0 '@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.15.0 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) eslint: 8.57.1 optionalDependencies: typescript: 5.6.3 @@ -42048,20 +41960,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-jest@29.7.0(@babel/core@8.0.0-alpha.13): - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@8.0.0-alpha.13) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - optional: true - babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.25.9 @@ -42128,39 +42026,12 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.0) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.0) - babel-preset-current-node-syntax@1.1.0(@babel/core@8.0.0-alpha.13): - dependencies: - '@babel/core': 8.0.0-alpha.13 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@8.0.0-alpha.13) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@8.0.0-alpha.13) - optional: true - babel-preset-jest@29.6.3(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.0) - babel-preset-jest@29.6.3(@babel/core@8.0.0-alpha.13): - dependencies: - '@babel/core': 8.0.0-alpha.13 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@8.0.0-alpha.13) - optional: true - backoff@2.5.0: dependencies: precond: 0.2.3 @@ -44380,7 +44251,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -46247,7 +46118,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -48839,7 +48710,7 @@ snapshots: dependencies: '@tediousjs/connection-string': 0.5.0 commander: 11.1.0 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) rfdc: 1.4.1 tarn: 3.0.2 tedious: 16.7.1 @@ -50614,7 +50485,7 @@ snapshots: ajv: 8.17.1 chalk: 5.3.0 ci-info: 4.1.0 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) deepmerge: 4.3.1 escalade: 3.2.0 fast-glob: 3.3.2 @@ -52756,7 +52627,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -52774,8 +52645,9 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.26.0) + esbuild: 0.24.2 - ts-jest@29.2.5(@babel/core@8.0.0-alpha.13)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-alpha.13))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -52789,10 +52661,10 @@ snapshots: typescript: 5.6.3 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 8.0.0-alpha.13 + '@babel/core': 7.26.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@8.0.0-alpha.13) + babel-jest: 29.7.0(@babel/core@7.26.0) ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2): dependencies: @@ -52964,7 +52836,7 @@ snapshots: cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.0 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) esbuild: 0.24.2 joycon: 3.1.1 picocolors: 1.1.1 @@ -52992,7 +52864,7 @@ snapshots: cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.0 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) esbuild: 0.24.2 joycon: 3.1.1 picocolors: 1.1.1 @@ -53616,7 +53488,7 @@ snapshots: '@volar/typescript': 2.4.10 '@vue/language-core': 2.1.6(typescript@5.9.2) compare-versions: 6.1.1 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.3.7(supports-color@5.5.0) kolorist: 1.8.0 local-pkg: 0.5.1 magic-string: 0.30.13 From b5f7dce2eee04b17ff6cd4e64de091f2030599a3 Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sun, 21 Sep 2025 19:45:43 -0700 Subject: [PATCH 50/52] conflict solving --- pnpm-lock.yaml | 179 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 147 insertions(+), 32 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fea2392c02a42..c41e1f5588aaf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -107,7 +107,7 @@ importers: version: 4.0.0 ts-jest: specifier: ^29.1.1 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3) + version: 29.2.5(@babel/core@8.0.0-alpha.13)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-alpha.13))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3) tsc-esm-fix: specifier: ^2.18.0 version: 2.20.27 @@ -7082,12 +7082,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 -<<<<<<< HEAD components/instamojo: {} -======= - components/instamojo: - specifiers: {} ->>>>>>> upstream/master components/instant: {} @@ -11744,12 +11739,7 @@ importers: components/redmine: {} -<<<<<<< HEAD components/reduct_video: {} -======= - components/reduct_video: - specifiers: {} ->>>>>>> upstream/master components/referral_rocket: {} @@ -13053,12 +13043,7 @@ importers: specifier: 1.6.0 version: 1.6.0 -<<<<<<< HEAD components/shopware: {} -======= - components/shopware: - specifiers: {} ->>>>>>> upstream/master components/short: dependencies: @@ -16870,7 +16855,7 @@ importers: version: 3.1.7 ts-jest: specifier: ^29.2.5 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2) tsup: specifier: ^8.3.6 version: 8.3.6(@microsoft/api-extractor@7.47.12(@types/node@20.17.30))(jiti@2.4.2)(postcss@8.5.6)(tsx@4.19.4)(typescript@5.7.2)(yaml@2.8.0) @@ -34933,7 +34918,7 @@ snapshots: '@babel/traverse': 7.25.9 '@babel/types': 7.26.0 convert-source-map: 2.0.0 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -35204,21 +35189,45 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -35229,16 +35238,34 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -35249,41 +35276,89 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@8.0.0-alpha.13)': + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -36338,7 +36413,7 @@ snapshots: '@eslint/eslintrc@3.2.0': dependencies: ajv: 6.12.6 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -41095,7 +41170,7 @@ snapshots: '@typescript-eslint/types': 8.15.0 '@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.15.0 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) eslint: 8.57.1 optionalDependencies: typescript: 5.6.3 @@ -41975,6 +42050,20 @@ snapshots: transitivePeerDependencies: - supports-color + babel-jest@29.7.0(@babel/core@8.0.0-alpha.13): + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@8.0.0-alpha.13) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + optional: true + babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.25.9 @@ -42041,12 +42130,39 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.0) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.0) + babel-preset-current-node-syntax@1.1.0(@babel/core@8.0.0-alpha.13): + dependencies: + '@babel/core': 8.0.0-alpha.13 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@8.0.0-alpha.13) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@8.0.0-alpha.13) + optional: true + babel-preset-jest@29.6.3(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.0) + babel-preset-jest@29.6.3(@babel/core@8.0.0-alpha.13): + dependencies: + '@babel/core': 8.0.0-alpha.13 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@8.0.0-alpha.13) + optional: true + backoff@2.5.0: dependencies: precond: 0.2.3 @@ -44266,7 +44382,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -46133,7 +46249,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -48725,7 +48841,7 @@ snapshots: dependencies: '@tediousjs/connection-string': 0.5.0 commander: 11.1.0 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) rfdc: 1.4.1 tarn: 3.0.2 tedious: 16.7.1 @@ -50500,7 +50616,7 @@ snapshots: ajv: 8.17.1 chalk: 5.3.0 ci-info: 4.1.0 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) deepmerge: 4.3.1 escalade: 3.2.0 fast-glob: 3.3.2 @@ -52642,7 +52758,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2)))(typescript@5.7.2): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -52660,9 +52776,8 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.26.0) - esbuild: 0.24.2 - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3): + ts-jest@29.2.5(@babel/core@8.0.0-alpha.13)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-alpha.13))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.17.6)(typescript@5.6.3)))(typescript@5.6.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -52676,10 +52791,10 @@ snapshots: typescript: 5.6.3 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.26.0 + '@babel/core': 8.0.0-alpha.13 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.26.0) + babel-jest: 29.7.0(@babel/core@8.0.0-alpha.13) ts-node@10.9.2(@types/node@20.17.30)(typescript@5.7.2): dependencies: @@ -52851,7 +52966,7 @@ snapshots: cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.0 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) esbuild: 0.24.2 joycon: 3.1.1 picocolors: 1.1.1 @@ -52879,7 +52994,7 @@ snapshots: cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.0 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) esbuild: 0.24.2 joycon: 3.1.1 picocolors: 1.1.1 @@ -53503,7 +53618,7 @@ snapshots: '@volar/typescript': 2.4.10 '@vue/language-core': 2.1.6(typescript@5.9.2) compare-versions: 6.1.1 - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.7(supports-color@9.4.0) kolorist: 1.8.0 local-pkg: 0.5.1 magic-string: 0.30.13 From 1d35b091b8daa2d6d0e868a215bdd283f1e68089 Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Sun, 21 Sep 2025 20:15:36 -0700 Subject: [PATCH 51/52] lint fixes --- .../actions/generate-image/generate-image.mjs | 4 ++-- .../actions/generate-motion/generate-motion.mjs | 2 +- .../actions/upload-image/upload-image.mjs | 13 ++++++++----- components/leonardo_ai/leonardo_ai.app.mjs | 14 ++++++++------ 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/components/leonardo_ai/actions/generate-image/generate-image.mjs b/components/leonardo_ai/actions/generate-image/generate-image.mjs index e02082e5be33e..30f48d7ffd0b5 100644 --- a/components/leonardo_ai/actions/generate-image/generate-image.mjs +++ b/components/leonardo_ai/actions/generate-image/generate-image.mjs @@ -95,7 +95,7 @@ export default { modelId, guidance_scale: guidanceScale, num_inference_steps: numInferenceSteps, - seed: seed + seed, }; const response = await this.app._makeRequest({ @@ -105,7 +105,7 @@ export default { data, }); - $.export("$summary", `Successfully generated ${numImages} image(s)`); + $.export("$summary", `Successfully generated ${numImages} image(s)`); return response; }, }; diff --git a/components/leonardo_ai/actions/generate-motion/generate-motion.mjs b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs index 159987fee1154..cf3e713c85ff9 100644 --- a/components/leonardo_ai/actions/generate-motion/generate-motion.mjs +++ b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs @@ -52,7 +52,7 @@ export default { motionStrength, isPublic, isInitImage, - isVariation, + isVariation, }; const response = await this.app._makeRequest({ diff --git a/components/leonardo_ai/actions/upload-image/upload-image.mjs b/components/leonardo_ai/actions/upload-image/upload-image.mjs index edfaa122054d7..3776134de71ee 100644 --- a/components/leonardo_ai/actions/upload-image/upload-image.mjs +++ b/components/leonardo_ai/actions/upload-image/upload-image.mjs @@ -64,17 +64,20 @@ export default { const { uploadInitImage } = uploadResponse; const fields = JSON.parse(uploadInitImage.fields); - const formData = new FormData(); + const formData = new FormData(); - //Important: Order of fields is sanctioned by Leonardo AI API. Fields should go first, then the file - for (const [label, value] of Object.entries(fields)) { + //Important: Order of fields is sanctioned by Leonardo AI API. Fields go first, then the file + for (const [ + label, + value, + ] of Object.entries(fields)) { formData.append(label, value.toString()); - } + } formData.append("file", stream, { contentType: metadata.contentType, knownLength: metadata.size, filename: metadata.name, - }); + }); const uploadUrl = uploadInitImage.url; // Step 2: Upload the file to the presigned URL diff --git a/components/leonardo_ai/leonardo_ai.app.mjs b/components/leonardo_ai/leonardo_ai.app.mjs index 6f8d78799cea3..72c5425d8cc74 100644 --- a/components/leonardo_ai/leonardo_ai.app.mjs +++ b/components/leonardo_ai/leonardo_ai.app.mjs @@ -1,5 +1,4 @@ import { axios } from "@pipedream/platform"; -import FormData from "form-data"; export default { type: "app", @@ -17,13 +16,16 @@ export default { }; }, async _makeRequest({ - $ = this, - method = "GET", - path, - data, + $ = this, + method = "GET", + path, + data, ...opts }) { - const { headers: userHeaders, ...rest } = opts; + const { + headers: userHeaders, + ...rest + } = opts; const config = { method, ...rest, From 18e7669c8e74a00712ef69ab9dd9075cee35429d Mon Sep 17 00:00:00 2001 From: Sergio Wong Date: Mon, 22 Sep 2025 22:20:53 -0700 Subject: [PATCH 52/52] Chipped down Readme, implemented async options in gen motion --- components/leonardo_ai/README.md | 81 ------------------- .../generate-motion/generate-motion.mjs | 51 +++++++++++- components/leonardo_ai/leonardo_ai.app.mjs | 42 +++++++++- 3 files changed, 88 insertions(+), 86 deletions(-) diff --git a/components/leonardo_ai/README.md b/components/leonardo_ai/README.md index d932d205f2e6e..bab2cb162520d 100644 --- a/components/leonardo_ai/README.md +++ b/components/leonardo_ai/README.md @@ -2,91 +2,10 @@ [Leonardo AI](https://leonardo.ai) is an AI-powered image generation platform that allows you to create stunning images, videos, and 3D models using advanced machine learning models. -## Actions - -### Generate Image -Creates new images from text prompts using Leonardo AI's image generation models. - -**Key Features:** -- Customizable image dimensions (256x256 to 1024x1024) -- Multiple model support -- Adjustable guidance scale and inference steps -- Batch generation (1-4 images) -- Seed support for reproducible results - -### Generate Motion -Creates motion videos from static images using Leonardo AI's SVD Motion Generation. - -**Key Features:** -- Converts static images to motion videos -- Adjustable motion strength -- Seed support for reproducible results - -### Unzoom Image -Creates unzoom variations of existing images, expanding the scene beyond the original frame. - -**Key Features:** -- Zoom out effect on existing images -- Adjustable zoom level -- Works with generated or uploaded images - -### Upload Image -Uploads images to Leonardo AI for use in generations and variations. - -### Upscale Image -Increases the resolution of images using Leonardo AI's Universal Upscaler. - -**Key Features:** -- Multiple upscaling modes (Universal Upscaler, Real-ESRGAN) -- 2x and 4x scale factors -- High-quality image enhancement - -## Usage Examples - -### Basic Image Generation -```javascript -// Generate a simple image -{ - "prompt": "A beautiful sunset over mountains", - "width": 512, - "height": 512, - "numImages": 1 -} -``` - -### Advanced Image Generation -```javascript -// Generate with specific model and settings -{ - "prompt": "A cyberpunk cityscape at night", - "modelId": "6bef9f1b-29cb-40c7-b9df-32b51c1f67d3", - "width": 1024, - "height": 1024, - "numImages": 2, - "guidanceScale": "10", - "numInferenceSteps": 30, - "seed": 12345 -} -``` - -### Motion Generation -```javascript -// Create motion from an image -{ - "imageId": "generated-image-id-here", - "motionStrength": "0.7", - "seed": 54321 -} -``` - ## API Reference For detailed information about Leonardo AI's API, visit the [official documentation](https://docs.leonardo.ai/reference). -## Rate Limits - -See the official Leonardo AI documentation for current limits. - ## Support For support with this component or Leonardo AI's API, please refer to: diff --git a/components/leonardo_ai/actions/generate-motion/generate-motion.mjs b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs index cf3e713c85ff9..8d4de7206a721 100644 --- a/components/leonardo_ai/actions/generate-motion/generate-motion.mjs +++ b/components/leonardo_ai/actions/generate-motion/generate-motion.mjs @@ -11,7 +11,56 @@ export default { imageId: { type: "string", label: "Image ID", - description: "The ID of the image to generate motion from. This should be a previously generated or uploaded image ID.", + description: "The ID of the image to generate motion from. You can either select from previously generated images or manually enter the ID of an uploaded image.", + async options({ prevContext }) { + // Get user info to retrieve userId + const userInfo = await this.app.getUserInfo({ + $: this, + }); + // Extract userId from the response structure + const userId = userInfo.user_details?.[0]?.user?.id || userInfo.id; + + // Get generations with pagination + const offset = prevContext?.offset || 0; + const limit = 20; + + const generations = await this.app.getGenerationsByUserId({ + $: this, + userId, + offset, + limit, + }); + + // Extract image IDs from generated_images array + const options = []; + if (generations.generations) { + for (const generation of generations.generations) { + if (generation.generated_images) { + for (const image of generation.generated_images) { + options.push({ + label: `Image ${image.id} (Generation ${generation.id})`, + value: image.id, + }); + } + } + } + } + + // Check if there are more pages + const hasMore = generations.generations && generations.generations.length === limit; + const nextOffset = hasMore + ? offset + limit + : null; + + return { + options, + context: nextOffset + ? { + offset: nextOffset, + } + : {}, + }; + }, }, motionStrength: { type: "integer", diff --git a/components/leonardo_ai/leonardo_ai.app.mjs b/components/leonardo_ai/leonardo_ai.app.mjs index 72c5425d8cc74..fd342f19c8e58 100644 --- a/components/leonardo_ai/leonardo_ai.app.mjs +++ b/components/leonardo_ai/leonardo_ai.app.mjs @@ -19,6 +19,7 @@ export default { $ = this, method = "GET", path, + url, // Allow external URLs (e.g., presigned URLs) data, ...opts }) { @@ -26,12 +27,22 @@ export default { headers: userHeaders, ...rest } = opts; + + // Use provided URL or construct from base URL + path + const requestUrl = url || `${this._baseUrl()}${path}`; + + // For external URLs (like presigned URLs), don't add default headers + // For internal API calls, add default headers + const defaultHeaders = url + ? {} + : this._getHeaders(); + const config = { method, ...rest, - url: `${this._baseUrl()}${path}`, + url: requestUrl, headers: { - ...this._getHeaders(), + ...defaultHeaders, ...(userHeaders || {}), }, data, @@ -61,8 +72,9 @@ export default { async uploadFileToPresignedUrl({ $, url, formData, }) { - const response = await axios($, { - url, + const response = await this._makeRequest({ + $, + url, // Use the presigned URL directly method: "POST", data: formData, headers: { @@ -71,5 +83,27 @@ export default { }); return response; }, + async getUserInfo({ $ }) { + const data = await this._makeRequest({ + $, + method: "GET", + path: "/me", + }); + return data; + }, + async getGenerationsByUserId({ + $, userId, offset = 0, limit = 20, + }) { + const data = await this._makeRequest({ + $, + method: "GET", + path: `/generations/user/${userId}`, + params: { + offset, + limit, + }, + }); + return data; + }, }, };