DocSchemaBuilder
A fluent API for building type-safe schemas in a chainable style. DocSchemaBuilder provides compile-time type inference as you build your schema.
Basic Usage
Create schemas using method chaining with automatic type inference:
import { DocSchemaBuilder } from '@interactive-inc/docs-client'
const schema = new DocSchemaBuilder()
.text('title', true) // required text field
.text('description', false) // optional text field
.relation('author', true) // required relation
.multiText('tags', false) // optional multi-text
.build()
// Use with DocClient
const fileRef = client.mdFile('article.md', schema)
Available Field Types
text(key, required)
Single-line text field for simple string values.
const schema = new DocSchemaBuilder()
.text('title', true) // required
.text('subtitle', false) // optional
.build()
number(key, required)
Numeric field for integer or decimal values.
const schema = new DocSchemaBuilder()
.number('price', true)
.number('discount', false)
.build()
boolean(key, required)
Boolean field for true/false values.
const schema = new DocSchemaBuilder()
.boolean('published', true)
.boolean('featured', false)
.build()
relation(key, required)
Reference to a single related document.
const schema = new DocSchemaBuilder()
.relation('author', true)
.relation('category', false)
.build()
multiRelation(key, required)
References to multiple related documents.
const schema = new DocSchemaBuilder()
.multiRelation('contributors', true)
.multiRelation('relatedPosts', false)
.build()
selectText(key, required)
Single selection from predefined text options.
const schema = new DocSchemaBuilder()
.selectText('status', true) // e.g., draft, published, archived
.selectText('priority', false) // e.g., low, medium, high
.build()
multiText(key, required)
Multiple text values as an array.
const schema = new DocSchemaBuilder()
.multiText('tags', false)
.multiText('keywords', false)
.build()
Additional Field Types
The builder also supports these specialized field types:
selectNumber(key, required)
- Single numeric selectionmultiNumber(key, required)
- Multiple numeric valuesmultiSelectText(key, required)
- Multiple text selectionsmultiSelectNumber(key, required)
- Multiple numeric selections
Type Safety
DocSchemaBuilder provides full type inference, making your schema type-safe:
// Schema is fully typed
const articleSchema = new DocSchemaBuilder()
.text('title', true)
.relation('author', true)
.multiText('tags', false)
.boolean('published', false)
.build()
// Use with file reference
const articleRef = client.mdFile('blog/post.md', articleSchema)
const article = await articleRef.read()
if (article instanceof Error) throw article
const meta = article.content.meta()
// TypeScript knows these field types
const title = meta.text('title') // string
const author = meta.relation('author') // string | undefined
const tags = meta.multiText('tags') // string[] | undefined
const published = meta.boolean('published') // boolean | undefined
Complex Schema Example
Build comprehensive schemas for content management:
const blogPostSchema = new DocSchemaBuilder()
// Core fields
.text('title', true)
.text('slug', true)
.text('description', true)
// Authorship
.relation('author', true)
.multiRelation('contributors', false)
// Categorization
.relation('category', true)
.multiText('tags', false)
// Publishing
.boolean('published', false)
.text('publishedAt', false)
.selectText('status', true)
// SEO
.text('metaTitle', false)
.text('metaDescription', false)
.multiText('keywords', false)
.build()
// Apply schema to directory
const postsDir = client.directory('posts')
const indexRef = await postsDir.index()
if (indexRef && !(await indexRef.exists())) {
// Create index with schema definition
await client.indexFile('posts').writeText(`---
title: Blog Posts
schema:
title:
type: text
required: true
author:
type: relation
path: ../authors
required: true
tags:
type: multi-text
required: false
published:
type: boolean
default: false
---
# Blog Posts
Articles and tutorials.`)
}
Migration from defineSchema
If you're using the older defineSchema
approach, DocSchemaBuilder provides a more intuitive API:
// Old approach
import { defineSchema, docCustomSchemaField } from '@interactive-inc/docs-client'
const oldSchema = defineSchema({
title: docCustomSchemaField.text(true),
tags: docCustomSchemaField.multiText(false)
})
// New approach with DocSchemaBuilder
const newSchema = new DocSchemaBuilder()
.text('title', true)
.multiText('tags', false)
.build()
// Both produce the same schema
Best Practices
- Start with Required Fields: Define required fields first for better readability
- Group Related Fields: Keep related fields together (e.g., all SEO fields)
- Use Descriptive Names: Choose clear, semantic field names
- Consider Defaults: Plan which fields should have default values in index.md
// Well-organized schema
const productSchema = new DocSchemaBuilder()
// Essential info
.text('name', true)
.text('sku', true)
.number('price', true)
// Inventory
.number('stock', true)
.boolean('inStock', true)
// Categorization
.relation('category', true)
.relation('brand', false)
.multiText('tags', false)
// Media
.text('thumbnail', false)
.multiText('images', false)
.build()