From 9e2947a8d6a48f165ddb030a3a744f2f140a4efa Mon Sep 17 00:00:00 2001 From: hypercross Date: Sat, 4 Apr 2026 21:38:07 +0800 Subject: [PATCH] refactor: prompt validation --- src/core/game.ts | 29 ++------------------------- src/index.ts | 2 +- src/utils/command/command-registry.ts | 29 +++++++++++++++++++-------- src/utils/command/command-runner.ts | 4 +++- 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/core/game.ts b/src/core/game.ts index 72ced91..207321c 100644 --- a/src/core/game.ts +++ b/src/core/game.ts @@ -10,6 +10,7 @@ import { registerCommand } from "@/utils/command"; import type { GameModule } from './game-host'; +import {PromptValidator} from "@/utils/command/command-runner"; export interface IGameContext = {} > { get value(): TState; @@ -17,7 +18,7 @@ export interface IGameContext = {} > { produceAsync(fn: (draft: TState) => void): Promise; run(input: string): Promise>; runParsed(command: Command): Promise>; - prompt(schema: CommandSchema | string, validator?: (command: Command) => string | null, currentPlayer?: string | null): Promise; + prompt(schema: CommandSchema | string, validator: PromptValidator, currentPlayer?: string | null): Promise; addInterruption(promise: Promise): void; // test only @@ -82,32 +83,6 @@ export function createGameCommandRegistry return createCommandRegistry>(); } -type CmdFunc = {}> = (this: IGameContext, ...args: any[]) => Promise; - -export function registerGameCommand = {}, TFunc extends CmdFunc = CmdFunc>( - registry: CommandRegistry>, - schema: CommandSchema | string, - run: TFunc -) { - const parsedSchema = typeof schema === 'string' ? parseCommandSchema(schema) : schema; - registerCommand(registry, { - schema: parsedSchema, - async run(this: CommandRunnerContext>, command: Command){ - const params = command.params; - return await run.call(this.context, ...params); - }, - }); - - return function(game: IGameContext, ...args: Parameters){ - return game.runParsed({ - options: {}, - params: args, - flags: {}, - name: parsedSchema.name, - }); - } -} - export { GameHost, createGameHost } from './game-host'; export type { GameHostStatus, GameModule } from './game-host'; diff --git a/src/index.ts b/src/index.ts index 1c6b273..0d88be0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,7 @@ // Core types export type { IGameContext } from './core/game'; -export { createGameContext, createGameCommandRegistry, registerGameCommand } from './core/game'; +export { createGameContext, createGameCommandRegistry } from './core/game'; export type { GameHost, GameHostStatus, GameModule } from './core/game'; export { createGameHost, createGameModule } from './core/game'; diff --git a/src/utils/command/command-registry.ts b/src/utils/command/command-registry.ts index 9ed0e67..fdd163a 100644 --- a/src/utils/command/command-registry.ts +++ b/src/utils/command/command-registry.ts @@ -1,5 +1,12 @@ import type { Command, CommandSchema } from './types'; -import type {CommandResult, CommandRunner, CommandRunnerContext, CommandRunnerEvents, PromptEvent} from './command-runner'; +import type { + CommandResult, + CommandRunner, + CommandRunnerContext, + CommandRunnerEvents, + PromptEvent, + PromptValidator +} from './command-runner'; import { parseCommand } from './command-parse'; import { applyCommandSchema } from './command-validate'; import { parseCommandSchema } from './schema-parse'; @@ -129,11 +136,11 @@ export function createCommandRunnerContext( } }; - const prompt = ( + const prompt = ( schema: CommandSchema | string, - validator?: (command: Command) => string | null, + validator: PromptValidator, currentPlayer?: string | null - ): Promise => { + ): Promise => { const resolvedSchema = typeof schema === 'string' ? parseCommandSchema(schema) : schema; return new Promise((resolve, reject) => { const tryCommit = (commandOrInput: Command | string) => { @@ -142,10 +149,16 @@ export function createCommandRunnerContext( if (!schemaResult.valid) { return schemaResult.errors.join('; '); } - const error = validator?.(schemaResult.command); - if (error) return error; - resolve(schemaResult.command); - return null; + try{ + const result = validator(schemaResult.command); + resolve(result); + return null; + }catch(e){ + if(e instanceof Error) + return e.message; + else + throw e; + } }; const cancel = (reason?: string) => { activePrompt = null; diff --git a/src/utils/command/command-runner.ts b/src/utils/command/command-runner.ts index 84c0682..d28d12a 100644 --- a/src/utils/command/command-runner.ts +++ b/src/utils/command/command-runner.ts @@ -31,11 +31,13 @@ export type CommandResult = { error: string; } +export type PromptValidator = (command: Command) => T; + export type CommandRunnerContext = { context: TContext; run: (input: string) => Promise>; runParsed: (command: Command) => Promise>; - prompt: (schema: CommandSchema | string, validator?: (command: Command) => string | null, currentPlayer?: string | null) => Promise; + prompt: (schema: CommandSchema | string, validator: PromptValidator, currentPlayer?: string | null) => Promise; on: (event: T, listener: (e: CommandRunnerEvents[T]) => void) => void; off: (event: T, listener: (e: CommandRunnerEvents[T]) => void) => void; };