# useDocyrusDataSourceJsonSchema URL: /docs/web/hooks/use-docyrus-data-source-json-schema Generate a JSON Schema (object schema, properties keyed by field slug) from a Docyrus data source field list. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/hooks-use-docyrus-data-source-json-schema ``` This hook is distributed as source. It is fully standalone — it ships its own `JsonSchema` type and a Docyrus field-type → JSON Schema mapping, so it has no runtime dependency on the JSON Schema Designer or the form-fields system. ## Overview `useDocyrusDataSourceJsonSchema` turns an array of Docyrus field descriptors into a standard **object JSON Schema** (Draft 2020-12 / Draft-07 compatible). Each field becomes one property: - `field.slug` → the property **key** (machine name). - `field.name` → the property `title` (user-facing label). - `field.type` → the property `type` / `format` (via the built-in field-type map). - `field.description` → the property `description`. Use it to drive AI Structured Outputs / tool definitions, runtime validation (Ajv, Zod-from-JSON-Schema, etc.), form generation, or any flow that needs a machine-readable contract for a data source. The hook is a pure, memoized transform — no state, no effects, no fetching. ## Usage ```tsx 'use client'; import { useDocyrusDataSourceJsonSchema } from '@/hooks/use-docyrus-data-source-json-schema'; const fields = [ { slug: 'full_name', name: 'Full Name', type: 'field-text', description: 'Contact full name' }, { slug: 'email', name: 'Email', type: 'field-email' }, { slug: 'status', name: 'Status', type: 'field-status', description: 'Pipeline stage' }, { slug: 'tags', name: 'Tags', type: 'field-tagSelect' }, { slug: 'revenue', name: 'Annual Revenue', type: 'field-money' }, ]; export function ContactSchema() { const schema = useDocyrusDataSourceJsonSchema(fields, { title: 'Contact', description: 'A CRM contact record', }); return
{JSON.stringify(schema, null, 2)};
}
```
Produces:
```json
{
"type": "object",
"properties": {
"full_name": { "type": "string", "title": "Full Name", "description": "Contact full name" },
"email": { "type": "string", "format": "email", "title": "Email" },
"status": { "type": "string", "title": "Status", "description": "Pipeline stage" },
"tags": { "type": "array", "items": { "type": "string" }, "title": "Tags" },
"revenue": { "type": "number", "title": "Annual Revenue" }
},
"additionalProperties": true,
"title": "Contact",
"description": "A CRM contact record"
}
```
### OpenAI Structured Outputs (strict mode)
Set `strict: true` to constrain the output to OpenAI Structured Outputs rules — `additionalProperties: false` plus every field slug listed in `required`:
```tsx
const schema = useDocyrusDataSourceJsonSchema(fields, { title: 'Contact', strict: true });
// schema.additionalProperties === false
// schema.required === ['full_name', 'email', 'status', 'tags', 'revenue']
```
### Marking fields required
```tsx
// every field required
useDocyrusDataSourceJsonSchema(fields, { required: true });
// only specific slugs required
useDocyrusDataSourceJsonSchema(fields, { required: ['full_name', 'email'] });
```
### Refining individual fields with `overrides`
The built-in mapping uses pragmatic defaults (single-choice / reference fields → `string`, multi-choice → `array` of `string`, structured fields → open `object`). When a field needs a tighter shape, deep-merge an override keyed by slug:
```tsx
const schema = useDocyrusDataSourceJsonSchema(fields, {
overrides: {
// narrow an enum/status field to a fixed set of option ids
status: { enum: ['lead', 'qualified', 'won', 'lost'] },
// describe the shape of a relation reference
owner: { type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' } } },
},
});
```
Overrides are deep-merged onto the generated property (override wins; nested objects merge recursively), so `title`/`description` derived from the field metadata are preserved unless you replace them explicitly.
### Outside React
Both `buildDataSourceJsonSchema` and `fieldToJsonSchema` are pure and can be called from server components, API routes, or AI tool-definition builders:
```ts
import { buildDataSourceJsonSchema } from '@/hooks/use-docyrus-data-source-json-schema';
const schema = buildDataSourceJsonSchema(fields, { strict: true });
```
## API Reference
### `useDocyrusDataSourceJsonSchema(fields, options?)`
| Parameter | Type | Description |
|-----------|------|-------------|
| `fields` | `DataSourceFieldDescriptor[]` | Field list. Each entry: `{ slug, name, type, description? }`. |
| `options` | `UseDocyrusDataSourceJsonSchemaOptions` | Generation options (see below). |
Returns a memoized `JsonSchema` object. Memoization keys on `fields` and each option — pass a stable `fields` reference to avoid rebuilding on every render.
### `DataSourceFieldDescriptor`
| Field | Type | Description |
|-------|------|-------------|
| `slug` | `string` | Machine name → JSON Schema **property key**. Fields without a slug are skipped. |
| `name` | `string` | User-facing label → property `title`. |
| `type` | `IFieldType` | Docyrus field type (e.g. `field-text`, `field-email`, `field-status`). Drives `type` / `format`. |
| `description` | `string \| null` | Optional → property `description`. |
### `UseDocyrusDataSourceJsonSchemaOptions`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `title` | `string` | `—` | `title` for the root object schema. |
| `description` | `string` | `—` | `description` for the root object schema. |
| `required` | `boolean \| string[]` | `—` | `true` → all slugs required; `string[]` → listed slugs required; omitted → no `required` array. |
| `strict` | `boolean` | `false` | OpenAI Structured Outputs mode: forces `additionalProperties: false` + all slugs `required`. Overrides `required` and `additionalProperties`. |
| `additionalProperties` | `boolean` | `true` | Root-level `additionalProperties`. Ignored when `strict`. |
| `includeTitles` | `boolean` | `true` | Emit each property's `title` from `field.name`. |
| `includeDescriptions` | `boolean` | `true` | Emit each property's `description` from `field.description`. |
| `includeDialect` | `boolean` | `false` | Include the `$schema` dialect keyword on the root. |
| `dialect` | `string` | `DEFAULT_JSON_SCHEMA_DIALECT` | Dialect URI used when `includeDialect` is set. |
| `overrides` | `Record