Velite Schemas
To use Zod in Velite, import the z utility from 'velite'. This is a re-export of the Zod library, and it supports all of the features of Zod.
See Zod's Docs for complete documentation on how Zod works and what features are available.
import { z } from 'velite'
// `z` is re-export of ZodIn addition, Velite has extended Zod schemas, added some commonly used features when building content models, you can import s from 'velite' to use these extended schemas.
import { s } from 'velite'
// `s` is extended from Zod with some custom schemas,
// `s` also includes all members of zod, so you can use `s` as `z`s.isodate()
string => string
Format date string to ISO date string.
date: s.isodate()
// case 1. valid date string
// '2017-01-01' => '2017-01-01T00:00:00.000Z'
// case 2. valid datetime string
// '2017-01-01 10:10:10' => '2017-01-01T10:10:10.000Z'
// case 3. invalid date string
// 'foo bar invalid' => issue 'Invalid date string's.unique(by)
string => string
validate unique value in collections.
name: s.unique('taxonomies')
// case 1. unique value
// 'foo' => 'foo'
// case 2. non-unique value (in all unique by 'taxonomies')
// 'foo' => issue 'Already exists'Parameters
by: unique identifier
- type:
string - default:
'global'
s.slug(by, reserved)
string => string
base on s.unique(), unique in collections, not allow reserved values, and validate slug format.
slug: s.slug('taxonomies', ['admin', 'login'])
// case 1. unique slug value
// 'hello-world' => 'hello-world'
// case 2. non-unique value (in all unique by 'taxonomies')
// 'hello-world' => issue 'Slug already exists'
// case 3. reserved slug value
// 'admin' => issue 'Slug is reserved'
// case 4. invalid slug value
// 'Hello World' => issue 'Invalid slug'Parameters
by: unique identifier
- type:
string - default:
'global'
reserved: reserved values
- type:
string[] - default:
[]
s.file(options)
string => string
file path relative to this file, copy file to config.output.assets directory and return the public url.
avatar: s.file()
// case 1. relative path
// 'avatar.png' => '/static/avatar-34kjfdsi.png'
// case 2. non-exists file
// 'not-exists.png' => issue 'File not exists'
// case 3. absolute path or full url (if allowed)
// '/icon.png' => '/icon.png'
// 'https://zce.me/logo.png' => 'https://zce.me/logo.png'Parameters
options.allowNonRelativePath:
allow non-relative path, if true, the value will be returned directly, if false, the value will be processed as a relative path
- type:
boolean - default:
true
s.image(options)
string => Image
image path relative to this file, like s.file(), copy file to config.output.assets directory and return the Image (image object with meta data).
avatar: s.image()
// case 1. relative path
// 'avatar.png' => {
// src: '/static/avatar-34kjfdsi.png',
// width: 100,
// height: 100,
// blurDataURL: 'data:image/png;base64,xxx',
// blurWidth: 8,
// blurHeight: 8
// }
// case 2. non-exists file
// 'not-exists.png' => issue 'File not exists'
// case 3. absolute path or full url (if allowed)
// '/icon.png' => { src: '/icon.png', width: 0, height: 0, blurDataURL: '', blurWidth: 0, blurHeight: 0 }
// 'https://zce.me/logo.png' => { src: 'https://zce.me/logo.png', width: 0, height: 0, blurDataURL: '', blurWidth: 0, blurHeight: 0 }Parameters
options.absoluteRoot:
root path for absolute path, if provided, the value will be processed as an absolute path.
- type:
string - default:
undefined
Types
/**
* Image object with metadata & blur image
*/
interface Image {
/**
* public url of the image
*/
src: string
/**
* image width
*/
width: number
/**
* image height
*/
height: number
/**
* blurDataURL of the image
*/
blurDataURL: string
/**
* blur image width
*/
blurWidth: number
/**
* blur image height
*/
blurHeight: number
}s.metadata()
string => Metadata
parse input or document body as markdown content and return Metadata.
currently only support readingTime & wordCount.
metadata: s.metadata()
// document body => { readingTime: 2, wordCount: 100 }Types
/**
* Document metadata.
*/
interface Metadata {
/**
* Reading time in minutes.
*/
readingTime: number
/**
* Word count.
*/
wordCount: number
}s.excerpt(options)
string => string
parse input or document body as markdown content and return excerpt text.
excerpt: s.excerpt()
// document body => excerpt textParameters
options: excerpt options
options.length:
excerpt length.
- type:
number - default:
260
s.markdown(options)
string => string
parse input or document body as markdown content and return html content. refer to Markdown Support for more information.
content: s.markdown()
// => html contentParameters
options: markdown options
- type:
MarkdownOptions, See MarkdownOptions - default:
{ gfm: true, removeComments: true, copyLinkedFiles: true }
s.mdx(options)
string => string
parse input or document body as mdx content and return component function-body. refer to MDX Support for more information.
code: s.mdx()
// => function-bodyParameters
options: mdx options
- type:
MdxOptions, See MdxOptions - default:
{ gfm: true, removeComments: true, copyLinkedFiles: true }
s.raw()
string => string
return raw document body.
code: s.raw()
// => raw document bodys.toc(options)
string => TocEntry[] | TocTree
parse input or document body as markdown content and return the table of contents.
toc: s.toc()
// document body => table of contentsParameters
options: toc options
- type:
TocOptions, See Options
options.original:
keep the original table of contents.
- type:
boolean - default:
false
Types
interface TocEntry {
/**
* Title of the entry
*/
title: string
/**
* URL that can be used to reach
* the content
*/
url: string
/**
* Nested items
*/
items: TocEntry[]
}
/**
* Tree for table of contents
*/
export interface TocTree {
/**
* Index of the node right after the table of contents heading, `-1` if no
* heading was found, `undefined` if no `heading` was given.
*/
index?: number
/**
* Index of the first node after `heading` that is not part of its section,
* `-1` if no heading was found, `undefined` if no `heading` was given, same
* as `index` if there are no nodes between `heading` and the first heading
* in the table of contents.
*/
endIndex?: number
/**
* List representing the generated table of contents, `undefined` if no table
* of contents could be created, either because no heading was found or
* because no following headings were found.
*/
map?: List
}Refer to mdast-util-toc for more information about Result and Options.
s.path(options)
=> string
get flattened path based on the file path.
path: s.path()
// => flattened path, e.g. 'posts/2021-01-01-hello-world'Parameters
options: flattening options
- type:
PathOptions
options.removeIndex:
Removes index from the path.
- type:
boolean - default:
true
Zod Primitive Types
In addition, all Zod's built-in schemas can be used normally, such as:
title: s.string().mix(3).max(100)
description: s.string().optional()
featured: s.boolean().default(false)You can refer to https://zod.dev get complete support documentation.
Define a Custom Schema
Refer to Custom Schema for more information about custom schema.