This is the script I created and now try to refine:

function(properties, context) {
  const JSZip = require("jszip");
  const axios = require("axios");
  const FormData = require("form-data");

  // 1) Create a new zip instance.
  const zip = new JSZip();

  // 2) Read and validate input properties.
  const folderStructure = properties.folder_structure || "{}";
  const outputFileName = properties.output_file_name || "output.zip";
  let fileUploadBaseURL = properties.bubble_website_url ? String(properties.bubble_website_url) : "";

  // Validate that the upload base URL starts with "https://"
  if (!fileUploadBaseURL.startsWith("https://")) {
    throw new Error(
      "Invalid file_upload_url (must start with 'https://'). Provided: " +
        fileUploadBaseURL
    );
  }
  // Remove any trailing slash.
  fileUploadBaseURL = fileUploadBaseURL.replace(/\/$/, "");

  // 3) Parse the folder structure JSON.
  let folderData;
  try {
    folderData = JSON.parse(folderStructure);
  } catch (err) {
    throw new Error("Invalid JSON for 'folder_structure': " + err.message);
  }

// 4) Recursive function to add files (or folders) to the zip.
function addToZip(currentFolder, data) {
  let promises = [];

  for (let key in data) {
    const value = data[key];

    // If the value is a string…
    if (typeof value === "string") {
      // …and if it starts with "https://", download it.
      if (value.startsWith("https://")) {
        const p = axios
          .get(value, { responseType: "arraybuffer" })
          .then(resp => {
            // Log download info.
            console.log(
              Downloaded "${key}" from ${value} with ${resp.data.byteLength} bytes
            );
            // Add the downloaded file to the current folder in the zip.
            currentFolder.file(key, resp.data, { binary: true });
          })
          .catch(err => {
            console.warn(⚠️ Failed to download "${value}": ${err.message});
          });
        promises.push(p);
      } else {
        // Otherwise, treat the string as plain text content.
        currentFolder.file(key, value);
      }
    } else if (value && typeof value === "object") {
      // If the value is an object, treat it as a nested folder.
      const subFolder = currentFolder.folder(key);
      // Recursively add the nested folder's contents.
      promises = promises.concat(addToZip(subFolder, value));
    }
  }

  return promises;
}

  // 5) Determine the attachment parameters.
  let thingToConnect = properties.thing_to_connect;
  let attachType = null;
  let attachID = null;

  if (thingToConnect && typeof thingToConnect === "object") {
    if (
      thingToConnect._pointer &&
      thingToConnect._pointer._id &&
      thingToConnect._pointer._type
    ) {
      attachType = thingToConnect._pointer._type;
      attachID = thingToConnect._pointer._id;
    } else if (thingToConnect.datatype && thingToConnect.unique_id) {
      attachType = thingToConnect.datatype;
      attachID = thingToConnect.unique_id;
    }
  } else if (typeof thingToConnect === "string" && thingToConnect.length > 5) {
    console.warn(
      "⚠️ Received a plain string for thing_to_connect, but no type info. Not attaching."
    );
  }

  // 6) Build the file upload URL.
  let fileUploadURL = ${fileUploadBaseURL}/fileupload;

  // 7) Download all files, add them to the zip, and then generate the ZIP buffer.
  const promises = addToZip(zip, folderData);

  return Promise.all(promises)
    .then(() => zip.generateAsync({ type: "nodebuffer" }))
    .then(buffer => {
      // Create a FormData instance and append the zip file.
      const form = new FormData();
      form.append("file", buffer, {
        filename: outputFileName,
        contentType: "application/zip"
      });

      // Attach the file to a Thing if a valid attachment was provided.
      if (attachID) {
        form.append("attach_to", attachID);
        form.append("private", "true");
        console.log(🔗 Attaching to: ${attachType} (ID: ${attachID}));
      } else {
        console.warn("⚠️ No valid Thing detected. File will not be attached.");
      }

      // Upload the ZIP file.
      return axios.post(fileUploadURL, form, {
        headers: form.getHeaders()
      });
    })
    .then(resp => {
      // 8) Process Bubble's response.
      const data = resp.data;
      let fileUrl;

      if (typeof data === "string") {
        fileUrl = data.trim();
      } else if (data && data.url) {
        fileUrl = data.url;
      } else {
        throw new Error("File upload failed. Unexpected response: " + JSON.stringify(data));
      }

      // Fix protocol-relative URLs.
      if (fileUrl.startsWith("//")) {
        fileUrl = "https:" + fileUrl;
      }

      // Return the file URL in a way that Bubble expects.
      return {
        zip_file_url: fileUrl,
        zip_file: fileUrl
      };
    })
    .catch(err => {
      throw new Error("Error generating ZIP file: " + err.message);
    });
}