From a5578fcd2c8ef0d8f301170fa19c2c1998aa6ccf Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Tue, 23 Sep 2025 10:47:07 -0400 Subject: [PATCH 1/2] wip --- .../actions/delete-file/delete-file.mjs | 26 ++++++ .../actions/list-files/list-files.mjs | 65 +++++++++++++++ .../actions/update-file/update-file.mjs | 42 ++++++++++ .../upload-file-to-folder.mjs | 53 ++++++++++++ .../actions/upload-file/upload-file.mjs | 6 +- components/xero_accounting_api/package.json | 3 +- .../xero_accounting_api.app.mjs | 83 ++++++++++++++++++- 7 files changed, 272 insertions(+), 6 deletions(-) create mode 100644 components/xero_accounting_api/actions/delete-file/delete-file.mjs create mode 100644 components/xero_accounting_api/actions/list-files/list-files.mjs create mode 100644 components/xero_accounting_api/actions/update-file/update-file.mjs create mode 100644 components/xero_accounting_api/actions/upload-file-to-folder/upload-file-to-folder.mjs diff --git a/components/xero_accounting_api/actions/delete-file/delete-file.mjs b/components/xero_accounting_api/actions/delete-file/delete-file.mjs new file mode 100644 index 0000000000000..33e11437661ed --- /dev/null +++ b/components/xero_accounting_api/actions/delete-file/delete-file.mjs @@ -0,0 +1,26 @@ +import xeroAccountingApi from "../../xero_accounting_api.app.mjs"; + +export default { + key: "xero_accounting_api-delete-file", + name: "Delete File", + description: "Delete a file. [See the documentation](https://developer.xero.com/documentation/api/files/files#delete-files)", + version: "0.0.{{ts}}", + type: "action", + props: { + xeroAccountingApi, + fileId: { + propDefinition: [ + xeroAccountingApi, + "fileId", + ], + }, + }, + async run({ $ }) { + const response = await this.xeroAccountingApi.deleteFile({ + $, + fileId: this.fileId, + }); + $.export("$summary", `Successfully deleted file with ID: ${this.fileId}`); + return response; + }, +}; diff --git a/components/xero_accounting_api/actions/list-files/list-files.mjs b/components/xero_accounting_api/actions/list-files/list-files.mjs new file mode 100644 index 0000000000000..f8d9e9a9447cb --- /dev/null +++ b/components/xero_accounting_api/actions/list-files/list-files.mjs @@ -0,0 +1,65 @@ +import xeroAccountingApi from "../../xero_accounting_api.app.mjs"; + +export default { + key: "xero_accounting_api-list-files", + name: "List Files", + description: "List files. [See the documentation](https://developer.xero.com/documentation/api/files/files#get-files)", + version: "0.0.{{ts}}", + type: "action", + props: { + xeroAccountingApi, + pagesize: { + type: "integer", + label: "Page Size", + description: "The number of records returned within a single API call", + optional: true, + default: 100, + min: 1, + max: 100, + }, + page: { + type: "integer", + label: "Page", + description: "The page number of the current page in the returned records", + optional: true, + default: 1, + }, + sort: { + type: "string", + label: "Sort", + description: "The field to sort the records by", + optional: true, + options: [ + "Name", + "Size", + "CreatedDateUTC", + ], + }, + direction: { + type: "string", + label: "Direction", + description: "The direction to sort the records by", + optional: true, + options: [ + "ASC", + "DESC", + ], + }, + }, + async run({ $ }) { + const { Items: items } = await this.xeroAccountingApi.listFiles({ + $, + params: { + pageSize: this.pagesize, + page: this.page, + sort: this.sort, + direction: this.direction, + }, + }); + + $.export("$summary", `Successfully retrieved ${items.length} file${items.length === 1 + ? "" + : "s"}`); + return items; + }, +}; diff --git a/components/xero_accounting_api/actions/update-file/update-file.mjs b/components/xero_accounting_api/actions/update-file/update-file.mjs new file mode 100644 index 0000000000000..a2014d1b5760a --- /dev/null +++ b/components/xero_accounting_api/actions/update-file/update-file.mjs @@ -0,0 +1,42 @@ +import xeroAccountingApi from "../../xero_accounting_api.app.mjs"; + +export default { + key: "xero_accounting_api-update-file", + name: "Update File", + description: "Rename a file or move it to a different folder. [See the documentation](https://developer.xero.com/documentation/api/files/files#put-files)", + version: "0.0.{{ts}}", + type: "action", + props: { + xeroAccountingApi, + fileId: { + propDefinition: [ + xeroAccountingApi, + "fileId", + ], + }, + name: { + type: "string", + label: "Name", + description: "The new name of the file", + optional: true, + }, + folderId: { + propDefinition: [ + xeroAccountingApi, + "folderId", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.xeroAccountingApi.updateFile(this.fileId, { + $, + data: { + Name: this.name, + FolderId: this.folderId, + }, + }); + $.export("$summary", `Successfully updated file with ID: ${this.fileId}`); + return response; + }, +}; diff --git a/components/xero_accounting_api/actions/upload-file-to-folder/upload-file-to-folder.mjs b/components/xero_accounting_api/actions/upload-file-to-folder/upload-file-to-folder.mjs new file mode 100644 index 0000000000000..60fb7c0a06957 --- /dev/null +++ b/components/xero_accounting_api/actions/upload-file-to-folder/upload-file-to-folder.mjs @@ -0,0 +1,53 @@ +import xeroAccountingApi from "../../xero_accounting_api.app.mjs"; +import { getFileStreamAndMetadata } from "@pipedream/platform"; +import FormData from "form-data"; + +export default { + key: "xero_accounting_api-upload-file-to-folder", + name: "Upload File to Folder", + description: "Upload a file to a folder. [See the documentation](https://developer.xero.com/documentation/api/files/files#post-files)", + version: "0.0.{{ts}}", + type: "action", + props: { + xeroAccountingApi, + filePathOrUrl: { + type: "string", + 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/myFile.txt`)", + }, + folderId: { + propDefinition: [ + xeroAccountingApi, + "folderId", + ], + }, + syncDir: { + type: "dir", + accessMode: "read", + sync: true, + optional: true, + }, + }, + async run({ $ }) { + const { + stream, metadata, + } = await getFileStreamAndMetadata(this.filePathOrUrl); + + const data = new FormData(); + data.append("Xero", stream, { + contentType: metadata.contentType, + knownLength: metadata.size, + filename: metadata.name, + }); + + const response = await this.xeroAccountingApi.uploadFileToFolder({ + $, + folderId: this.folderId, + data, + headers: data.getHeaders(), + }); + + $.export("$summary", `Successfully uploaded file to folder with ID: ${this.folderId}`); + return response; + }, +}; diff --git a/components/xero_accounting_api/actions/upload-file/upload-file.mjs b/components/xero_accounting_api/actions/upload-file/upload-file.mjs index 72f53dedd5bcf..9db860573da41 100644 --- a/components/xero_accounting_api/actions/upload-file/upload-file.mjs +++ b/components/xero_accounting_api/actions/upload-file/upload-file.mjs @@ -3,9 +3,9 @@ import xeroAccountingApi from "../../xero_accounting_api.app.mjs"; export default { key: "xero_accounting_api-upload-file", - name: "Upload File", + name: "Upload File (Attachment)", description: "Uploads a file to the specified document. [See the documentation](https://developer.xero.com/documentation/api/accounting/invoices#upload-attachment)", - version: "1.0.2", + version: "1.0.3", type: "action", props: { xeroAccountingApi, @@ -64,7 +64,7 @@ export default { } = await getFileStreamAndMetadata(this.filePathOrUrl); const fileBinary = await this.streamToBuffer(stream); - const response = await this.xeroAccountingApi.uploadFile({ + const response = await this.xeroAccountingApi.uploadAttachment({ $, tenantId: this.tenantId, documentType: this.documentType, diff --git a/components/xero_accounting_api/package.json b/components/xero_accounting_api/package.json index 0e2b3bffebb7c..9a91d8d157f57 100644 --- a/components/xero_accounting_api/package.json +++ b/components/xero_accounting_api/package.json @@ -10,7 +10,8 @@ "homepage": "https://pipedream.com/apps/xero_accounting_api", "author": "Pipedream (https://pipedream.com/)", "dependencies": { - "@pipedream/platform": "^3.1.0" + "@pipedream/platform": "^3.1.0", + "form-data": "^4.0.4" }, "publishConfig": { "access": "public" diff --git a/components/xero_accounting_api/xero_accounting_api.app.mjs b/components/xero_accounting_api/xero_accounting_api.app.mjs index a6e1dc32c1c9f..072f0357254db 100644 --- a/components/xero_accounting_api/xero_accounting_api.app.mjs +++ b/components/xero_accounting_api/xero_accounting_api.app.mjs @@ -77,6 +77,38 @@ export default { label: "Line items", description: "The LineItems collection can contain any number of individual LineItem sub-elements. At least one is required to create a complete Invoice. [Refer to Tax Type](https://developer.xero.com/documentation/api/accounting/types#report-tax-types), [Refer to Line Items](https://developer.xero.com/documentation/api/accounting/invoices#creating-updating-and-deleting-line-items-when-updating-invoices)\n\n**Example:** `[{\"Description\":\"Football\", \"Quantity\":\"20\", \"UnitAmount\":\"50000\", \"TaxType\":\"OUTPUT\" }]`", }, + fileId: { + type: "string", + label: "File ID", + description: "Unique identification of the file", + async options({ page }) { + const { Items: items } = await this.listFiles({ + params: { + page: page + 1, + }, + }); + return items?.map(({ + Id: value, Name: label, + }) => ({ + label, + value, + })) || []; + }, + }, + folderId: { + type: "string", + label: "Folder ID", + description: "Unique identification of the folder", + async options() { + const folders = await this.listFolders(); + return folders?.map(({ + Id: value, Name: label, + }) => ({ + label, + value, + })) || []; + }, + }, }, methods: { setLastDateChecked(db, value) { @@ -102,10 +134,13 @@ export default { modifiedSince, path, headers, + isFilesApi = false, ...opts }) { return axios($, { - url: `${BASE_URL}/api.xro/2.0${path}`, + url: `${BASE_URL}${(isFilesApi + ? "/files.xro/1.0" + : "/api.xro/2.0")}${path}`, headers: this.getHeader({ tenantId, modifiedSince, @@ -356,7 +391,7 @@ export default { ...opts, }); }, - uploadFile({ + uploadAttachment({ documentType, documentId, fileName, ...opts }) { return this._makeRequest({ @@ -388,5 +423,49 @@ export default { ...opts, }); }, + listFiles(opts = {}) { + return this._makeRequest({ + path: "/Files", + isFilesApi: true, + ...opts, + }); + }, + uploadFileToFolder({ + folderId, ...opts + }) { + return this._makeRequest({ + method: "POST", + path: `/Files/${folderId}`, + isFilesApi: true, + ...opts, + }); + }, + updateFile({ + fileId, ...opts + }) { + return this._makeRequest({ + method: "PUT", + path: `/Files/${fileId}`, + isFilesApi: true, + ...opts, + }); + }, + deleteFile({ + fileId, ...opts + }) { + return this._makeRequest({ + method: "DELETE", + path: `/Files/${fileId}`, + isFilesApi: true, + ...opts, + }); + }, + listFolders(opts = {}) { + return this._makeRequest({ + path: "/Folders", + isFilesApi: true, + ...opts, + }); + }, }, }; From 09099a9a9e028480e9eb3da078516f232370e124 Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Fri, 26 Sep 2025 10:46:55 -0400 Subject: [PATCH 2/2] pnpm-lock.yaml --- pnpm-lock.yaml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32d2f100b784d..b1c6bc68df220 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: {} @@ -11737,8 +11736,7 @@ importers: components/redmine: {} - components/reduct_video: - specifiers: {} + components/reduct_video: {} components/referral_rocket: {} @@ -13042,8 +13040,7 @@ importers: specifier: 1.6.0 version: 1.6.0 - components/shopware: - specifiers: {} + components/shopware: {} components/short: dependencies: @@ -13850,8 +13847,7 @@ importers: components/streamwish: {} - components/strety: - specifiers: {} + components/strety: {} components/stripe: dependencies: @@ -16076,6 +16072,9 @@ importers: '@pipedream/platform': specifier: ^3.1.0 version: 3.1.0 + form-data: + specifier: ^4.0.4 + version: 4.0.4 components/xperiencify: dependencies: @@ -38941,6 +38940,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: