@composio/core
Version:

478 lines (471 loc) • 15.9 kB
JavaScript
const require_chunk = require('./chunk-CQwRTUmo.cjs');
let _composio_client = require("@composio/client");
let zod_v3 = require("zod/v3");
let chalk = require("chalk");
chalk = require_chunk.__toESM(chalk);
//#region src/utils/env.ts
const getEnvVariable = (name, defaultValue = void 0) => {
try {
return process.env[name] || defaultValue;
} catch (_e) {
return defaultValue;
}
};
/**
* Method to return all the envs based on a specific prefix
* @param prefix
* @example
* COMPOSIO_TOOLKIT_VERSION_GITHUB=20250902_00
* COMPOSIO_TOOLKIT_VERSION_SLACK=20250902_00
* COMPOSIO_TOOLKIT_VERSION_GMAIL=latest
* @returns {Record<string, unknown>}
* @returns
*/
const getEnvsWithPrefix = (prefix) => {
try {
if (process && process.env) return Object.fromEntries(Object.entries(process.env).filter(([key]) => key.startsWith(prefix)));
else return {};
} catch (error) {
return {};
}
};
//#endregion
//#region src/utils/constants.ts
var constants_exports = /* @__PURE__ */ require_chunk.__exportAll({
CLIENT_PUSHER_KEY: () => CLIENT_PUSHER_KEY,
COMPOSIO_DIR: () => COMPOSIO_DIR,
COMPOSIO_LOG_LEVEL: () => COMPOSIO_LOG_LEVEL,
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
DEFAULT_WEB_URL: () => DEFAULT_WEB_URL,
IS_DEVELOPMENT_OR_CI: () => IS_DEVELOPMENT_OR_CI,
TELEMETRY_URL: () => TELEMETRY_URL,
TEMP_FILES_DIRECTORY_NAME: () => TEMP_FILES_DIRECTORY_NAME,
USER_DATA_FILE_NAME: () => USER_DATA_FILE_NAME
});
const COMPOSIO_DIR = ".composio";
const USER_DATA_FILE_NAME = "user_data.json";
const TEMP_FILES_DIRECTORY_NAME = "files";
const DEFAULT_BASE_URL = "https://backend.composio.dev";
const DEFAULT_WEB_URL = "https://platform.composio.dev";
const TELEMETRY_URL = "https://app.composio.dev";
const CLIENT_PUSHER_KEY = getEnvVariable("CLIENT_PUSHER_KEY") || "ff9f18c208855d77a152";
const COMPOSIO_LOG_LEVEL = getEnvVariable("COMPOSIO_LOG_LEVEL");
const IS_DEVELOPMENT_OR_CI = getEnvVariable("DEVELOPMENT") || getEnvVariable("CI") || false;
//#endregion
//#region src/utils/logger.ts
const LOG_LEVELS = {
silent: -1,
error: 0,
warn: 1,
info: 2,
debug: 3
};
/**
* Get the current log level from environment variables.
* Defaults to 'info' if not set or invalid.
* @returns {LogLevel} The current log level
*/
const getLogLevel = () => {
const envLevel = (COMPOSIO_LOG_LEVEL ?? "info")?.toLowerCase();
return envLevel && envLevel in LOG_LEVELS ? envLevel : "info";
};
var Logger = class {
level;
includeTimestamp;
console;
constructor(options = {}) {
this.level = options.level ?? getLogLevel();
this.includeTimestamp = options.includeTimestamp ?? true;
this.console = console;
}
formatMessage(args) {
const formattedArgs = args.map((arg, index) => {
if (typeof arg === "object") return JSON.stringify(arg);
else {
if (index === 0) if (args.length > 1) return chalk.default.yellow(`${arg}`);
else return String(arg);
return String(arg);
}
}).join("\n");
if (!this.includeTimestamp) return formattedArgs;
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
return `${chalk.default.gray(timestamp)} - ${formattedArgs}`;
}
shouldLog(level) {
return LOG_LEVELS[level] <= LOG_LEVELS[this.level];
}
error(...args) {
if (this.shouldLog("error")) this.console.error(this.formatMessage(args));
}
warn(...args) {
if (this.shouldLog("warn")) this.console.warn(this.formatMessage(args));
}
info(...args) {
if (this.shouldLog("info")) this.console.info(this.formatMessage(args));
}
debug(...args) {
if (this.shouldLog("debug")) this.console.debug(this.formatMessage(args));
}
};
const logger = new Logger();
var logger_default = logger;
//#endregion
//#region src/errors/ComposioError.ts
/**
* @fileoverview Error class for Composio.
*
* This error class is used to create custom errors for Composio.
* It extends the built-in Error class and adds additional properties for code, status code, cause, meta, and possible fixes.
*
* @author Musthaq Ahamad <musthaq@composio.dev>
* @module errors/ComposioError
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error}
*/
/**
* Base error class for all Composio errors
*/
var ComposioError = class ComposioError extends Error {
/** @readonly Error name */
name = "ComposioError";
code;
possibleFixes;
errorId;
/**
* Creates a new ComposioError
* @param message Error message
* @param options Additional error options
*/
constructor(message, options = {}) {
super(message);
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
const statusCode = options.statusCode || (options.cause instanceof _composio_client.BadRequestError ? options.cause.status : void 0);
this.code = `TS-SDK::${options.code}`;
this.possibleFixes = options.possibleFixes;
this.definePropertyIfExists("statusCode", statusCode);
this.definePropertyIfExists("cause", options.cause);
const combinedStack = options.cause instanceof Error ? ComposioError.combineStackTraces(options.cause.stack, this.stack) : options.stack ?? this.stack;
this.definePropertyIfExists("stack", combinedStack);
if (options.meta && Object.keys(options.meta).length > 0) this.definePropertyIfExists("meta", options.meta);
}
/**
* Helper method to define a property only if it has a value
* @param propertyName Name of the property to define
* @param value Value to assign to the property
* @private
*/
definePropertyIfExists(propertyName, value) {
if (value !== void 0) Object.defineProperty(this, propertyName, {
value,
enumerable: true,
writable: false,
configurable: true
});
}
/**
* Helper method to combine stack traces when wrapping errors
* This ensures the full call chain is preserved
* @param originalStack The stack of the error being wrapped
* @param currentStack The stack of the wrapper error
* @returns Combined stack trace
* @private
*/
static combineStackTraces(originalStack, currentStack) {
if (!originalStack) return currentStack;
if (!currentStack) return originalStack;
const currentHeader = currentStack.split("\n")[0];
const originalStackBody = originalStack.split("\n").slice(1).join("\n");
return `${currentHeader}\n${currentStack.split("\n").slice(1).join("\n")}\n\nCaused by:\n${originalStackBody}`;
}
/**
* Extract and normalize error data for formatting
* @param includeStack Whether to include stack trace information
* @returns Structured error data for formatting
* @private
*/
getErrorData(includeStack = false) {
const data = {
name: this.name,
message: this.message
};
const { cause, code, stack, statusCode, meta, possibleFixes } = this;
if (cause !== void 0) {
const rawCause = cause;
data.cause = rawCause instanceof Error ? rawCause.message : String(rawCause);
}
if (code) data.code = code;
if (statusCode !== void 0) data.statusCode = statusCode;
if (meta) data.meta = meta;
if (possibleFixes) data.possibleFixes = possibleFixes;
if (includeStack && stack) if (stack.includes("Caused by:")) {
const [currentStack, causeStack] = stack.split("Caused by:");
data.stack = [
...currentStack.split("\n").slice(1),
"Caused by:",
...causeStack.split("\n")
];
} else data.stack = stack.split("\n").slice(1);
return data;
}
/**
* Prints a user-friendly, colorful representation of the error to the logger
* @param includeStack Whether to include the stack trace in the output (default: false)
*/
prettyPrint(includeStack = false) {
const data = this.getErrorData(includeStack);
let output = "\n" + chalk.default.bgRed.white.bold(" ERROR ") + " " + chalk.default.white.bold(data.message) + "\n";
if (data.code) output += chalk.default.yellow(`Error Code: ${data.code}`) + "\n";
if (data.statusCode !== void 0) output += chalk.default.yellow(`Status: ${data.statusCode}`) + "\n";
if (data.cause) {
output += chalk.default.gray("Reason:") + "\n";
output += " " + chalk.default.white(data.cause) + "\n";
}
if (data.meta) {
output += chalk.default.gray("Additional Information:") + "\n";
output += " " + chalk.default.white(JSON.stringify(data.meta, null, 2).replace(/\n/g, "\n ")) + "\n";
}
if (data.possibleFixes?.length) {
output += "\n" + chalk.default.cyan.bold("Try the following:") + "\n";
const fixes = data.possibleFixes?.map((fix, index) => ` ${index + 1}. ` + chalk.default.white(fix));
output += fixes?.join("\n") + "\n";
}
if (data.stack?.length) {
output += "\n" + chalk.default.gray("Stack Trace:") + "\n";
output += chalk.default.gray(data.stack.join("\n")) + "\n";
}
output += "\n";
logger_default.error(output);
}
/**
* Static factory method to create and pretty print an error in one step
* @param message Error message
* @param options Error options
* @param includeStack Whether to include the stack trace in the output
* @returns The created error instance
*/
static createAndPrint(message, options = {}, includeStack = false) {
const error = new ComposioError(message, options);
error.prettyPrint(includeStack);
return error;
}
/**
* Utility function to handle errors in a consistent way
* This properly displays the error without throwing
* @param error The error to handle
* @param options Options for error handling
*/
static handle(error, options = {}) {
const { includeStack = false, exitProcess = false } = options;
if (error instanceof ComposioError) error.prettyPrint(includeStack);
else if (error instanceof zod_v3.ZodError) this.handleZodError(error, includeStack);
else if (error instanceof Error) this.handleStandardError(error, includeStack);
else this.handleUnknownError(error);
if (exitProcess) this.throwError(error);
}
/**
* Utility function to handle errors and then throw them
* This properly displays the error and then throws it, allowing callers to catch it.
* Use this for fatal errors that should stop execution.
* @param error The error to handle and throw
* @param includeStack Whether to include the stack trace in the output
* @throws ComposioError - Always throws after displaying the error
*/
static handleAndThrow(error, includeStack = false) {
this.handle(error, { includeStack });
this.throwError(error);
}
/**
* Helper method to throw an error as a ComposioError
* @param error The error to throw
* @private
*/
static throwError(error) {
if (error instanceof ComposioError) throw error;
else if (error instanceof Error) throw new ComposioError(error.message, { cause: error });
else throw new ComposioError(String(error));
}
/**
* Helper method to handle Zod validation errors
* @param error The Zod error to handle
* @param includeStack Whether to include the stack trace
* @private
*/
static handleZodError(error, includeStack) {
logger_default.error("\n" + chalk.default.bgRed.white.bold(" ERROR ") + " " + chalk.default.white.bold(error.message));
logger_default.error(chalk.default.gray("Invalid parameters:"));
error.errors.forEach((err) => {
logger_default.error(chalk.default.yellow(err.path.join(".")) + " " + chalk.default.white(err.message));
});
logger_default.error(chalk.default.gray("Expected parameters:"));
error.errors.forEach((err) => {
logger_default.error(chalk.default.yellow(err.path.join(".")) + " " + chalk.default.white(err.message));
});
if (includeStack) {
logger_default.error("\n" + chalk.default.gray("Validation Errors:"));
error.errors.forEach((err) => {
const path = err.path.join(".");
logger_default.error(chalk.default.gray(" • ") + chalk.default.yellow(path ? `${path}: ` : "") + chalk.default.white(err.message));
});
if (error.stack) {
logger_default.error("\n" + chalk.default.gray("Stack Trace:"));
const stackLines = error.stack.split("\n").slice(1);
logger_default.error(chalk.default.gray(stackLines.join("\n")));
}
}
logger_default.error("");
}
/**
* Helper method to handle standard Error objects
* @param error The standard error to handle
* @param includeStack Whether to include the stack trace
* @private
*/
static handleStandardError(error, includeStack) {
logger_default.error("\n" + chalk.default.bgRed.white.bold(" ERROR ") + " " + chalk.default.white.bold(error.message));
if (includeStack && error.stack) {
logger_default.error("\n" + chalk.default.gray("Stack Trace:"));
const stackLines = error.stack.split("\n").slice(1);
logger_default.error(chalk.default.gray(stackLines.join("\n")));
}
logger_default.error("");
}
/**
* Helper method to handle unknown error types
* @param error The unknown error value
* @private
*/
static handleUnknownError(error) {
logger_default.error("\n" + chalk.default.bgRed.white.bold(" ERROR ") + " " + chalk.default.white.bold("Unknown error occurred"));
if (error !== null && error !== void 0) {
logger_default.error(chalk.default.gray("Error details:"));
logger_default.error(" " + chalk.default.white(String(error)));
}
logger_default.error("");
}
};
//#endregion
//#region src/utils/uuid.ts
function getRandomUUID() {
return globalThis.crypto.randomUUID();
}
function getRandomShortId() {
return getRandomUUID().slice(0, 8).replace(/-/g, "");
}
//#endregion
//#region src/utils/buffer.ts
/**
* Convert ArrayBuffer to base64.
*/
function arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binary = "";
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
return btoa(binary);
}
const base64ToUint8Array = (base64) => {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
return bytes;
};
const uint8ArrayToBase64 = (bytes) => {
let binary = "";
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
return btoa(binary);
};
//#endregion
Object.defineProperty(exports, 'COMPOSIO_DIR', {
enumerable: true,
get: function () {
return COMPOSIO_DIR;
}
});
Object.defineProperty(exports, 'COMPOSIO_LOG_LEVEL', {
enumerable: true,
get: function () {
return COMPOSIO_LOG_LEVEL;
}
});
Object.defineProperty(exports, 'ComposioError', {
enumerable: true,
get: function () {
return ComposioError;
}
});
Object.defineProperty(exports, 'DEFAULT_BASE_URL', {
enumerable: true,
get: function () {
return DEFAULT_BASE_URL;
}
});
Object.defineProperty(exports, 'IS_DEVELOPMENT_OR_CI', {
enumerable: true,
get: function () {
return IS_DEVELOPMENT_OR_CI;
}
});
Object.defineProperty(exports, 'TEMP_FILES_DIRECTORY_NAME', {
enumerable: true,
get: function () {
return TEMP_FILES_DIRECTORY_NAME;
}
});
Object.defineProperty(exports, 'USER_DATA_FILE_NAME', {
enumerable: true,
get: function () {
return USER_DATA_FILE_NAME;
}
});
Object.defineProperty(exports, 'arrayBufferToBase64', {
enumerable: true,
get: function () {
return arrayBufferToBase64;
}
});
Object.defineProperty(exports, 'base64ToUint8Array', {
enumerable: true,
get: function () {
return base64ToUint8Array;
}
});
Object.defineProperty(exports, 'constants_exports', {
enumerable: true,
get: function () {
return constants_exports;
}
});
Object.defineProperty(exports, 'getEnvVariable', {
enumerable: true,
get: function () {
return getEnvVariable;
}
});
Object.defineProperty(exports, 'getEnvsWithPrefix', {
enumerable: true,
get: function () {
return getEnvsWithPrefix;
}
});
Object.defineProperty(exports, 'getRandomShortId', {
enumerable: true,
get: function () {
return getRandomShortId;
}
});
Object.defineProperty(exports, 'getRandomUUID', {
enumerable: true,
get: function () {
return getRandomUUID;
}
});
Object.defineProperty(exports, 'logger_default', {
enumerable: true,
get: function () {
return logger_default;
}
});
Object.defineProperty(exports, 'uint8ArrayToBase64', {
enumerable: true,
get: function () {
return uint8ArrayToBase64;
}
});