Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: improvements #201

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineConfig } from 'vitepress'

export default defineConfig({
title: 'Velite',
description: "Velite is a tool for building type-safe data layer, turn Markdown/MDX, YAML, JSON, or other files into app's data layer with Zod schema.",
description: "Velite is a tool for building type-safe data layer, turns Markdown/MDX, YAML, JSON, or other files into app's data layer with Zod schema.",
lastUpdated: true,
cleanUrls: true,
head: [
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ basic

```shell
$ npm install # install dependencies
$ npm run dev # run build with watch mode
$ npm run dev # run build in watch mode
$ npm run build # build content by velite
```

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/nextjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ nextjs

```shell
$ npm install # install dependencies
$ npm run dev # run build with watch mode
$ npm run dev # run build in watch mode
$ npm run build # build content by velite
```

Expand Down
14 changes: 6 additions & 8 deletions docs/guide/code-highlighting.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Code Highlighting

Considering that not all content contains code, and that syntax highlighting often comes with custom styles, Velite doesn't want to subjectively determine the final presentation of your content. So we don't include built-in code highlighting features.

If you think code highlighting is necessary for your content, you can implement if by referring to the following methods.
Velite doesn't include built-in code highlighting features because not all content contains code, and that syntax highlighting often comes with custom styles. But you can easily implement it yourself with build-time plugins or client-side highlighters.

## rehype-pretty-code

Expand Down Expand Up @@ -38,7 +36,7 @@ export default defineConfig({
})
```

Add some necessary styles, such as:
`rehype-pretty-code` creates the proper HTML structure for syntax highlighting, you can then add styles however you like. Here is an example stylesheet:

```css
[data-rehype-pretty-code-figure] pre {
Expand Down Expand Up @@ -78,7 +76,7 @@ Add some necessary styles, such as:
}
```

refer to [examples](https://github.com/zce/velite/blob/main/examples/nextjs/velite.config.ts) for more details.
Refer to [examples](https://github.com/zce/velite/blob/main/examples/nextjs/velite.config.ts) for more details.

## @shikijs/rehype

Expand Down Expand Up @@ -165,9 +163,9 @@ export default defineConfig({

## Client-side

Code highlighting in Client-side. You can use [prismjs](https://prismjs.com) or [shiki](https://shiki.matsu.io) to highlight code in client-side.
You can use [prismjs](https://prismjs.com) or [shiki](https://shiki.matsu.io) to highlight code on the client side. Client-side highlighting does not add build overhead to Velite.

for example:
For example:

```js
import { codeToHtml } from 'https://esm.sh/shikiji'
Expand All @@ -179,6 +177,6 @@ Array.from(document.querySelectorAll('pre code[class*="language-"]')).map(async

::: tip

This method is most recommended if there are a large number of documents that need to be processed frequently. Because syntax highlighting and parsing is very time-consuming, it will greatly affect the construction speed of Velite.
If you have a large of number of documents that need to be syntax highlighted, it is recommended to use the client-side method. Because syntax highlighting and parsing can be very time-consuming, and it will greatly affect the construction speed of Velite.

:::
2 changes: 1 addition & 1 deletion docs/guide/custom-loader.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Custom Loader

built-in loaders are:
Built-in loaders are:

- `matter-loader`: parse frontmatter and provide content and data
- `json-loader`: parse document as json
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/custom-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Schema is the core of Velite. It defines the structure and type of your content and validates it.
>
> refer to [Velite Schemas](velite-schemas.md) for more information about built-in schema.
> Refer to [Velite Schemas](velite-schemas.md) for more information about built-in schema.

Velite supports custom schema. A schema is a JavaScript function that returns a [Zod](https://zod.dev) schema object.

Expand Down Expand Up @@ -33,7 +33,7 @@ export const hello = defineSchema(() =>
)
```

refer to [Zod documentation](https://zod.dev) for more information about Zod.
Refer to [Zod documentation](https://zod.dev) for more information about Zod.

## Define a Transformation Schema

Expand Down
16 changes: 8 additions & 8 deletions docs/guide/define-collections.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Define Collections

Content collections are the best way to manage and author content in content-first applications. Velite help to organize and validate your your contents, and provide automatic TypeScript type-safety for all of your contents.
Content collections are the best way to manage and author content in content-first applications. Velite helps you organize and validate your contents, and provides type-safety through automatic type generations.

## What is a Collection?

Expand Down Expand Up @@ -86,7 +86,7 @@ const site = defineCollection({

Velite uses [Zod](https://zod.dev) to validate the content items in a collection. The `schema` option is used to define the Zod schema used to validate the content items in the collection.

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](https://zod.dev) for complete documentation on how Zod works and what features are available.
To use Zod in Velite, import the `z` utility from `'velite'`. This is a re-export of Zod's `z` object, and it supports all of the features of Zod. See [Zod's Docs](https://zod.dev) for a complete documentation on how Zod works and what features are available.

```js
import { z } from 'velite'
Expand All @@ -104,7 +104,7 @@ The schema is usually a `ZodObject`, validating the shape of the content item. B

:::

For more useful schemas, I recommend that you use [Velite extended schemas `s`](velite-schemas.md):
For more complex schemas, I recommend that you use [Velite extended schemas `s`](velite-schemas.md):

- `s.slug()`: validate slug format, unique in posts collection.
- `s.isodate()`: format date string to ISO date string.
Expand Down Expand Up @@ -156,7 +156,7 @@ const posts = defineCollection({

### Transform Context Metadata

The transform function can receive a second argument, which is the context object. This is useful for adding computed fields to the content items in a collection.
The `transform()` function can receive a second argument, which is the context object. This is useful for adding computed fields to the content items in a collection.

```js
const posts = defineCollection({
Expand All @@ -176,9 +176,9 @@ the type of `meta` is `ZodMeta`, which extends [`VeliteFile`](../reference/types

## Content Body

Velite built-in Loader keep content raw body in `meta.content`, and plain text body in `meta.plain`.
Velite's built-in loader keeps content's raw body in `meta.content`, and the plain text body in `meta.plain`.

To extract the original content, you can customize a schema.
To add them as a field, you can use a custom schema.

```js
const posts = defineCollection({
Expand Down Expand Up @@ -237,11 +237,11 @@ Velite can extract excerpt from content files. This is useful for adding compute
```js
const posts = defineCollection({
schema: s.object({
excerpt: s.excerpt() // excerpt of markdown content
excerpt: s.excerpt({ length: 200 }) // excerpt of the markdown body
})
})
```

#### Reference

- [`s.excerpt()`](velite-schemas.md#s-excerpt)
- [`s.excerpt(options)`](velite-schemas.md#s-excerpt)
10 changes: 5 additions & 5 deletions docs/guide/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

::: warning

🚧 this documentation is not yet complete currently. but the functionality is mostly stable, although there is still a possibility of significant changes being made.
🚧 This documentation is not yet complete currently. but the functionality is mostly stable, although there is still a possibility of significant changes being made.

However, I have provided some [examples](https://github.com/zce/velite/tree/main/examples) for your consideration.

:::

## What is Velite?

Velite is a tool for building type-safe data layer, turn Markdown / MDX, YAML, JSON, or other files into app's data layer with Zod schema.
Velite is a tool for building type-safe data layer, turns Markdown / MDX, YAML, JSON, or other files into app's data layer with Zod schema.

![Velite Workflow](/assets/flow-dark.svg#dark 'Velite Workflow')
![Velite Workflow](/assets/flow.svg#light 'Velite Workflow')
Expand All @@ -24,7 +24,7 @@ Velite is a tool for building type-safe data layer, turn Markdown / MDX, YAML, J
## Key Features

- **Easy to use**: Move your contents into `content` folder, define collections schema, run `velite`, then use the output data in your application.
- **Type-safe**: Contents schema validation by [Zod](https://zod.dev), and generate type inference for TypeScript.
- **Type-safe**: Contents schema validation by [Zod](https://zod.dev), and generate type definitions for TypeScript.
- **Framework Agnostic**: JSON & Entry & DTS output, out of the box support for any JavaScript framework or library.
- **Light-weight**: Choose more native APIs instead of bloated NPM modules, less runtime dependencies, so it is fast and efficiently.
- **Still powerful**: Built-in Markdown / MDX, YAML, JSON support, relative files & images processing, schema validation, etc.
Expand All @@ -51,13 +51,13 @@ You can try Velite directly in your browser on StackBlitz, It runs Velite direct

### Type-Safe Contents

Velite validates your contents by [Zod](https://zod.dev) schema, and generates type inference for TypeScript. so you can use the output data in your application with confidence.
Velite validates your contents by [Zod](https://zod.dev) schema, and generates type definitions for TypeScript. so you can use the output data in your application with confidence.

### Full Type inference

<p><video src="/assets/type-inference@2x.mp4" loop muted autoplay /></p>

- auto-generate TypeScript type inference for each collection
- auto-generate TypeScript type definitions for each collection
- support IDE IntelliSense, auto-completion & type checking & refactoring & etc.

### Full Controllable Content Transform
Expand Down
59 changes: 38 additions & 21 deletions docs/guide/last-modified.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
# Last Modified Schema

We provide a last modified timestamp schema based on file stat and git timestamp.
You can create a custom schema to show the last modified time for your contents. This can be based on:

- File stat

- Git timestamp

## Based on file stat

create a timestamp schema based on file stat.
Create a timestamp schema based on file stat.

```ts
const timestamp = () =>
s.custom<string | undefined>(i => i === undefined || typeof i === 'string').transform<string>(async (value, { meta, addIssue }) => {
if (value != null) {
addIssue({ fatal: false, code: 'custom', message: '`s.timestamp()` schema will resolve the file modified timestamp' })
}

const stats = await stat(meta.path)
return stats.mtime.toISOString()
})
import { stat } from 'fs/promises'
import { defineSchema } from 'velite'

const timestamp = defineSchema(() =>
s
.custom<string | undefined>(i => i === undefined || typeof i === 'string')
.transform<string>(async (value, { meta, addIssue }) => {
if (value != null) {
addIssue({ fatal: false, code: 'custom', message: '`s.timestamp()` schema will resolve the file modified timestamp' })
}

const stats = await stat(meta.path)
return stats.mtime.toISOString()
})
)
```

use it in your schema
Use it in your schema

```ts
const posts = defineCollection({
Expand All @@ -33,19 +43,26 @@ const posts = defineCollection({
## Based on git timestamp

```ts
import { exec } from 'child_process'
import { promisify } from 'util'
import { defineSchema } from 'velite'

const execAsync = promisify(exec)

const timestamp = () =>
s.custom<string | undefined>(i => i === undefined || typeof i === 'string').transform<string>(async (value, { meta, addIssue }) => {
if (value != null) {
addIssue({ fatal: false, code: 'custom', message: '`s.timestamp()` schema will resolve the value from `git log -1 --format=%cd`' })
}
const { stdout } = await execAsync(`git log -1 --format=%cd ${meta.path}`)
return new Date(stdout).toISOString()
})
const timestamp = defineSchema(() =>
s
.custom<string | undefined>(i => i === undefined || typeof i === 'string')
.transform<string>(async (value, { meta, addIssue }) => {
if (value != null) {
addIssue({ fatal: false, code: 'custom', message: '`s.timestamp()` schema will resolve the value from `git log -1 --format=%cd`' })
}
const { stdout } = await execAsync(`git log -1 --format=%cd ${meta.path}`)
return new Date(stdout).toISOString()
})
)
```

use it in your schema
Use it in your schema

```ts
const posts = defineCollection({
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ echo '\npublic/static' >> .gitignore

:::

## Run Velite with Watch Mode
## Run Velite in Watch Mode

Run `velite dev` or `velite` with `--watch` option, then Velite will watch the contents files and rebuild them automatically when they are changed.
When the `--watch` flag is used with `velite dev` or `velite`, Velite will watch the contents files and rebuild them automatically when they are changed.

::: code-group

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/using-markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Markdown is a lightweight markup language with plain text formatting syntax. It

::: tip Markdown or MDX

Markdown is top-level supported in Velite, Although we also support MDX, I think that MDX is not the best choice for content creators. Although it is powerful and has stronger programmability, it is easy to lose the essence of writing and recording, and become addicted to technology.
Markdown has top-level support in Velite. Although we also support MDX, I think that MDX is not the best choice for content creators. Although it is powerful and has stronger programmability, it is easy to lose the essence of writing and recording, and become addicted to technology.

- **Portable**: Markdown is portable, you can use it anywhere, even in the terminal.
- **Simple**: Markdown is simple, you can learn it in 10 minutes, don't need to spend a lot of time to learn React.
Expand Down
20 changes: 10 additions & 10 deletions docs/guide/using-mdx.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Velite supports MDX out of the box. You can use MDX to write your content, and V

## Getting Started

For example, you have the following content structure:
For example, suppose you have the following content structure:

```diff {2,3,4}
project-root
Expand All @@ -21,7 +21,7 @@ project-root
└── velite.config.js
```

In your `./content/posts/hello-world.mdx`:
The`./content/posts/hello-world.mdx` document is a MDX document with the following content:

```mdx
---
Expand All @@ -39,7 +39,7 @@ flood conditions in many of the nearby rivers.
<Chart year={year} color="#fcb32c" />
```

In your `./velite.config.js`:
Use the `s.mdx()` schema to add the compiled MDX code to your content collection.

```js {10}
import { defineConfig, s } from 'velite'
Expand Down Expand Up @@ -75,7 +75,7 @@ By default, Velite will compile the MDX content into a function-body string, whi

## Rendering MDX Content

First of all, you can create a component to render the MDX content:
First, you can create a generic component for rendering the compiled mdx code. It should accept the code and a list of components that are used in the MDX content.

`./components/mdx-content.tsx`:

Expand Down Expand Up @@ -128,7 +128,7 @@ export default function Post({ params: { slug } }) {

### How to import components in MDX?

Velite's built-in `s.mdx()` schema does not support importing components in MDX. The main reason is that I don't want a lot of repetition and redundancy in the output code.
You don't need to, since Velite's `s.mdx()` schema does not bundle those components at build time. There is no need to construct a import tree. This can help reduce output size for your contents.

For example, suppose you extract a common component for multiple MDXs and import the component in these MDXs.

Expand Down Expand Up @@ -167,9 +167,9 @@ import { Callout } from '../components/callout'

:::

If Velite uses bundling to compile MDX, the `Callout` component will be bundled into each MDX file, which will cause a lot of redundancy in the output code.
If Velite uses a bundler to comiple your MDX, the `Callout` component will be bundled into each MDX file, which will cause a lot of redundancy in the output code.

If you want to use components in MDX, you can use the following workaround:
Instead, simply use whatever components you want in your MDX files without a import.

::: code-group

Expand Down Expand Up @@ -212,7 +212,7 @@ export default function Post({ params: { slug } }) {
}
```

or Global components:
You can also add global components so that they are available to all MDX files.

```tsx {3,7}
import * as runtime from 'react/jsx-runtime'
Expand Down Expand Up @@ -240,9 +240,9 @@ export const MDXContent = ({ code, components }: MDXProps) => {
}
```

### How to bundle MDX?
### What if I want to bundle MDX?

If your scenario can ignore the size of data and duplication of code, bundling MDX is really a better choice because it has better portability.
If you can make do with the increased output size, bundling MDX can be a good option for better portability.

You can install the following packages to bundle MDX:

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/velite-schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { s } from 'velite'

`string => string`

format date string to ISO date string.
Format date string to ISO date string.

```ts
date: s.isodate()
Expand Down
Loading