diff --git a/packages/shared/src/schemas.test.ts b/packages/shared/src/schemas.test.ts index ca60cb1..f64067c 100644 --- a/packages/shared/src/schemas.test.ts +++ b/packages/shared/src/schemas.test.ts @@ -165,10 +165,18 @@ describe('traceRequestSchema', () => { }); }); - it('rejects an invalid url', () => { - expect(traceRequestSchema.safeParse({ url: 'not-a-url' }).success).toBe( - false, - ); + it('accepts a local game asset path (not just http(s))', () => { + // The proxy resolves relative paths against the games root, so a bare + // path is a valid trace source. + expect( + traceRequestSchema.safeParse({ url: 'poker/parts/assets/cards.png' }) + .success, + ).toBe(true); + }); + + it('rejects a missing or blank url', () => { + expect(traceRequestSchema.safeParse({}).success).toBe(false); + expect(traceRequestSchema.safeParse({ url: '' }).success).toBe(false); }); it('rejects an unknown mode or format', () => { diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas.ts index 8796231..477d44d 100644 --- a/packages/shared/src/schemas.ts +++ b/packages/shared/src/schemas.ts @@ -59,7 +59,10 @@ export const traceFormatSchema = z.enum(['svg', 'shape']); /** Query params for `GET /trace`. */ export const traceRequestSchema = z.object({ - url: z.string().url('url must be a valid URL'), + // The url may be an http(s) URL or a local game asset path relative to the + // games root (e.g. `poker/parts/assets/cards.png`); the proxy resolves both + // via `resolveAsset`. Only a non-empty string is validated here. + url: z.string().min(1, 'url is required'), mode: traceModeSchema.default('alpha'), threshold: z.coerce.number().int().min(0).max(255).default(128), format: traceFormatSchema.default('shape'),