fix(core): Improve error handling, logging, and test suite; update dependency versions

This commit is contained in:
2025-03-10 23:38:21 +00:00
parent 5c4836fd68
commit 779593f73a
12 changed files with 1648 additions and 236 deletions

109
ts/cli.ts
View File

@@ -1,17 +1,40 @@
import * as plugins from './plugins.js';
import * as paths from './paths.js';
import { Tspm, IProcessConfig } from './classes.tspm.js';
import { Tspm, type IProcessConfig } from './classes.tspm.js';
import {
Logger,
LogLevel,
handleError,
TspmError,
ProcessError,
ConfigError,
ValidationError
} from './utils.errorhandler.js';
export const run = async () => {
// Define interface for CLI arguments
interface CliArguments {
_: (string | number)[];
[key: string]: any;
}
export const run = async (): Promise<void> => {
const cliLogger = new Logger('CLI');
const tspmProjectinfo = new plugins.projectinfo.ProjectInfo(paths.packageDir);
const tspm = new Tspm();
// Check if debug mode is enabled
const debugMode = process.env.TSPM_DEBUG === 'true';
if (debugMode) {
cliLogger.setLevel(LogLevel.DEBUG);
cliLogger.debug('Debug mode enabled');
}
const smartcliInstance = new plugins.smartcli.Smartcli();
smartcliInstance.addVersion(tspmProjectinfo.npm.version);
// Default command - show help and list processes
smartcliInstance.standardCommand().subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
console.log(`TSPM - TypeScript Process Manager v${tspmProjectinfo.npm.version}`);
console.log('Usage: tspm [command] [options]');
console.log('\nCommands:');
@@ -46,7 +69,7 @@ export const run = async () => {
// Start command - start a new process
smartcliInstance.addCommand('start').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const script = argvArg._.length > 1 ? String(argvArg._[1]) : '';
if (!script) {
console.error('Error: Missing script argument. Usage: tspm start <script>');
@@ -59,6 +82,8 @@ export const run = async () => {
const memLimit = parseMemoryString(argvArg.memory || '500MB');
try {
cliLogger.debug(`Starting process with script: ${script}`);
const processConfig: IProcessConfig = {
id: argvArg.id || name.replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase(),
name: name,
@@ -71,17 +96,32 @@ export const run = async () => {
watch: Boolean(argvArg.watch)
};
cliLogger.debug(`Created process config: ${JSON.stringify(processConfig)}`);
await tspm.start(processConfig);
console.log(`Process ${processConfig.id} started successfully.`);
} catch (error) {
console.error(`Error starting process: ${error.message}`);
} catch (error: Error | unknown) {
const tspmError = handleError(error);
if (tspmError instanceof ValidationError) {
console.error(`Validation error: ${tspmError.message}`);
} else if (tspmError instanceof ProcessError) {
console.error(`Process error: ${tspmError.message}`);
if (debugMode) {
console.error(`Error details: ${JSON.stringify(tspmError.details)}`);
}
} else {
console.error(`Error starting process: ${tspmError.message}`);
}
cliLogger.error(tspmError);
}
},
});
// Start as daemon command
smartcliInstance.addCommand('startAsDaemon').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const script = argvArg._.length > 1 ? String(argvArg._[1]) : '';
if (!script) {
console.error('Error: Missing script argument. Usage: tspm startAsDaemon <script>');
@@ -114,7 +154,7 @@ export const run = async () => {
// Stop command
smartcliInstance.addCommand('stop').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const id = argvArg._.length > 1 ? String(argvArg._[1]) : '';
if (!id) {
@@ -123,17 +163,26 @@ export const run = async () => {
}
try {
cliLogger.debug(`Stopping process: ${id}`);
await tspm.stop(id);
console.log(`Process ${id} stopped.`);
} catch (error) {
console.error(`Error stopping process: ${error.message}`);
} catch (error: Error | unknown) {
const tspmError = handleError(error);
if (tspmError instanceof ValidationError) {
console.error(`Validation error: ${tspmError.message}`);
} else {
console.error(`Error stopping process: ${tspmError.message}`);
}
cliLogger.error(tspmError);
}
}
});
// Restart command
smartcliInstance.addCommand('restart').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const id = argvArg._.length > 1 ? String(argvArg._[1]) : '';
if (!id) {
@@ -142,17 +191,28 @@ export const run = async () => {
}
try {
cliLogger.debug(`Restarting process: ${id}`);
await tspm.restart(id);
console.log(`Process ${id} restarted.`);
} catch (error) {
console.error(`Error restarting process: ${error.message}`);
} catch (error: Error | unknown) {
const tspmError = handleError(error);
if (tspmError instanceof ValidationError) {
console.error(`Validation error: ${tspmError.message}`);
} else if (tspmError instanceof ProcessError) {
console.error(`Process error: ${tspmError.message}`);
} else {
console.error(`Error restarting process: ${tspmError.message}`);
}
cliLogger.error(tspmError);
}
}
});
// Delete command
smartcliInstance.addCommand('delete').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const id = argvArg._.length > 1 ? String(argvArg._[1]) : '';
if (!id) {
@@ -161,17 +221,28 @@ export const run = async () => {
}
try {
cliLogger.debug(`Deleting process: ${id}`);
await tspm.delete(id);
console.log(`Process ${id} deleted.`);
} catch (error) {
console.error(`Error deleting process: ${error.message}`);
} catch (error: Error | unknown) {
const tspmError = handleError(error);
if (tspmError instanceof ValidationError) {
console.error(`Validation error: ${tspmError.message}`);
} else if (tspmError instanceof ConfigError) {
console.error(`Configuration error: ${tspmError.message}`);
} else {
console.error(`Error deleting process: ${tspmError.message}`);
}
cliLogger.error(tspmError);
}
}
});
// List command
smartcliInstance.addCommand('list').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const processes = tspm.list();
if (processes.length === 0) {
@@ -193,7 +264,7 @@ export const run = async () => {
// Describe command
smartcliInstance.addCommand('describe').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const id = argvArg._.length > 1 ? String(argvArg._[1]) : '';
if (!id) {
@@ -224,7 +295,7 @@ export const run = async () => {
// Logs command
smartcliInstance.addCommand('logs').subscribe({
next: async (argvArg) => {
next: async (argvArg: CliArguments) => {
const id = argvArg._.length > 1 ? String(argvArg._[1]) : '';
if (!id) {