diff --git a/components/zoho_workdrive/actions/download-file/download-file.mjs b/components/zoho_workdrive/actions/download-file/download-file.mjs index 5c7016b5442ec..36bb7d844623a 100644 --- a/components/zoho_workdrive/actions/download-file/download-file.mjs +++ b/components/zoho_workdrive/actions/download-file/download-file.mjs @@ -1,13 +1,16 @@ import app from "../../zoho_workdrive.app.mjs"; import { getFilePath } from "../../common/utils.mjs"; import { LIMIT } from "../../common/constants.mjs"; +import { + additionalFolderProps, findMaxFolderId, +} from "../../common/additionalFolderProps.mjs"; import fs from "fs"; export default { key: "zoho_workdrive-download-file", name: "Download File to Tmp Direcory", description: "Download a file to the /tmp directory. [See the documentation](https://workdrive.zoho.com/apidocs/v1/filesfolders/downloadserverfile)", - version: "0.0.5", + version: "0.0.6", type: "action", props: { app, @@ -34,21 +37,37 @@ export default { folderType, }), ], - label: "Folder Id", - description: "The unique ID of the folder where file is located.", + label: "Folder ID", + description: "The unique ID of the folder where file is located. Select a folder to view its subfolders.", + reloadProps: true, }, - fileId: { + syncDir: { + type: "dir", + accessMode: "write", + sync: true, + }, + }, + async additionalProps() { + const folderProps = await additionalFolderProps.call(this); + const props = { + ...folderProps, + }; + props.fileId = { type: "string", - label: "File Id", + label: "File ID", description: "The unique ID of the file to download.", withLabel: true, - async options({ page }) { + options: async ({ page }) => { + const num = this.findMaxFolderId(this); + const limit = this.getLimit(); const { data } = await this.app.listFiles({ - folderId: this.folderId, + folderId: num > 0 + ? this[`folderId${num}`] + : this.folderId, filter: "allfiles", params: new URLSearchParams({ - "page[limit]": LIMIT, - "page[offset]": LIMIT * page, + "page[limit]": limit, + "page[offset]": limit * page, }).toString(), }); return data.map(({ @@ -58,17 +77,19 @@ export default { label: attributes.name, })); }, - }, - fileName: { + }; + props.fileName = { type: "string", label: "Filename", description: "What to name the new file saved to /tmp directory", optional: true, - }, - syncDir: { - type: "dir", - accessMode: "write", - sync: true, + }; + return props; + }, + methods: { + findMaxFolderId, + getLimit() { + return LIMIT; }, }, async run({ $ }) { diff --git a/components/zoho_workdrive/actions/upload-file/upload-file.mjs b/components/zoho_workdrive/actions/upload-file/upload-file.mjs index afbca6c65c413..3ed2a230d3c9f 100644 --- a/components/zoho_workdrive/actions/upload-file/upload-file.mjs +++ b/components/zoho_workdrive/actions/upload-file/upload-file.mjs @@ -1,11 +1,14 @@ import { getFileStreamAndMetadata } from "@pipedream/platform"; import FormData from "form-data"; import app from "../../zoho_workdrive.app.mjs"; +import { + additionalFolderProps, findMaxFolderId, +} from "../../common/additionalFolderProps.mjs"; export default { key: "zoho_workdrive-upload-file", name: "Upload File", - version: "0.0.7", + version: "0.0.8", description: "Upload a new file to your WorkDrive account. [See the documentation](https://workdrive.zoho.com/apidocs/v1/chunkupload/chunkuploadcreatesession)", type: "action", props: { @@ -33,6 +36,7 @@ export default { folderType, }), ], + reloadProps: true, }, filename: { label: "Filename", @@ -58,6 +62,9 @@ export default { optional: true, }, }, + async additionalProps() { + return additionalFolderProps.call(this); + }, async run({ $ }) { const { stream, metadata, @@ -70,7 +77,12 @@ export default { }); const override = this.overrideNameExist?.toString(); - data.append("parent_id", this.parentId); + const num = findMaxFolderId(this); + const parentId = num > 0 + ? this[`folderId${num}`] + : this.parentId; + + data.append("parent_id", parentId); if (this.filename) data.append("filename", this.filename); if (override) data.append("override-name-exist", override); diff --git a/components/zoho_workdrive/common/additionalFolderProps.mjs b/components/zoho_workdrive/common/additionalFolderProps.mjs new file mode 100644 index 0000000000000..2153c5b302568 --- /dev/null +++ b/components/zoho_workdrive/common/additionalFolderProps.mjs @@ -0,0 +1,84 @@ +async function additionalFolderProps() { + const props = {}; + const rootFolderId = this.folderId || this.parentId; + if (!rootFolderId) { + return props; + } + + const { data: rootSubfolders } = await this.app.listFiles({ + folderId: rootFolderId, + }); + + if (!rootSubfolders.length) { + return props; + } + + props["folderId1"] = { + type: "string", + label: "Folder 2 ID", + description: "The unique ID of the subfolder. Select a folder to view its subfolders.", + options: rootSubfolders.map(({ + id, attributes: { name }, + }) => ({ + value: id, + label: name, + })), + optional: true, + reloadProps: true, + }; + + const num = findMaxFolderId(this); + + if (num < 1) { + return props; + } + + for (let i = 2; i <= num + 1; i++) { + const { data: subfolders } = await this.app.listFiles({ + folderId: this[`folderId${i - 1}`], + }); + + if (!subfolders.length) { + return props; + } + + props[`folderId${i}`] = { + type: "string", + label: `Folder ${i + 1} ID`, + description: `The unique ID of the subfolder ${i + 1}. Select a folder to view its subfolders.`, + options: subfolders.map(({ + id, attributes: { name }, + }) => ({ + value: id, + label: name, + })), + optional: true, + reloadProps: true, + }; + } + + return props; +} + +function findMaxFolderId(obj) { + let maxNum = -Infinity; + + Object.keys(obj).forEach((key) => { + const match = key.match(/^(folderId(\d*)|parentId)$/); + if (match) { + const num = match[2] === undefined || match[2] === "" + ? 0 + : parseInt(match[2], 10); + if (num > maxNum) { + maxNum = num; + } + } + }); + + return maxNum; +} + +export { + additionalFolderProps, + findMaxFolderId, +}; diff --git a/components/zoho_workdrive/package.json b/components/zoho_workdrive/package.json index 6a37dd6f64bfa..a05b19217b072 100644 --- a/components/zoho_workdrive/package.json +++ b/components/zoho_workdrive/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/zoho_workdrive", - "version": "0.2.6", + "version": "0.2.7", "description": "Pipedream Zoho WorkDrive Components", "main": "zoho_workdrive.app.mjs", "keywords": [ diff --git a/components/zoho_workdrive/sources/common/base.mjs b/components/zoho_workdrive/sources/common/base.mjs new file mode 100644 index 0000000000000..10178b8bb798a --- /dev/null +++ b/components/zoho_workdrive/sources/common/base.mjs @@ -0,0 +1,38 @@ +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; +import app from "../../zoho_workdrive.app.mjs"; +import { additionalFolderProps } from "../../common/additionalFolderProps.mjs"; + +export default { + props: { + app, + db: "$.service.db", + timer: { + label: "Polling interval", + description: "Pipedream will poll the Zoho WorkDrive on this schedule", + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + teamId: { + propDefinition: [ + app, + "teamId", + ], + }, + }, + async additionalProps() { + return additionalFolderProps.call(this); + }, + methods: { + _getLastDate() { + return this.db.get("lastDate") || 0; + }, + _setLastDate(lastDate) { + this.db.set("lastDate", lastDate); + }, + }, + async run() { + await this.startEvent(); + }, +}; diff --git a/components/zoho_workdrive/sources/new-file-in-folder/new-file-in-folder.mjs b/components/zoho_workdrive/sources/new-file-in-folder/new-file-in-folder.mjs index 6032351afcc80..fbfbda347d820 100644 --- a/components/zoho_workdrive/sources/new-file-in-folder/new-file-in-folder.mjs +++ b/components/zoho_workdrive/sources/new-file-in-folder/new-file-in-folder.mjs @@ -1,45 +1,29 @@ -import { - ConfigurationError, - DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, -} from "@pipedream/platform"; -import app from "../../zoho_workdrive.app.mjs"; +import { ConfigurationError } from "@pipedream/platform"; +import common from "../common/base.mjs"; import { Readable } from "stream"; import { fileTypeFromBuffer } from "file-type"; +import { findMaxFolderId } from "../../common/additionalFolderProps.mjs"; import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "zoho_workdrive-new-file-in-folder", name: "New File In Folder", - version: "0.2.0", + version: "0.2.1", description: "Emit new event when a new file is created in a specific folder.", type: "source", dedupe: "unique", props: { - app, - db: "$.service.db", - timer: { - label: "Polling interval", - description: "Pipedream will poll the Zoho WorkDrive on this schedule", - type: "$.interface.timer", - default: { - intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, - }, - }, - teamId: { - propDefinition: [ - app, - "teamId", - ], - }, + ...common.props, folderType: { propDefinition: [ - app, + common.props.app, "folderType", ], }, folderId: { propDefinition: [ - app, + common.props.app, "parentId", ({ teamId, folderType, @@ -48,15 +32,10 @@ export default { folderType, }), ], - label: "Folder Id", - description: "Select the unique ID of the folder.", - optional: true, - }, - typedFolderId: { - type: "string", - label: "Typed Folder Id", - description: "Type in the unique ID of the folder. Use this if you hit rate limits on the `Folder Id` prop.", + label: "Folder ID", + description: "Select the unique ID of the folder. Select a folder to view its subfolders.", optional: true, + reloadProps: true, }, includeLink: { label: "Include Link", @@ -72,12 +51,7 @@ export default { }, }, methods: { - _getLastDate() { - return this.db.get("lastDate") || 0; - }, - _setLastDate(lastDate) { - this.db.set("lastDate", lastDate); - }, + ...common.methods, async stashFile(item) { const fileContent = await this.app.downloadFile({ fileId: item.id, @@ -95,33 +69,32 @@ export default { return await file.withoutPutUrl().withGetUrl(); }, async startEvent(maxResults = 0) { - const { - app, - folderId, - typedFolderId, - } = this; + const num = findMaxFolderId(this); + const folderId = num > 0 + ? this[`folderId${num}`] + : this.folderId; - if (!folderId && !typedFolderId) { - throw new ConfigurationError("Please select a Folder Id or type in a Typed Folder Id."); + if (!folderId) { + throw new ConfigurationError("Please select a Folder ID or type in a Folder ID."); } const lastDate = this._getLastDate(); let maxDate = lastDate; - const items = app.paginate({ - fn: app.listFiles, + const items = this.app.paginate({ + fn: this.app.listFiles, maxResults, filter: "allfiles", sort: "created_time", - folderId: folderId || typedFolderId, + folderId, }); let responseArray = []; for await (const item of items) { - const createdTime = item.attributes.created_time; - if (new Date(createdTime) > new Date(lastDate)) { + const createdTime = item.attributes.created_time_in_millisecond; + if (createdTime > lastDate) { responseArray.push(item); - if (new Date(createdTime) > new Date(maxDate)) { + if (createdTime > maxDate) { maxDate = createdTime; } } @@ -136,8 +109,8 @@ export default { item, { id: item.id, - summary: `A new file with id: "${item.id}" was created!`, - ts: item.attributes.created_time, + summary: `A new file with ID: "${item.id}" was created!`, + ts: item.attributes.created_time_in_millisecond, }, ); } @@ -148,8 +121,5 @@ export default { await this.startEvent(10); }, }, - async run() { - await this.startEvent(); - }, sampleEmit, }; diff --git a/components/zoho_workdrive/sources/new-folder/new-folder.mjs b/components/zoho_workdrive/sources/new-folder/new-folder.mjs index 571a61da5a289..fb4581ba01abd 100644 --- a/components/zoho_workdrive/sources/new-folder/new-folder.mjs +++ b/components/zoho_workdrive/sources/new-folder/new-folder.mjs @@ -1,42 +1,27 @@ -import { - ConfigurationError, - DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, -} from "@pipedream/platform";import app from "../../zoho_workdrive.app.mjs"; +import { ConfigurationError } from "@pipedream/platform"; +import common from "../common/base.mjs"; +import { findMaxFolderId } from "../../common/additionalFolderProps.mjs"; import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "zoho_workdrive-new-folder", name: "New Folder", - version: "0.1.0", + version: "0.1.1", description: "Emit new event when a new folder is created in a specific folder.", type: "source", dedupe: "unique", props: { - app, - db: "$.service.db", - timer: { - label: "Polling interval", - description: "Pipedream will poll the Zoho WorkDrive on this schedule", - type: "$.interface.timer", - default: { - intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, - }, - }, - teamId: { - propDefinition: [ - app, - "teamId", - ], - }, + ...common.props, folderType: { propDefinition: [ - app, + common.props.app, "folderType", ], }, folderId: { propDefinition: [ - app, + common.props.app, "parentId", ({ teamId, folderType, @@ -45,52 +30,41 @@ export default { folderType, }), ], - label: "Folder Id", - description: "The unique ID of the folder.", - optional: true, - }, - typedFolderId: { - type: "string", - label: "Typed Folder Id", - description: "Type in the unique ID of the folder. Use this if you hit rate limits on the `Folder Id` prop.", + label: "Folder ID", + description: "The unique ID of the folder. Select a folder to view its subfolders.", optional: true, + reloadProps: true, }, }, methods: { - _getLastDate() { - return this.db.get("lastDate") || 0; - }, - _setLastDate(lastDate) { - this.db.set("lastDate", lastDate); - }, + ...common.methods, async startEvent(maxResults = 0) { - const { - app, - folderId, - typedFolderId, - } = this; + const num = findMaxFolderId(this); + const folderId = num > 0 + ? this[`folderId${num}`] + : this.folderId; - if (!folderId && !typedFolderId) { - throw new ConfigurationError("Please select a Folder Id or type in a Typed Folder Id."); + if (!folderId) { + throw new ConfigurationError("Please select a Folder ID or type in a Folder ID."); } const lastDate = this._getLastDate(); let maxDate = lastDate; - const items = app.paginate({ - fn: app.listFiles, + const items = this.app.paginate({ + fn: this.app.listFiles, maxResults, filter: "folder", sort: "created_time", - folderId: folderId || typedFolderId, + folderId, }); let responseArray = []; for await (const item of items) { - const createdTime = item.attributes.created_time; - if (new Date(createdTime) > new Date(lastDate)) { + const createdTime = item.attributes.created_time_in_millisecond; + if (createdTime > lastDate) { responseArray.push(item); - if (new Date(createdTime) > new Date(maxDate)) { + if (createdTime > maxDate) { maxDate = createdTime; } } @@ -102,8 +76,8 @@ export default { item, { id: item.id, - summary: `A new folder with id: "${item.id}" was created!`, - ts: item.attributes.created_time, + summary: `A new folder with ID: "${item.id}" was created!`, + ts: item.attributes.created_time_in_millisecond, }, ); } @@ -114,8 +88,5 @@ export default { await this.startEvent(25); }, }, - async run() { - await this.startEvent(); - }, sampleEmit, }; diff --git a/components/zoho_workdrive/zoho_workdrive.app.mjs b/components/zoho_workdrive/zoho_workdrive.app.mjs index 92fecd795c92b..6aec03cda6a64 100644 --- a/components/zoho_workdrive/zoho_workdrive.app.mjs +++ b/components/zoho_workdrive/zoho_workdrive.app.mjs @@ -7,7 +7,7 @@ export default { propDefinitions: { teamId: { type: "string", - label: "Team Id", + label: "Team ID", description: "The unique ID that represents a team.", async options() { const { data: { id: userId } } = await this.getUser(); @@ -25,16 +25,17 @@ export default { }, parentId: { type: "string", - label: "Parent Id", - description: "The unique ID of the folder where files are to be uploaded.", + label: "Parent ID", + description: "The unique ID of the folder where files are to be uploaded. Select a folder to view its subfolders.", async options({ - page, teamId, folderType, + page, teamId, folderType, includeSubfolders = false, }) { return await this.listRootFolders({ folderType, teamId, limit: LIMIT, offset: LIMIT * page, + includeSubfolders, }); }, }, @@ -106,7 +107,7 @@ export default { }); }, async listRootFolders({ - teamId, folderType, limit, offset, params = {}, ...args + teamId, folderType, limit, offset, params = {}, includeSubfolders = true, ...args }) { const { data: { id: teamCurrentUserId } } = await this.getTeamCurrentUser({ teamId, @@ -138,11 +139,13 @@ export default { value: id, label: attributes.name, }); - const subFolders = await this.paginateFolders({ - folderId: id, - prefix: "- ", - }); - reponseArray.push(...subFolders); + if (includeSubfolders) { + const subFolders = await this.paginateFolders({ + folderId: id, + prefix: "- ", + }); + reponseArray.push(...subFolders); + } } return reponseArray; },