diff --git a/package.json b/package.json index 112a7a5..b4863e0 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "author": "Ibrahim.H", "license": "MIT", "dependencies": { + "@heyputer/putility": "^1.0.2", "chalk": "^5.3.0", "cli-table3": "^0.6.5", "commander": "^13.0.0", diff --git a/src/commands/shell.js b/src/commands/shell.js index d3232f5..bb62566 100644 --- a/src/commands/shell.js +++ b/src/commands/shell.js @@ -4,6 +4,8 @@ import Conf from 'conf'; import { execCommand, getPrompt } from '../executor.js'; import { getAuthToken, login } from './auth.js'; import { PROJECT_NAME } from '../commons.js'; +import ErrorModule from '../modules/ErrorModule.js'; +import putility, { AdvancedBase } from '@heyputer/putility'; const config = new Conf({ projectName: PROJECT_NAME }); @@ -32,6 +34,16 @@ export async function startShell() { process.exit(0); } + const modules = [ + ErrorModule, + ]; + + const context = new putility.libs.context.Context({ + events: new putility.libs.event.Emitter(), + }); + + for ( const module of modules ) module({ context }); + try { console.log(chalk.green('Welcome to Puter-CLI! Type "help" for available commands.')); rl.setPrompt(getPrompt()); @@ -41,7 +53,7 @@ export async function startShell() { const trimmedLine = line.trim(); if (trimmedLine) { try { - await execCommand(trimmedLine); + await execCommand(context, trimmedLine); } catch (error) { console.error(chalk.red(error.message)); } diff --git a/src/commands/sites.js b/src/commands/sites.js index d51fe23..401b329 100644 --- a/src/commands/sites.js +++ b/src/commands/sites.js @@ -5,12 +5,13 @@ import { getCurrentUserName, getCurrentDirectory } from './auth.js'; import { API_BASE, getHeaders, generateAppName, resolvePath, isValidAppName } from '../commons.js'; import { displayNonNullValues, formatDate, isValidAppUuid } from '../utils.js'; import { getSubdomains, createSubdomain, deleteSubdomain } from './subdomains.js'; +import { ErrorAPI } from '../modules/ErrorModule.js'; /** * Listing subdomains */ -export async function listSites(args = {}) { +export async function listSites(args = {}, context) { try { const data = await getSubdomains(args); @@ -57,6 +58,7 @@ export async function listSites(args = {}) { } } catch (error) { + context.events.emit('error', { error }); console.error(chalk.red('Error listing sites:'), error.message); throw error; } diff --git a/src/commons.js b/src/commons.js index d3b3034..bd44760 100644 --- a/src/commons.js +++ b/src/commons.js @@ -6,8 +6,8 @@ import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; export const PROJECT_NAME = 'puter-cli'; -export const API_BASE = 'https://api.puter.com'; -export const BASE_URL = 'https://puter.com'; +export const API_BASE = 'http://api.puter.localhost:4100'; +export const BASE_URL = 'http://puter.localhost:4100'; /** * Get headers with the correct Content-Type for multipart form data. diff --git a/src/executor.js b/src/executor.js index 082770b..bad2601 100644 --- a/src/executor.js +++ b/src/executor.js @@ -12,6 +12,7 @@ import inquirer from 'inquirer'; import { exec } from 'node:child_process'; import { parseArgs } from './utils.js'; import { rl } from './commands/shell.js'; +import { ErrorAPI } from './modules/ErrorModule.js'; const config = new Conf({ projectName: PROJECT_NAME }); @@ -61,6 +62,9 @@ const commands = { rl.write(commandToCopy); } }, + 'last-error': async (_, context) => { + context[ErrorAPI].showLast(); + }, 'app:create': async (rawArgs) => { try { const args = parseArgs(rawArgs.join(' ')); @@ -150,7 +154,7 @@ const commands = { * Execute a command * @param {string} input The command line input */ -export async function execCommand(input) { +export async function execCommand(context, input) { const [cmd, ...args] = input.split(' '); @@ -184,7 +188,7 @@ export async function execCommand(input) { } if (commands[cmd]) { try { - await commands[cmd](args); + await commands[cmd](args, context); } catch (error) { console.error(chalk.red(`Error executing command: ${error.message}`)); } diff --git a/src/modules/ErrorModule.js b/src/modules/ErrorModule.js new file mode 100644 index 0000000..51eaedd --- /dev/null +++ b/src/modules/ErrorModule.js @@ -0,0 +1,33 @@ +const ERROR_BUFFER_LIMIT = 20; + +export const ErrorAPI = Symbol('ErrorAPI'); + +export default ({ context }) => { + // State Variables + const errors = []; + + context.events.on('error', (error) => { + context[ErrorAPI].report(error); + }); + + // Module Methods + context[ErrorAPI] = { + // Add an error to the error history + report (error) { + errors.push(error); + if (errors.length > ERROR_BUFFER_LIMIT) { + errors = errors.slice(errors.length - ERROR_BUFFER_LIMIT); + } + }, + // Print the last error from the error history, + // and remove it from the history + showLast () { + const err = errors.pop(); + if (err) { + console.error(err); + } else { + console.log('No errors to report'); + } + } + }; +};