) => {
- if (e.key === 'Enter') {
- handleCommandWrapper();
- if (command.trim().length !== 0) {
- setCommandHistory((prev) => [...prev, command]);
- setHistoryIndex(-1);
- }
- return;
- }
-
- const filteredCommandHistory = commandHistory.filter((cmd) => {
- return cmd.startsWith(tempCommand);
- });
-
- if (e.key === 'ArrowUp') {
- e.preventDefault();
- if (historyIndex < filteredCommandHistory.length - 1) {
- if (historyIndex === -1) {
- // Save current input when starting to navigate history
- setTempCommand(command);
- }
- const newIndex = historyIndex + 1;
- setHistoryIndex(newIndex);
- setCommand(
- filteredCommandHistory[filteredCommandHistory.length - 1 - newIndex]!,
- );
- }
- } else if (e.key === 'ArrowDown') {
- e.preventDefault();
- if (historyIndex > -1) {
- const newIndex = historyIndex - 1;
- setHistoryIndex(newIndex);
- if (newIndex === -1) {
- // Restore the saved input when reaching the bottom
- setCommand(tempCommand);
- } else {
- setCommand(
- filteredCommandHistory[
- filteredCommandHistory.length - 1 - newIndex
- ]!,
- );
- }
- }
- }
- };
-
- return {
- handleInputChange,
- handleKeyDown,
- terminalRef,
- inputRef,
- output,
- setOutput,
- command,
- tempCommand,
- setTempCommand,
- };
-};
diff --git a/apps/playground-web/components/Playground/TerminalUI.tsx b/apps/playground-web/components/Playground/TerminalUI.tsx
index 949bd17..a9217b2 100644
--- a/apps/playground-web/components/Playground/TerminalUI.tsx
+++ b/apps/playground-web/components/Playground/TerminalUI.tsx
@@ -6,9 +6,10 @@ import { useState } from 'react';
import Tooltip from '../Overlays/Tooltip';
export function TerminalUI({ initialCommandsLeft = 1000 }) {
const [commandsLeft, setCommandsLeft] = useState(initialCommandsLeft);
- const decreaseCommandsLeft = () => {
- setCommandsLeft((prev) => (prev > 0 ? prev - 1 : 0));
+ const handleCommandExecuted = (commands: number) => {
+ setCommandsLeft(commands);
};
+
return (
<>
@@ -23,7 +24,7 @@ export function TerminalUI({ initialCommandsLeft = 1000 }) {
className="h-64 md:h-[30rem] bg-gray-100 rounded-lg overflow-hidden shadow-md"
data-testid="shell-container"
>
-
+
diff --git a/apps/playground-web/components/Playground/__tests__/TerminalUI.test.tsx b/apps/playground-web/components/Playground/__tests__/TerminalUI.test.tsx
index eaa6b5f..1ef04af 100644
--- a/apps/playground-web/components/Playground/__tests__/TerminalUI.test.tsx
+++ b/apps/playground-web/components/Playground/__tests__/TerminalUI.test.tsx
@@ -4,17 +4,16 @@ import userEvent from '@testing-library/user-event';
import { TerminalUI } from '../TerminalUI';
import { formatTime } from '@/shared/utils/commonUtils';
+// Shared variable to store initialCommandsLeft
+let sharedInitialCommandsLeft = 1000;
+
jest.mock('@/shared/hooks/useTimer', () => ({
useTimer: jest.fn(() => ({ timeLeft: 15 * 60 })), // Mock 15 minutes
}));
-jest.mock('@/shared/utils/commonUtils', () => ({
- formatTime: jest.fn(
- (seconds) => `${Math.floor(seconds / 60)}:${seconds % 60}`,
- ),
-}));
-
const setupTest = (initialCommandsLeft = 1000) => {
+ sharedInitialCommandsLeft = initialCommandsLeft;
+
const user = userEvent.setup();
const utils = render(
,
@@ -39,6 +38,21 @@ const setupTest = (initialCommandsLeft = 1000) => {
};
};
+jest.mock('@/shared/utils/commonUtils', () => ({
+ formatTime: jest.fn(
+ (seconds) => `${Math.floor(seconds / 60)}:${seconds % 60}`,
+ ),
+ handleResult: jest.fn(
+ ({ result, newOutput, setOutput, onCommandExecuted }) => {
+ const mockData = result?.body?.data ? result.body.data : 'mock error';
+ setOutput([newOutput, mockData]);
+
+ const commandsLeft = Math.max(0, sharedInitialCommandsLeft - 1);
+ onCommandExecuted(commandsLeft);
+ },
+ ),
+}));
+
describe('TerminalUI Component', () => {
it('renders TerminalUI', () => {
const { terminalContainer, diceIcons, shellContainer, cliInputElement } =
diff --git a/apps/playground-web/components/Shell/Shell.tsx b/apps/playground-web/components/Shell/Shell.tsx
index 47f320b..643a9a3 100644
--- a/apps/playground-web/components/Shell/Shell.tsx
+++ b/apps/playground-web/components/Shell/Shell.tsx
@@ -5,10 +5,10 @@
import { useShell } from './hooks/useShell';
interface ShellProps {
- decreaseCommandsLeft: () => void;
+ onCommandExecuted: (commandsLeft: number) => void;
}
-export default function Shell({ decreaseCommandsLeft }: ShellProps) {
+export default function Shell({ onCommandExecuted }: ShellProps) {
const {
handleInputChange,
handleKeyDown,
@@ -16,7 +16,7 @@ export default function Shell({ decreaseCommandsLeft }: ShellProps) {
inputRef,
output,
command,
- } = useShell(decreaseCommandsLeft);
+ } = useShell(onCommandExecuted);
return (
{
const user = userEvent.setup();
- const utils = render(
- ,
- );
+ const utils = render();
const terminalElement = screen.getByTestId('terminal');
const cliInputElement = screen.getByTestId('shell-input');
diff --git a/apps/playground-web/components/Shell/hooks/useShell.tsx b/apps/playground-web/components/Shell/hooks/useShell.tsx
index 846a68b..5da2699 100644
--- a/apps/playground-web/components/Shell/hooks/useShell.tsx
+++ b/apps/playground-web/components/Shell/hooks/useShell.tsx
@@ -5,7 +5,7 @@ import { useState, useEffect, useRef, KeyboardEvent, ChangeEvent } from 'react';
import { handleCommand } from '@/shared/utils/shellUtils';
import blocklistedCommands from '@/shared/utils/blocklist';
-export const useShell = (decreaseCommandsLeft: () => void) => {
+export const useShell = (onCommandExecuted: (commandsLeft: number) => void) => {
// states
const [command, setCommand] = useState('');
const [output, setOutput] = useState([]);
@@ -32,11 +32,10 @@ export const useShell = (decreaseCommandsLeft: () => void) => {
`(error) ERR unknown command '${commandName}'`,
]);
} else {
- handleCommand({ command, setOutput }); // Execute if not blocklisted
+ handleCommand({ command, setOutput, onCommandExecuted }); // Execute if not blocklisted
}
setCommand(''); // Clear input
- decreaseCommandsLeft(); // Call to update remaining commands
};
useEffect(() => {
diff --git a/apps/playground-web/lib/api.ts b/apps/playground-web/lib/api.ts
index 1e3931e..3a6e916 100644
--- a/apps/playground-web/lib/api.ts
+++ b/apps/playground-web/lib/api.ts
@@ -1,26 +1,28 @@
// src/lib/api.ts
import { WebService } from '@/services/webServices';
+import { MonoResponse } from './monoResponse';
+
export const executeShellCommandOnServer = async (
cmd: string,
cmdOptions: object,
-) => {
+): Promise<{ headers: { [key: string]: string }; body: MonoResponse }> => {
const cmdExecURL = `/shell/exec/${cmd}`;
try {
const response = await WebService.post(cmdExecURL, cmdOptions);
// Check if the response contains data or if it's an error response
- if (response?.data) {
- return response.data;
- } else if (response?.error) {
- return response.error;
+ if (response?.body?.data) {
+ return response;
+ } else if (response?.body?.error) {
+ return response;
} else {
throw new Error('Unexpected response structure');
}
} catch (error) {
// Propagate the error from the backend exactly as it is
console.error('Error executing command:', error);
- return `${error}`; // Just return the error message directly
+ throw new Error(`${error}`);
}
};
diff --git a/apps/playground-web/lib/monoResponse.ts b/apps/playground-web/lib/monoResponse.ts
new file mode 100644
index 0000000..f520a05
--- /dev/null
+++ b/apps/playground-web/lib/monoResponse.ts
@@ -0,0 +1,4 @@
+export interface MonoResponse {
+ data: string | null;
+ error: string | null;
+}
diff --git a/apps/playground-web/lib/monoSchema.ts b/apps/playground-web/lib/monoSchema.ts
new file mode 100644
index 0000000..16651e1
--- /dev/null
+++ b/apps/playground-web/lib/monoSchema.ts
@@ -0,0 +1,13 @@
+import { z } from 'zod';
+
+const BodySchema = z.object({
+ data: z.string(),
+});
+
+// Define the schema for an error response
+const ErrorSchema = z.object({
+ error: z.string(),
+});
+
+// Combine the schemas
+export const MonoSchema = z.union([BodySchema, ErrorSchema]);
diff --git a/apps/playground-web/package.json b/apps/playground-web/package.json
index 1482284..4204b69 100644
--- a/apps/playground-web/package.json
+++ b/apps/playground-web/package.json
@@ -17,6 +17,7 @@
"test:coverage": "jest --coverage"
},
"dependencies": {
+ "@dicedb/ui": "workspace:*",
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@mui/icons-material": "^6.1.1",
@@ -29,9 +30,12 @@
"react-dom": "^18",
"react-terminal-ui": "^1.3.0",
"sharp": "^0.33.5",
- "@dicedb/ui": "workspace:*"
+ "zod": "^3.23.8"
},
"devDependencies": {
+ "@dicedb/eslint-config": "workspace:*",
+ "@dicedb/tailwind-config": "workspace:*",
+ "@dicedb/typescript-config": "workspace:*",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.1",
@@ -48,9 +52,6 @@
"prettier": "^3.3.3",
"tailwindcss": "^3.4.1",
"ts-node": "^10.9.2",
- "typescript": "^5",
- "@dicedb/typescript-config": "workspace:*",
- "@dicedb/eslint-config": "workspace:*",
- "@dicedb/tailwind-config": "workspace:*"
+ "typescript": "^5"
}
}
diff --git a/apps/playground-web/services/webServices.ts b/apps/playground-web/services/webServices.ts
index 77294c1..63c7461 100644
--- a/apps/playground-web/services/webServices.ts
+++ b/apps/playground-web/services/webServices.ts
@@ -1,3 +1,7 @@
+import { MonoSchema } from '@/lib/monoSchema';
+
+import { MonoResponse } from '@/lib/monoResponse';
+
let PLAYGROUND_MONO_URL = process.env.NEXT_PUBLIC_PLAYGROUND_MONO_URL;
if (!PLAYGROUND_MONO_URL) {
@@ -24,7 +28,10 @@ export const WebService = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data: any = null,
headers: HeadersType,
- ) => {
+ ): Promise<{
+ headers: { [key: string]: string };
+ body: MonoResponse;
+ }> => {
const options: RequestOptions = {
method,
headers: {
@@ -41,24 +48,45 @@ export const WebService = {
try {
const response = await fetch(`${PLAYGROUND_MONO_URL}${url}`, options);
- // If the response is not OK, check if the response contains error information
- if (!response.ok) {
- const errorResponse = await response.json();
- if (errorResponse?.error) {
- throw errorResponse.error;
- } else {
- throw new Error(`HTTP error! Status: ${response.status}`);
- }
- }
+ const headers: { [key: string]: string } = {};
+ response?.headers?.forEach((value: string, key: string) => {
+ headers[key] = value;
+ });
// Parse the result as JSON
- const result = await response.json();
- return result;
+ const body = await response.json();
+ const parsedBody = MonoSchema.safeParse(body);
+ if (!parsedBody.success) {
+ console.error('Invalid response data:', parsedBody.error);
+ return {
+ headers: headers,
+ body: { data: null, error: parsedBody?.error?.message },
+ };
+ }
+
+ if ('data' in parsedBody.data) {
+ return {
+ headers: headers,
+ body: { data: parsedBody?.data?.data, error: null },
+ };
+ } else {
+ return {
+ headers: headers,
+ body: { data: null, error: parsedBody.data.error },
+ };
+ }
} catch (error) {
if (error instanceof Error) {
console.error(`Error with ${method} request: ${error.message}`);
+ return {
+ headers: headers,
+ body: { error: `${error.message}`, data: null },
+ };
}
- throw error;
+ return {
+ headers: headers,
+ body: { error: 'Unknown error occurred', data: null },
+ };
}
},
diff --git a/apps/playground-web/shared/utils/cliUtils.ts b/apps/playground-web/shared/utils/cliUtils.ts
deleted file mode 100644
index 5d967ca..0000000
--- a/apps/playground-web/shared/utils/cliUtils.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-// src/shared/utils/cliUtils.ts
-
-import { executeShellCommandOnServer } from '@/lib/api';
-import { CommandHandler } from '@/types';
-
-export const handleCommand = async ({ command, setOutput }: CommandHandler) => {
- const newOutput = `dice > ${command}`;
- let result: string;
-
- const [cmd, ...args] = command.split(' ');
- if (!cmd) {
- result = 'Invalid command';
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- return;
- }
-
- switch (cmd.toUpperCase()) {
- case 'GET':
- if (args.length < 1) {
- result = 'Invalid command. Usage: GET key';
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- return;
- }
-
- try {
- const [key] = args;
- const cmdOptions = { key: key };
- result = await executeShellCommandOnServer(cmd, cmdOptions);
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- } catch (error: unknown) {
- console.error('Error executing command:', error);
- result = 'Error executing command';
- return `Error: ${String(error)}`;
- }
- break;
-
- case 'SET':
- if (args.length === 2) {
- const [key, value] = args;
- try {
- const cmdOptions = { key: key, value: value };
- result = await executeShellCommandOnServer(cmd, cmdOptions);
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- } catch (error: unknown) {
- console.error('Error executing command:', error);
- result = 'Error executing command';
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- return `Error: ${String((error as Error).message || error)}`;
- }
- } else {
- result = 'Invalid command. Usage: SET key value';
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- }
- break;
-
- case 'DEL':
- if (args.length <= 1) {
- const [keys] = args;
- try {
- const cmdOptions = { keys: [keys] };
- result = await executeShellCommandOnServer(cmd, cmdOptions);
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- } catch (error: unknown) {
- console.error('Error executing command:', error);
- result = 'Error executing command';
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- return `Error: ${String((error as Error).message || error)}`;
- }
- } else {
- result = 'Invalid command. Usage: DEL key1 key2 ....';
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- }
- break;
-
- default:
- result = `Unknown command: ${cmd}`;
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
- }
-};
diff --git a/apps/playground-web/shared/utils/commonUtils.ts b/apps/playground-web/shared/utils/commonUtils.ts
index c07147e..beaa013 100644
--- a/apps/playground-web/shared/utils/commonUtils.ts
+++ b/apps/playground-web/shared/utils/commonUtils.ts
@@ -1,5 +1,41 @@
+import { MonoResponse } from '@/lib/monoResponse';
+
export const formatTime = (seconds: number): string => {
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes}:${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}`;
};
+
+interface HandleResultProps {
+ result: {
+ headers: { [key: string]: string }; // Correctly defined headers type
+ body: MonoResponse; // MonoResponse for body
+ };
+ newOutput: string;
+ setOutput: (prevOutput: any) => any; // Adjust type as necessary
+ onCommandExecuted: (commandsLeft: number) => void; // Allow undefined
+}
+
+export const handleResult = ({
+ result,
+ newOutput,
+ setOutput,
+ onCommandExecuted,
+}: HandleResultProps) => {
+ if (result?.body?.data) {
+ setOutput((prevOutput: any) => [
+ ...prevOutput,
+ newOutput,
+ result?.body?.data,
+ ]);
+ } else if (result?.body?.error) {
+ setOutput((prevOutput: any) => [
+ ...prevOutput,
+ newOutput,
+ result?.body?.error,
+ ]);
+ }
+
+ const commandsLeft = Number(result.headers['x-ratelimit-remaining']);
+ onCommandExecuted(commandsLeft);
+};
diff --git a/apps/playground-web/shared/utils/shellUtils.ts b/apps/playground-web/shared/utils/shellUtils.ts
index b8f6dd8..269f94e 100644
--- a/apps/playground-web/shared/utils/shellUtils.ts
+++ b/apps/playground-web/shared/utils/shellUtils.ts
@@ -2,10 +2,15 @@
import { executeShellCommandOnServer } from '@/lib/api';
import { CommandHandler } from '@/types';
+import { handleResult } from '@/shared/utils/commonUtils';
-export const handleCommand = async ({ command, setOutput }: CommandHandler) => {
+export const handleCommand = async ({
+ command,
+ setOutput,
+ onCommandExecuted,
+}: CommandHandler) => {
const newOutput = `dice > ${command}`;
- let result: string;
+ let result: any;
const { cmd, args } = parseCommand(command);
@@ -14,7 +19,7 @@ export const handleCommand = async ({ command, setOutput }: CommandHandler) => {
}
try {
result = await executeShellCommandOnServer(cmd, args);
- setOutput((prevOutput) => [...prevOutput, newOutput, result]);
+ handleResult({ result, newOutput, setOutput, onCommandExecuted });
} catch (error: unknown) {
console.error('Error executing command:', error);
result = 'Error executing command';
diff --git a/apps/playground-web/types/index.d.ts b/apps/playground-web/types/index.d.ts
index 1324c2e..cd03372 100644
--- a/apps/playground-web/types/index.d.ts
+++ b/apps/playground-web/types/index.d.ts
@@ -3,4 +3,5 @@ import * as React from 'react';
export interface CommandHandler {
command: string;
setOutput: React.Dispatch>;
+ onCommandExecuted: (commandsLeft: number) => void;
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 44f384b..adb50a8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -108,6 +108,9 @@ importers:
sharp:
specifier: ^0.33.5
version: 0.33.5
+ zod:
+ specifier: ^3.23.8
+ version: 3.23.8
devDependencies:
'@dicedb/eslint-config':
specifier: workspace:*
@@ -223,7 +226,7 @@ importers:
version: 29.7.0
ts-jest:
specifier: ^29.2.5
- version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3)
+ version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0))(typescript@5.6.3)
typescript:
specifier: ^5.3.3
version: 5.6.3
@@ -238,7 +241,7 @@ importers:
version: 7.18.0(eslint@8.57.1)(typescript@5.6.3)
'@vercel/style-guide':
specifier: ^5.2.0
- version: 5.2.0(@next/eslint-plugin-next@14.2.15)(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(prettier@3.3.3)(typescript@5.6.3)
+ version: 5.2.0(@next/eslint-plugin-next@14.2.15)(eslint@8.57.1)(jest@29.7.0(babel-plugin-macros@3.1.0))(prettier@3.3.3)(typescript@5.6.3)
eslint-config-prettier:
specifier: ^9.1.0
version: 9.1.0(eslint@8.57.1)
@@ -4624,6 +4627,9 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
+ zod@3.23.8:
+ resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
+
snapshots:
'@adobe/css-tools@4.4.0': {}
@@ -5906,7 +5912,7 @@ snapshots:
'@ungap/structured-clone@1.2.0': {}
- '@vercel/style-guide@5.2.0(@next/eslint-plugin-next@14.2.15)(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(prettier@3.3.3)(typescript@5.6.3)':
+ '@vercel/style-guide@5.2.0(@next/eslint-plugin-next@14.2.15)(eslint@8.57.1)(jest@29.7.0(babel-plugin-macros@3.1.0))(prettier@3.3.3)(typescript@5.6.3)':
dependencies:
'@babel/core': 7.25.8
'@babel/eslint-parser': 7.25.8(@babel/core@7.25.8)(eslint@8.57.1)
@@ -5914,13 +5920,13 @@ snapshots:
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)
'@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.3)
eslint-config-prettier: 9.1.0(eslint@8.57.1)
- eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.31.0)
+ eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1)
eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
- eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3)
+ eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(babel-plugin-macros@3.1.0))(typescript@5.6.3)
eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1)
- eslint-plugin-playwright: 0.16.0(eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3))(eslint@8.57.1)
+ eslint-plugin-playwright: 0.16.0(eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(babel-plugin-macros@3.1.0))(typescript@5.6.3))(eslint@8.57.1)
eslint-plugin-react: 7.37.1(eslint@8.57.1)
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1)
eslint-plugin-testing-library: 6.3.0(eslint@8.57.1)(typescript@5.6.3)
@@ -6844,7 +6850,7 @@ snapshots:
eslint: 8.57.1
eslint-plugin-turbo: 2.1.3(eslint@8.57.1)
- eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0):
+ eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)):
dependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
@@ -6862,7 +6868,7 @@ snapshots:
debug: 4.3.7
enhanced-resolve: 5.17.1
eslint: 8.57.1
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
fast-glob: 3.3.2
get-tsconfig: 4.8.1
is-bun-module: 1.2.1
@@ -6881,7 +6887,7 @@ snapshots:
debug: 4.3.7
enhanced-resolve: 5.17.1
eslint: 8.57.1
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
fast-glob: 3.3.2
get-tsconfig: 4.8.1
is-bun-module: 1.2.1
@@ -6894,7 +6900,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
+ eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -6905,7 +6911,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
+ eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -6933,7 +6939,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
@@ -6951,7 +6957,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3):
+ eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(babel-plugin-macros@3.1.0))(typescript@5.6.3):
dependencies:
'@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.6.3)
eslint: 8.57.1
@@ -6984,11 +6990,11 @@ snapshots:
eslint-plugin-only-warn@1.1.0: {}
- eslint-plugin-playwright@0.16.0(eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3))(eslint@8.57.1):
+ eslint-plugin-playwright@0.16.0(eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(babel-plugin-macros@3.1.0))(typescript@5.6.3))(eslint@8.57.1):
dependencies:
eslint: 8.57.1
optionalDependencies:
- eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3)
+ eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(babel-plugin-macros@3.1.0))(typescript@5.6.3)
eslint-plugin-react-hooks@4.6.2(eslint@8.57.1):
dependencies:
@@ -9554,7 +9560,7 @@ snapshots:
ts-interface-checker@0.1.13: {}
- ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))(typescript@5.6.3):
+ ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@20.16.11)(babel-plugin-macros@3.1.0))(typescript@5.6.3):
dependencies:
bs-logger: 0.2.6
ejs: 3.1.10
@@ -9893,3 +9899,5 @@ snapshots:
yn@3.1.1: {}
yocto-queue@0.1.0: {}
+
+ zod@3.23.8: {}
diff --git a/src/lib/__tests__/api.test.ts b/src/lib/__tests__/api.test.ts
index 5bd6590..a6d91f0 100644
--- a/src/lib/__tests__/api.test.ts
+++ b/src/lib/__tests__/api.test.ts
@@ -1,5 +1,6 @@
import { executeShellCommandOnServer } from '../api';
import { WebService } from '@/services/webServices';
+import { handleCommand } from '@/shared/utils/cliUtils';
// Mock WebService
jest.mock('@/services/webServices', () => ({
@@ -90,4 +91,26 @@ describe('executeShellCommandOnServer', () => {
);
expect(result).toEqual('Some Response');
});
+
+ it('should call onCommandExecuted with (1000) for GET command', async () => {
+ const command = 'GET testKey';
+ const mockResult = {
+ body: { data: 'mockData' },
+ headers: { 'x-ratelimit-remaining': 1000 },
+ }; // Updated mock result
+ (executeShellCommandOnServer as jest.Mock).mockResolvedValueOnce(
+ mockResult,
+ ); // Mock the API response
+
+ const setOutputMock = jest.fn();
+ const onCommandExecutedMock = jest.fn();
+
+ await handleCommand({
+ command,
+ setOutput: setOutputMock,
+ onCommandExecuted: onCommandExecutedMock,
+ });
+
+ expect(onCommandExecutedMock).toHaveBeenCalledWith(1000);
+ });
});