diff --git a/packages/game/package.json b/packages/game/package.json index 7e6a856..5854459 100644 --- a/packages/game/package.json +++ b/packages/game/package.json @@ -6,5 +6,7 @@ "scripts": { "build": "tsc -b" }, - "dependencies": {} + "dependencies": { + "zod": "^3.23.8" + } } diff --git a/packages/game/src/schema/condition.ts b/packages/game/src/schema/condition.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/game/src/schema/index.ts b/packages/game/src/schema/index.ts new file mode 100644 index 0000000..f21337b --- /dev/null +++ b/packages/game/src/schema/index.ts @@ -0,0 +1,54 @@ +import { z } from 'zod' + +export const requirementsSchema = z.object({ + requirements: z.array(z.string()), +}) + +export type IRequirements = z.infer + +export const fileInputSchema = z.object({ + path: z.string(), + type: z.enum(['file', 'folder']), +}) + +export type IFileInput = z.infer + +export const fileExistenceInputSchema = fileInputSchema.extend({ + exists: z.boolean(), +}) + +export type IFileExistenceInput = z.infer + +const baseConditionSchema = z.object({ + command: z.string().optional(), + output: z.string().optional(), + error: z.string().optional(), + pwd: z.string().optional(), + files: z.array(fileExistenceInputSchema).optional(), +}) + +export type ICondition = z.infer & { + or?: ICondition[] + not?: ICondition +} + +export const conditionSchema: z.ZodType = + baseConditionSchema.extend({ + or: z.lazy(() => z.array(conditionSchema)).optional(), + not: z.lazy(() => conditionSchema).optional(), + }) + +export const responseSchema = z.object({ + type: z.enum(['narrative', 'dialogue']), + content: z.string(), +}) + +export const stageSchema = z.object({ + id: z.string().regex(/^[a-zA-Z0-9_-]+$/), + name: z.string().optional(), + requirements: z.array(z.string()), + condition: conditionSchema, + response: responseSchema, +}) + +export type IStage = z.infer diff --git a/packages/game/src/schema/requirements.ts b/packages/game/src/schema/requirements.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/game/src/schema/stage.ts b/packages/game/src/schema/stage.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index 11dd056..ad05f5c 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -4,6 +4,7 @@ import { OutputMatcher } from '../src/condition/OutputMatcher' import { PwdMatcher } from '../src/condition/PwdMatcher' import { CommandMatcher } from '../src/condition/CommandMatcher' import { ErrorMatcher } from '../src/condition/ErrorMatcher.js' +import { conditionSchema } from '../src/schema' test('command match', () => { const matcher = new CommandMatcher('^echo start$') @@ -80,3 +81,14 @@ test('condition with NOT', () => { expect(condition.match({ command: 'echo start' })).toBe(false) expect(condition.match({ command: 'echo hello' })).toBe(true) }) + +it('should parse condition', () => { + const condition = { + command: 'echo start', + output: 'start', + not: { + pwd: '/home/user', + }, + } + expect(conditionSchema.safeParse(condition).error).toBeUndefined() +}) diff --git a/yarn.lock b/yarn.lock index 746b92f..13fbb96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9747,5 +9747,5 @@ yocto-queue@^0.1.0: zod@^3.23.8: version "3.23.8" - resolved "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==