test
This commit is contained in:
7
src/command_exit.ts
Normal file
7
src/command_exit.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { State } from "./state.js";
|
||||
|
||||
export function commandExit(state: State) {
|
||||
console.log('Closing the Pokedex... Goodbye!');
|
||||
state.readline.close()
|
||||
process.exit(0)
|
||||
}
|
||||
10
src/command_help.ts
Normal file
10
src/command_help.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { State } from "./state.js";
|
||||
|
||||
export function commandHelp(state: State) {
|
||||
const commands = state.commands;
|
||||
let finalString = 'Welcome to the Pokedex!\nUsage: \n\n'
|
||||
for (const command of Object.values(commands)) {
|
||||
finalString += `${command.name}: ${command.description}\n`
|
||||
}
|
||||
console.log(finalString);
|
||||
}
|
||||
20
src/commands.ts
Normal file
20
src/commands.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { commandHelp } from "./command_help.js";
|
||||
import { commandExit } from "./command_exit.js";
|
||||
|
||||
import type { CLICommand } from "./state.js";
|
||||
|
||||
export function getCommands(): Record<string, CLICommand> {
|
||||
return {
|
||||
exit: {
|
||||
name: "exit",
|
||||
description: 'Exits the pokedex',
|
||||
callback: commandExit,
|
||||
},
|
||||
|
||||
help: {
|
||||
name: "help",
|
||||
description: 'Help command for pokedex',
|
||||
callback: commandHelp,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import { startREPL } from "./repl.js"
|
||||
import { initState } from "./state.js";
|
||||
|
||||
function main() {
|
||||
startREPL();
|
||||
async function main() {
|
||||
const state = initState();
|
||||
startREPL(state);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cleanInput } from "./repl.ts";
|
||||
import { cleanInput } from "./repl.js";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
describe.each([
|
||||
|
||||
43
src/repl.ts
43
src/repl.ts
@@ -1,4 +1,41 @@
|
||||
export function cleanInput(input: string): string[] {
|
||||
const lowercaseString = input.toLowerCase();
|
||||
return lowercaseString.trim().split(" ");
|
||||
import type { CLICommand, State } from './state.js';
|
||||
|
||||
|
||||
export function startREPL(state: State) {
|
||||
state.readline.prompt();
|
||||
|
||||
state.readline.on("line", async (input) => {
|
||||
const words = cleanInput(input);
|
||||
if (words.length === 0) {
|
||||
state.readline.prompt();
|
||||
return;
|
||||
}
|
||||
|
||||
const commandName = words[0];
|
||||
|
||||
const cmd = state.commands[commandName];
|
||||
if (!cmd) {
|
||||
console.log(
|
||||
`Unknown command: "${commandName}". Type "help" for a list of commands.`,
|
||||
);
|
||||
state.readline.prompt();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
cmd.callback(state);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
state.readline.prompt();
|
||||
});
|
||||
}
|
||||
|
||||
export function cleanInput(input: string): string[] {
|
||||
return input
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.split(" ")
|
||||
.filter((word) => word !== "");
|
||||
}
|
||||
|
||||
28
src/state.ts
Normal file
28
src/state.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { createInterface, type Interface } from "node:readline";
|
||||
import { stdin, stdout } from 'node:process'
|
||||
import { getCommands } from "./commands.js";
|
||||
|
||||
export type CLICommand = {
|
||||
name: string,
|
||||
description: string,
|
||||
callback: (state: State) => void;
|
||||
}
|
||||
|
||||
export type State = {
|
||||
readline: Interface,
|
||||
commands: Record<string, CLICommand>;
|
||||
}
|
||||
|
||||
export function initState() {
|
||||
const rl = createInterface({
|
||||
input: stdin,
|
||||
output: stdout,
|
||||
prompt: 'Pokedex > ',
|
||||
});
|
||||
|
||||
return {
|
||||
readline: rl,
|
||||
commands: getCommands(),
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user