UNPKG

@composio/core

Version:

![Composio Banner](https://github.com/user-attachments/assets/9ba0e9c1-85a4-4b51-ae60-f9fe7992e819)

220 lines (218 loc) 8.23 kB
import { c as TEMP_FILES_DIRECTORY_NAME, n as logger_default, r as COMPOSIO_DIR } from "./ComposioError-ChkSdxqU.mjs"; import { i as getRandomShortId, n as base64ToUint8Array, r as uint8ArrayToBase64 } from "./buffer-yOtEsT4J.mjs"; import { platform } from "#platform"; import crypto from "node:crypto"; //#region src/utils/fileUtils.node.ts const getExtensionFromMimeType = (mimeType) => { const mimeToExt = { "text/plain": "txt", "text/html": "html", "text/css": "css", "text/javascript": "js", "application/json": "json", "application/xml": "xml", "application/pdf": "pdf", "application/zip": "zip", "application/x-zip-compressed": "zip", "application/gzip": "gz", "application/x-tar": "tar", "application/msword": "doc", "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx", "application/vnd.ms-excel": "xls", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx", "application/vnd.ms-powerpoint": "ppt", "application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx", "image/jpeg": "jpg", "image/jpg": "jpg", "image/png": "png", "image/gif": "gif", "image/svg+xml": "svg", "image/webp": "webp", "image/bmp": "bmp", "image/tiff": "tiff", "audio/mpeg": "mp3", "audio/wav": "wav", "audio/ogg": "ogg", "video/mp4": "mp4", "video/mpeg": "mpeg", "video/quicktime": "mov", "video/x-msvideo": "avi", "video/webm": "webm" }; const cleanMimeType = mimeType.split(";")[0].toLowerCase().trim(); if (mimeToExt[cleanMimeType]) return mimeToExt[cleanMimeType]; const parts = cleanMimeType.split("/"); if (parts.length === 2) { const cleanSubtype = parts[1].toLowerCase(); if (cleanSubtype.includes("+")) { const plusParts = cleanSubtype.split("+"); const prefix = plusParts[0]; const suffix = plusParts[plusParts.length - 1]; if ([ "svg", "atom", "rss" ].includes(prefix)) return prefix; if ([ "json", "xml", "yaml", "zip", "gzip" ].includes(suffix)) return suffix; return suffix; } return cleanSubtype || "txt"; } return "txt"; }; const generateTimestampedFilename = (extension, prefix) => { return `${prefix || "file_ts"}${Date.now()}${getRandomShortId()}.${extension}`; }; const readFileContent = async (filePath) => { try { if (!platform.supportsFileSystem) throw new Error("File system operations are not supported in this runtime environment"); const content = platform.readFileSync(filePath); return { fileName: generateTimestampedFilename(filePath.split(".").pop() || "txt"), content: content instanceof Uint8Array ? uint8ArrayToBase64(content) : uint8ArrayToBase64(new TextEncoder().encode(content)), mimeType: "application/octet-stream" }; } catch (error) { throw new Error(`Error reading file at ${filePath}: ${error}`); } }; const readFileContentFromURL = async (path) => { const response = await fetch(path); if (!response.ok) throw new Error(`Failed to fetch file: ${response.statusText}`); const arrayBuffer = await response.arrayBuffer(); const content = new Uint8Array(arrayBuffer); const mimeType = response.headers.get("content-type") || "application/octet-stream"; const pathname = new URL(path).pathname; let fileName = platform.basename(pathname); if (!fileName || fileName === "/") fileName = generateTimestampedFilename(getExtensionFromMimeType(mimeType)); else if (!fileName.includes(".")) fileName = generateTimestampedFilename(getExtensionFromMimeType(mimeType)); return { content: uint8ArrayToBase64(content), mimeType, fileName }; }; const uploadFileToS3 = async (fileName, content, toolSlug, toolkitSlug, mimeType, client) => { const contentBytes = base64ToUint8Array(content); const { key, new_presigned_url: signedURL } = await client.files.createPresignedURL({ filename: fileName, mimetype: mimeType, md5: crypto.createHash("md5").update(contentBytes).digest("hex"), tool_slug: toolSlug, toolkit_slug: toolkitSlug }); logger_default.debug(`Uploading ${key} file to S3: ${key}`); const uploadBuffer = new Uint8Array(contentBytes.byteLength); uploadBuffer.set(contentBytes); const uploadResponse = await fetch(signedURL, { method: "PUT", body: uploadBuffer, headers: { "Content-Type": mimeType, "Content-Length": contentBytes.length.toString() } }); if (!uploadResponse.ok) throw new Error(`Failed to upload file to S3: ${uploadResponse.statusText}`); return key; }; const readFile = async (file) => { if (file instanceof File) { const content = await file.arrayBuffer(); return { fileName: file.name, content: uint8ArrayToBase64(new Uint8Array(content)), mimeType: file.type }; } else if (typeof file === "string") if (file.startsWith("http")) return await readFileContentFromURL(file); else return await readFileContent(file); throw new Error("Invalid file type"); }; const getFileDataAfterUploadingToS3 = async (file, { toolSlug, toolkitSlug, client }) => { if (!file) throw new Error("Either path or blob must be provided"); const fileData = await readFile(file); logger_default.debug(`Uploading file to S3...`); const s3key = await uploadFileToS3(platform.basename(fileData.fileName), fileData.content, toolSlug, toolkitSlug, fileData.mimeType, client); logger_default.debug(`Done! File uploaded to S3: ${s3key}`, JSON.stringify(fileData, null, 2)); return { name: fileData.fileName, mimetype: fileData.mimeType, s3key }; }; const downloadFileFromS3 = async ({ toolSlug, s3Url, mimeType }) => { const response = await fetch(s3Url); if (!response.ok) throw new Error(`Failed to download file: ${response.statusText}`); const data = await response.arrayBuffer(); const fileName = generateTimestampedFilename(getExtensionFromMimeType(mimeType), `${toolSlug}_`); return { name: fileName, mimeType, s3Url, filePath: saveFile(fileName, new Uint8Array(data), true) }; }; /** * Gets the Composio directory. * @param createDirIfNotExists - Whether to create the directory if it doesn't exist. * @returns The path to the Composio directory. */ const getComposioDir = (createDirIfNotExists = false) => { try { const homeDir = platform.homedir(); if (!homeDir) return null; const composioDir = platform.joinPath(homeDir, COMPOSIO_DIR); if (createDirIfNotExists && platform.supportsFileSystem && !platform.existsSync(composioDir)) platform.mkdirSync(composioDir); return composioDir; } catch (_error) { return null; } }; /** * Gets the Composio temporary files directory. * @param createDirIfNotExists - Whether to create the directory if it doesn't exist. * @returns The path to the Composio temporary files directory. */ const getComposioTempFilesDir = (createDirIfNotExists = false) => { try { const homeDir = platform.homedir(); if (!homeDir) return null; const composioFilesDir = platform.joinPath(homeDir, COMPOSIO_DIR, TEMP_FILES_DIRECTORY_NAME); if (createDirIfNotExists && platform.supportsFileSystem && !platform.existsSync(composioFilesDir)) platform.mkdirSync(composioFilesDir); return composioFilesDir; } catch (_error) { return null; } }; /** * Saves a file to the Composio directory. * @param file - The name of the file to save. * @param content - The content of the file to save. Can be a string or Uint8Array. * @param isTempFile - Whether the file is a temporary file. * @returns The path to the saved file. */ const saveFile = (file, content, isTempFile = false) => { try { if (!platform.supportsFileSystem) { logger_default.debug("File system operations are not supported in this runtime environment"); return null; } const composioFilesDir = isTempFile ? getComposioTempFilesDir(true) : getComposioDir(true); if (!composioFilesDir) return null; const filePath = platform.joinPath(composioFilesDir, platform.basename(file)); logger_default.info(`Saving file to: ${filePath}`); if (content instanceof Uint8Array) platform.writeFileSync(filePath, content); else platform.writeFileSync(filePath, content, "utf8"); return filePath; } catch (_error) { logger_default.debug(`Error saving file: ${_error}`); return null; } }; //#endregion export { getFileDataAfterUploadingToS3 as n, downloadFileFromS3 as t };