© 2026 Hedgehog Software, LLC
const RequiredFileSchema = (maxSizeInMb: number, requiredMessage: string) => Schema.Unknown.pipe( Schema.filter((u): u is File => u instanceof File, { message: () => requiredMessage, }), Schema.compose(ValidFileSchema(maxSizeInMb)) ) as S.Schema<File>; export const ToolSubmissionSchema = Schema.Struct({ // Other fields homepageScreenshot: RequiredFileSchema( SCREENSHOT_MAX_SIZE_MB, "Homepage screenshot is required." ), }).pipe(Schema.annotations({ parseOptions: { errors: "all" } }));
Homepage screenshot is required.
resolver
resolver: effectTsResolver(ToolSubmissionSchema),
Expected file, actual undefined
import { HttpApiEndpoint } from "@effect/platform"; import { Schema } from "effect"; import { ToolSubmissionSchema } from "@/lib/schema"; export const submitTool = HttpApiEndpoint.post("submitTool", "/submit") .setPayload(ToolSubmissionSchema) .addSuccess( Schema.Struct({ success: Schema.Boolean, }) );
https://github.com/sundaray/next-effect