From f7780c3d982c4dc305706bfccb60c7aa187b0f42 Mon Sep 17 00:00:00 2001 From: Justin Lin Date: Fri, 18 Apr 2025 15:17:25 +0800 Subject: [PATCH] feat: add get responses --- packages/game/src/Quest.ts | 15 +++++++- packages/game/src/Session.ts | 13 ++++++- packages/game/src/Stage.ts | 2 +- packages/game/src/schema/condition.ts | 3 +- packages/game/src/schema/index.ts | 29 +++++++++++++++ packages/game/src/types.ts | 45 ----------------------- packages/game/test/asyncCondition.test.ts | 2 +- packages/game/test/session.test.ts | 22 +++++++++++ packages/game/test/stage.test.ts | 17 ++++++++- 9 files changed, 94 insertions(+), 54 deletions(-) diff --git a/packages/game/src/Quest.ts b/packages/game/src/Quest.ts index e7a3e5d..8757458 100644 --- a/packages/game/src/Quest.ts +++ b/packages/game/src/Quest.ts @@ -1,7 +1,12 @@ /* eslint-disable no-await-in-loop */ -import { IQuest, IStage } from './schema' +import { + IQuest, + IStage, + IFileExistenceChecker, + ICommand, + IResponse, +} from './schema' import { Stage } from './Stage' -import { ICommand, IFileExistenceChecker } from './types' export class Quest { private stages: Stage[] @@ -32,4 +37,10 @@ export class Quest { } return null } + + getResponses(completed: string[]): IResponse[] { + return this.quest.stages + .filter((stage) => completed.includes(stage.id)) + .map((stage) => stage.response) + } } diff --git a/packages/game/src/Session.ts b/packages/game/src/Session.ts index 9750c48..173117b 100644 --- a/packages/game/src/Session.ts +++ b/packages/game/src/Session.ts @@ -1,6 +1,11 @@ import { Quest } from './Quest' -import { IQuest } from './schema' -import { ICommand, ISession, IFileExistenceChecker } from './types' +import { + IQuest, + ICommand, + ISession, + IFileExistenceChecker, + IResponse, +} from './schema' export class Session implements ISession { private completed: string[] = [] @@ -34,4 +39,8 @@ export class Session implements ISession { } return stageId } + + getResponses(): IResponse[] { + return this.quest.getResponses(this.completed) + } } diff --git a/packages/game/src/Stage.ts b/packages/game/src/Stage.ts index 1c83b71..d7da490 100644 --- a/packages/game/src/Stage.ts +++ b/packages/game/src/Stage.ts @@ -1,4 +1,4 @@ -import { IStage, ICommand, IFileExistenceChecker } from './types' +import { IStage, ICommand, IFileExistenceChecker } from './schema' import { Condition } from './condition/Condition' export class Stage { diff --git a/packages/game/src/schema/condition.ts b/packages/game/src/schema/condition.ts index f387c89..fc16680 100644 --- a/packages/game/src/schema/condition.ts +++ b/packages/game/src/schema/condition.ts @@ -1,9 +1,8 @@ import { z } from 'zod' -import { FileType } from '../types.js' export const fileInputSchema = z.object({ path: z.string(), - type: z.nativeEnum(FileType), + type: z.enum(['file', 'folder']), }) export type IFileInput = z.infer diff --git a/packages/game/src/schema/index.ts b/packages/game/src/schema/index.ts index 357a272..bdb7c02 100644 --- a/packages/game/src/schema/index.ts +++ b/packages/game/src/schema/index.ts @@ -3,3 +3,32 @@ export { stageSchema, IStage } from './stage.js' export { requirementsSchema, IRequirements } from './requirements.js' export { responseSchema, IResponse } from './response.js' export { questSchema, IQuest } from './quest.js' + +export interface ICommand { + command?: string + output?: string + error?: string + pwd?: string +} + +export enum FileType { + FILE = 'file', + FOLDER = 'folder', +} + +export interface FileInput { + path: string + type: FileType +} + +export interface FileExistenceInput extends FileInput { + exists: boolean +} + +export interface IFileExistenceChecker { + exists(file: FileInput): Promise +} + +export interface ISession { + completedStages: string[] +} diff --git a/packages/game/src/types.ts b/packages/game/src/types.ts index 972200f..e69de29 100644 --- a/packages/game/src/types.ts +++ b/packages/game/src/types.ts @@ -1,45 +0,0 @@ -export interface ICommand { - command?: string - output?: string - error?: string - pwd?: string -} - -export interface ICondition { - command?: string - output?: string - error?: string - pwd?: string - or?: ICondition[] - not?: ICondition - files?: FileExistenceInput[] -} - -export enum FileType { - FILE = 'file', - FOLDER = 'folder', -} - -export interface FileInput { - path: string - type: FileType -} - -export interface FileExistenceInput extends FileInput { - exists: boolean -} - -export interface IFileExistenceChecker { - exists(file: FileInput): Promise -} - -export interface IStage { - id: string - name?: string - requirements?: string[] - condition: ICondition -} - -export interface ISession { - completedStages: string[] -} diff --git a/packages/game/test/asyncCondition.test.ts b/packages/game/test/asyncCondition.test.ts index 8ad2630..53b34f1 100644 --- a/packages/game/test/asyncCondition.test.ts +++ b/packages/game/test/asyncCondition.test.ts @@ -1,5 +1,5 @@ import { test, expect } from '@jest/globals' -import { IFileExistenceChecker, FileType, FileInput } from '../src/types.js' +import { IFileExistenceChecker, FileType, FileInput } from '../src/schema' import { checkFiles } from '../src/condition/FileMatcher.js' import { Condition } from '../src/condition/Condition.js' diff --git a/packages/game/test/session.test.ts b/packages/game/test/session.test.ts index 5de1353..1742117 100644 --- a/packages/game/test/session.test.ts +++ b/packages/game/test/session.test.ts @@ -92,4 +92,26 @@ describe('Session', () => { 'stage4' ) }) + + it('should return responses', () => { + const session = new Session( + { + completedStages: ['stage1'], + }, + quest, + new MockFileChecker() + ) + expect(session.getResponses()).toEqual([ + { + type: 'narrative', + content: 'Narrative 1', + }, + ]) + + session.complete('stage2') + expect(session.getResponses()).toEqual([ + { type: 'narrative', content: 'Narrative 1' }, + { type: 'narrative', content: 'Narrative 2' }, + ]) + }) }) diff --git a/packages/game/test/stage.test.ts b/packages/game/test/stage.test.ts index 5631e21..3b446f3 100644 --- a/packages/game/test/stage.test.ts +++ b/packages/game/test/stage.test.ts @@ -1,6 +1,6 @@ import { test, expect } from '@jest/globals' import { Stage } from '../src/Stage' -import { FileType } from '../src/types' +import { FileType } from '../src/schema' import { MockFileChecker } from './asyncCondition.test' const checker = new MockFileChecker() @@ -13,6 +13,11 @@ test('check stage condition', async () => { command: 'ls', pwd: '/home/user', }, + requirements: [], + response: { + type: 'narrative', + content: 'Narrative 1', + }, }) expect( await stage.satisfies( @@ -47,6 +52,11 @@ test('check stage with async condition truthy', async () => { }, ], }, + requirements: [], + response: { + type: 'narrative', + content: 'Narrative 1', + }, }) expect(await stage.satisfies({}, checker)).toBe(true) }) @@ -64,6 +74,11 @@ test('check stage with async condition falsy', async () => { }, ], }, + requirements: [], + response: { + type: 'narrative', + content: 'Narrative 1', + }, }) expect(await stage.satisfies({}, checker)).toBe(false) })