Schema Registry
The schema registry provides type-safe access to your registered schemas with full TypeScript inference via discriminated unions.
Registering Schemas
Pass your Zod schemas in the schemas option when initializing the client. Each schema is identified by a unique key.
import { ProposeFlow } from '@proposeflow/sdk';
import { z } from 'zod';
const blogPostSchema = z.object({
title: z.string(),
content: z.string(),
tags: z.array(z.string()),
});
const productSchema = z.object({
name: z.string(),
price: z.number(),
description: z.string(),
});
// Register schemas in the constructor
export const pf = new ProposeFlow({
apiKey: process.env.PROPOSEFLOW_API_KEY!,
schemas: {
blogPost: blogPostSchema,
product: productSchema,
},
});Type Inference
TypeScript automatically infers the correct types based on your schemas using discriminated unions.
// The generate() method knows the return type based on schema name
const { proposal: blogProposal } = await pf.generate('blogPost', {
input: 'Write about TypeScript',
});
// blogProposal.generatedObject is typed as { title: string; content: string; tags: string[] }
console.log(blogProposal.generatedObject.title); // ✓ TypeScript knows this is a string
console.log(blogProposal.generatedObject.price); // ✗ Error: 'price' doesn't exist
const { proposal: productProposal } = await pf.generate('product', {
input: 'A wireless keyboard',
});
// productProposal.generatedObject is typed as { name: string; price: number; description: string }
console.log(productProposal.generatedObject.price); // ✓ TypeScript knows this is a numberAutomatic Schema Registration
The easiest way to manage schemas is with automatic registration. Enable autoRegisterSchemas and the SDK will automatically register schemas when you call generate().
import { ProposeFlow } from '@proposeflow/sdk';
import { z } from 'zod';
const blogPostSchema = z.object({
title: z.string(),
content: z.string(),
tags: z.array(z.string()),
});
export const pf = new ProposeFlow({
apiKey: process.env.PROPOSEFLOW_API_KEY!,
schemas: {
blogPost: blogPostSchema,
},
schemaSync: 'hash', // Use content-based versioning
autoRegisterSchemas: true, // Auto-register on first generate()
});
// No manual registration needed - just generate!
const { proposal } = await pf.generate('blogPost', {
input: 'Write about TypeScript generics',
});With hash-based sync, schemas are versioned by their content. If you modify your Zod schema, a new version is automatically registered on the next generate() call.
Manual Schema Registration
You can also register schemas manually with explicit version strings. This gives you more control over versioning and lets you add descriptions and event field allowlists.
// Register a single schema from the registry
const schema = await pf.schemas.register('blogPost', {
version: '1.0.0',
description: 'A blog post for a tech company website',
eventFields: ['title', 'content', 'tags'],
});
// Or register all schemas at once
const schemas = await pf.schemas.registerAll({
version: '1.0.0',
});
console.log(schemas);
// { blogPost: { id: 'sch_abc...', ... }, product: { id: 'sch_xyz...', ... } }Discriminated Unions
When fetching proposals, use the schemaName field to narrow the type.
// Fetch proposals - returns a discriminated union
const { data: proposals } = await pf.proposals.list({ status: 'pending' });
for (const proposal of proposals) {
// Use schemaName to narrow the type
if (proposal.schemaName === 'blogPost') {
// TypeScript knows this is a BlogPost
console.log(proposal.generatedObject.title);
console.log(proposal.generatedObject.tags);
} else if (proposal.schemaName === 'product') {
// TypeScript knows this is a Product
console.log(proposal.generatedObject.name);
console.log(proposal.generatedObject.price);
}
}Listing Registered Schemas
// List all schemas registered to your account
const { data: schemas, nextCursor } = await pf.schemas.list({
limit: 10,
});
for (const schema of schemas) {
console.log(schema.name, schema.id, schema.version);
}
// Get a specific schema by ID
const schema = await pf.schemas.get('sch_abc123');
// Delete a schema by ID
await pf.schemas.delete('sch_abc123');Type Helpers
Use the InferSchema helper to extract types from your schemas.
import { InferSchema } from '@proposeflow/sdk';
const blogPostSchema = z.object({
title: z.string(),
content: z.string(),
});
// Extract the type
type BlogPost = InferSchema<typeof blogPostSchema>;
// { title: string; content: string }
// Or use z.infer directly
type BlogPost = z.infer<typeof blogPostSchema>;