Form Schema API
Derive Standard Schema compatible Zod endpoints directly from your OmniSvelte models for seamless form validation.
Form Schema API
The formSchema() helper generates a Standard Schema-compatible Zod object derived directly from your OmniSvelte model's defineSchema() definition.
Instead of duplicating your database schema into separate validation schemas for forms, you can generate them dynamically and pass them directly into SvelteKit remote functions.
Quick Start
// src/routes/posts/data.remote.ts
import { formSchema } from 'omni-svelte/remote';
import { Post } from '$models';
// Automatically infers Zod string for title, text for content, etc.
export const postFormSchema = formSchema(Post.schema, {
pick: ['title', 'content'],
partial: false
});You can then pass this derived schema into a remote form function to enforce strict server-side validation:
import { form } from '@sveltejs/kit';
export const createPost = form({
schema: postFormSchema,
action: async (event, input) => {
// input is strongly typed based on the schema!
return await Post.create(input);
}
});Options Reference
The second argument to formSchema allows you to pick, omit, and modify the fields derived from the database model.
Picking and Omitting
Use pick to whitelist fields (recommended for security) or omit to blacklist them:
// Only allow title and content
const createSchema = formSchema(Post.schema, {
pick: ['title', 'content']
});
// Allow everything except internal timestamps
const updateSchema = formSchema(Post.schema, {
omit: ['created_at', 'updated_at']
});Note: You cannot use both
pickandomitat the same time. Choose one.
Partial schemas (for Updates)
When building an update form, you usually don't require the user to submit every single field. Set partial: true to make all fields optional:
const updateSchema = formSchema(Post.schema, {
pick: ['title', 'content', 'published'],
partial: true // All fields become optional
});Overriding field types
Sometimes the database column type doesn't perfectly match the form input you want to receive. For example, a belongsTo relationship might be represented as an integer in the database, but you want to validate that the user submitted a valid array of IDs for a multi-select.
Use overrides to inject a custom Zod validation for specific keys:
import { z } from 'zod';
const schema = formSchema(Post.schema, {
pick: ['title', 'author_id'],
overrides: {
// Override the default number validation with a custom rule
author_id: z.number().positive("Author must be a valid ID")
}
});Working with resource()
If you are using the resource() generator, you don't need to call formSchema() manually! resource() automatically uses formSchema() under the hood to generate schemas based on your fillable configuration.
export const { create, update } = resource(Post, {
fillable: {
create: ['title', 'content'], // Uses formSchema with pick
update: ['title', 'content', 'published'] // Uses formSchema with pick + partial
}
});