From 2cee1b5a7ce08a6c4e157e89a0709ea1dd927a00 Mon Sep 17 00:00:00 2001 From: Ayush Pahwa Date: Sat, 17 Jul 2021 20:26:06 +0530 Subject: [PATCH] Added axios call to the special use case of downloading zip files (#5927) * Added axios call to the special use case of downloading zip files * Removed console logs, added comments, fixed error handling * Removed url check from getType, exported a fn to check tif string is a URL * Changed filter from only zip to binary --- app/client/src/sagas/ActionExecutionSagas.ts | 26 +++++++++++++++++++- app/client/src/utils/TypeHelpers.ts | 14 +++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/client/src/sagas/ActionExecutionSagas.ts b/app/client/src/sagas/ActionExecutionSagas.ts index 27725b110a..c28a7e7401 100644 --- a/app/client/src/sagas/ActionExecutionSagas.ts +++ b/app/client/src/sagas/ActionExecutionSagas.ts @@ -80,7 +80,8 @@ import { } from "actions/pageActions"; import { getAppStoreName } from "constants/AppConstants"; import downloadjs from "downloadjs"; -import { getType, Types } from "utils/TypeHelpers"; +import Axios from "axios"; +import { getType, isURL, Types } from "utils/TypeHelpers"; import { Toaster } from "components/ads/Toast"; import { Variant } from "components/ads/common"; import PerformanceTracker, { @@ -259,6 +260,29 @@ async function downloadSaga( AppsmithConsole.info({ text: `download('${jsonString}', '${name}', '${type}') was triggered`, }); + } else if ( + dataType === Types.STRING && + isURL(data) && + type === "application/x-binary" + ) { + // Requires a special handling for the use case when the user is trying to download a binary file from a URL + // due to incompatibility in the downloadjs library. In this case we are going to fetch the file from the URL + // using axios with the arraybuffer header and then pass it to the downloadjs library. + Axios.get(data, { responseType: "arraybuffer" }) + .then((res) => { + downloadjs(res.data, name, type); + AppsmithConsole.info({ + text: `download('${data}', '${name}', '${type}') was triggered`, + }); + }) + .catch((error) => { + log.error(error); + Toaster.show({ + text: createMessage(ERROR_WIDGET_DOWNLOAD, error), + variant: Variant.danger, + }); + if (event.callback) event.callback({ success: false }); + }); } else { downloadjs(data, name, type); AppsmithConsole.info({ diff --git a/app/client/src/utils/TypeHelpers.ts b/app/client/src/utils/TypeHelpers.ts index 8a00efc3a4..9b78ad223f 100644 --- a/app/client/src/utils/TypeHelpers.ts +++ b/app/client/src/utils/TypeHelpers.ts @@ -1,6 +1,7 @@ import _ from "lodash"; export enum Types { + URL = "URL", STRING = "STRING", NUMBER = "NUMBER", BOOLEAN = "BOOLEAN", @@ -23,3 +24,16 @@ export const getType = (value: unknown) => { if (_.isNull(value)) return Types.NULL; return Types.UNKNOWN; }; + +export function isURL(str: string) { + const pattern = new RegExp( + "^(https?:\\/\\/)?" + // protocol + "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name + "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address + "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path + "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string + "(\\#[-a-z\\d_]*)?$", + "i", + ); // fragment locator + return !!pattern.test(str); +}