# Schema API

The schema utilities are available from the `/schema` subpath export:

```typescript
import { buildZodSchema, schemaFieldsToZodSource } from '@promptlycms/prompts/schema';
```

---

## `buildZodSchema(fields)`

Builds a Zod object schema at runtime from an array of `SchemaField` objects.

```typescript
import { buildZodSchema } from '@promptlycms/prompts/schema';

const result = await promptly.getPrompt('my-prompt');
const schema = buildZodSchema(result.config.schema);

// Use for validation
const validated = schema.parse(data);
```

### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `fields` | `SchemaField[]` | Array of schema field definitions from the CMS |

### Return type

Returns `z.ZodObject<Record<string, z.ZodTypeAny>>` - a Zod object schema with one property per field.

### How fields are built

Each `SchemaField` is processed in three layers:

1. **Type builder** - creates the base Zod type from `field.type` (e.g. `z.string()`, `z.number()`)
2. **Validation applicators** - applies validation rules from `field.validations` (e.g. `.min()`, `.email()`)
3. **Description** - adds `.describe()` if `field.params.description` is set

---

## `schemaFieldsToZodSource(fields)`

Generates Zod source code as a string from an array of `SchemaField` objects. Useful for codegen pipelines.

```typescript
import { schemaFieldsToZodSource } from '@promptlycms/prompts/schema';

const result = await promptly.getPrompt('my-prompt');
const source = schemaFieldsToZodSource(result.config.schema);
console.log(source);
```

### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `fields` | `SchemaField[]` | Array of schema field definitions from the CMS |

### Return type

Returns `string` - valid Zod source code that can be written to a file or evaluated.

### Example output

Given fields for `name` (string, min 1), `age` (number, int, positive), and `tags` (array of strings):

```typescript
z.object({
  name: z.string().min(1, 'Required'),
  age: z.number().int('Must be integer').positive('Must be positive'),
  tags: z.array(z.string()),
})
```

---

## `SchemaField` type

```typescript
type SchemaField = {
  id: string;
  name: string;
  type: string;
  validations: ValidationRule[];
  params: SchemaFieldParams;
};
```

### `ValidationRule`

```typescript
type ValidationRule = {
  id: string;
  type: string;
  message: string;
  value: string;
  transform?: string;
  keyType?: string;
  valueType?: string;
  discriminator?: string;
  cases?: Record<string, SchemaField[]>;
};
```

### `SchemaFieldParams`

```typescript
type SchemaFieldParams = {
  coerce?: boolean;
  description?: string;
  enumValues?: string[];
  unionTypes?: string[];
  elementType?: string;
  keyType?: string;
  valueType?: string;
  isTuple?: boolean;
  tupleTypes?: string[];
  isStrict?: boolean;
  isPassthrough?: boolean;
  isDiscriminatedUnion?: boolean;
  discriminator?: string;
  discriminatedUnion?: {
    discriminator: string;
    cases: Record<string, {
      value: string;
      fields: SchemaField[];
    }>;
  };
  stringOptions?: {
    datetime?: { offset?: boolean; precision?: number };
    ip?: { version?: 'v4' | 'v6' };
  };
};
```

## Supported types and validations

See the [Structured Output guide](https://docs.promptlycms.com/guides/structured-output/) for the complete list of supported types and validation rules.