Skip to content

Commit

Permalink
feat: allow absolute path in s.image() (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
zce authored Apr 10, 2024
1 parent 2c2b6f6 commit 467f5b2
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 103 deletions.
3 changes: 2 additions & 1 deletion docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ export default defineConfig({
{ text: 'Asset Handling', link: 'asset-handling' },
{ text: 'Code Highlighting', link: 'code-highlighting' },
{ text: 'Integration with Next.js', link: 'with-nextjs' },
{ text: 'Custom Loader', link: 'custom-loader' }
{ text: 'Custom Loader', link: 'custom-loader' },
{ text: 'Custom Schema', link: 'custom-schema' }
// { text: 'Fast Refresh', link: 'fast-refresh' }
]
},
Expand Down
41 changes: 30 additions & 11 deletions docs/guide/custom-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@ export const title = defineSchema(() => s.string().transform(value => value.toUp
// ...
```

### Example

#### Remote Image with BlurDataURL Schema

```ts
import { getImageMetadata, s } from 'velite'

import type { Image } from 'velite'

/**
* Remote Image with metadata schema
*/
export const remoteImage = () =>
s.string().transform<Image>(async (value, { addIssue }) => {
try {
const response = await fetch(value)
const blob = await response.blob()
const buffer = await blob.arrayBuffer()
const metadata = await getImageMetadata(Buffer.from(buffer))
if (metadata == null) throw new Error(`Failed to get image metadata: ${value}`)
return { src: value, ...metadata }
} catch (err) {
const message = err instanceof Error ? err.message : String(err)
addIssue({ code: 'custom', message })
return null as never
}
})
```

## Schema Context

> [!TIP]
Expand All @@ -67,14 +96,4 @@ export const path = defineSchema(() =>

### Reference

```ts
interface ZodMeta extends VeliteMeta {}

class VeliteMeta extends VFile {
config: Config
// raw file content body
get content(): string | undefined
// plain text content body
get plain(): string | undefined
}
```
the type of `meta` is `ZodMeta`, which extends [`VeliteFile`](../reference/types.md#VeliteFile).
14 changes: 1 addition & 13 deletions docs/guide/define-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,7 @@ const posts = defineCollection({
})
```

#### Reference

```ts
interface ZodMeta extends VeliteMeta {}

class VeliteMeta extends VFile {
config: Config
// raw file content body
get content(): string | undefined
// plain text content body
get plain(): string | undefined
}
```
the type of `meta` is `ZodMeta`, which extends [`VeliteFile`](../reference/types.md#VeliteFile). for more information, see [Custom Schema](custom-schema.md).

## Content Body

Expand Down
77 changes: 18 additions & 59 deletions docs/guide/velite-schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,26 +115,18 @@ avatar: s.file()

#### **options**: file options

- type: `FileOptions`, See [FileOptions](#types)
- default: `{ allowNonRelativePath: true }`
##### **options.allowNonRelativePath**:

### Types
allow non-relative path, if true, the value will be returned directly, if false, the value will be processed as a relative path

```ts
interface FileOptions {
/**
* Allow non-relative path.
* @default true
*/
allowNonRelativePath?: boolean
}
```
- type: `boolean`
- default: `true`

## `s.image()`

`string => Image`

image path relative to this file, like `s.file()`, copy file to `config.output.assets` directory and return the [Image](#types-1) (image object with meta data).
image path relative to this file, like `s.file()`, copy file to `config.output.assets` directory and return the [Image](#types) (image object with meta data).

```ts
avatar: s.image()
Expand All @@ -160,20 +152,14 @@ avatar: s.image()

#### **options**: image options

- type: `ImageOptions`, See [ImageOptions](#types-1)
- default: `{ allowNonRelativePath: false }`
##### **options.absoluteRoot**:

### Types
root path for absolute path, if provided, the value will be processed as an absolute path.

```ts
interface ImageOptions {
/**
* Allow non-relative path.
* @default false
*/
allowNonRelativePath?: boolean
}
```
- type: `string`
- default: `undefined`

### Types

```ts
/**
Expand Down Expand Up @@ -211,7 +197,7 @@ interface Image {

`string => Metadata`

parse input or document body as markdown content and return [Metadata](#types-2).
parse input or document body as markdown content and return [Metadata](#types-1).

currently only support `readingTime` & `wordCount`.

Expand Down Expand Up @@ -253,20 +239,12 @@ excerpt: s.excerpt()

#### **options**: excerpt options

- type: `ExcerptOptions`, See [ExcerptOptions](#types-3)
- default: `{ length: 260 }`
##### **options.length**:

### Types
excerpt length.

```ts
interface ExcerptOptions {
/**
* Excerpt length.
* @default 260
*/
length?: number
}
```
- type: `number`
- default: `260`

## `s.markdown(options)`

Expand Down Expand Up @@ -319,7 +297,7 @@ code: s.raw()

`string => TocEntry[] | TocTree`

parse input or document body as markdown content and return the table of contents.
parse input or document body as markdown content and return the [table of contents](#types-2).

```ts
toc: s.toc()
Expand Down Expand Up @@ -404,30 +382,11 @@ path: s.path()

##### **options.removeIndex**:

Removes index from path for subfolders
Removes `index` from the path.

- type: `boolean`
- default: `true`

### Types

```ts
/**
* Options for flattened path
* extraction
*/
export interface PathOptions {
/**
* removes `index` from the path
*
* `/docs/general/index.md` => `docs/general`
*
* @default false
*/
removeIndex?: boolean
}
```

## Zod Primitive Types

In addition, all Zod's built-in schemas can be used normally, such as:
Expand Down
27 changes: 27 additions & 0 deletions docs/other/snippets.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Snippets

#### Remote Image with BlurDataURL Schema

```ts
import { getImageMetadata, s } from 'velite'

import type { Image } from 'velite'

/**
* Remote Image with metadata schema
*/
export const remoteImage = () =>
s.string().transform<Image>(async (value, { addIssue }) => {
try {
const response = await fetch(value)
const blob = await response.blob()
const buffer = await blob.arrayBuffer()
const metadata = await getImageMetadata(Buffer.from(buffer))
if (metadata == null) throw new Error(`Failed to get image metadata: ${value}`)
return { src: value, ...metadata }
} catch (err) {
const message = err instanceof Error ? err.message : String(err)
addIssue({ code: 'custom', message })
return null as never
}
})
```

## Built-in `s.mdx()` schema result render

```tsx
Expand Down
47 changes: 47 additions & 0 deletions docs/reference/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,53 @@ interface Loader {
}
```

## VeliteFile

```ts
interface ZodMeta extends File {}

class File extends VFile {
/**
* Get parsed records from file
*/
get records(): unknown

/**
* Get content of file
*/
get content(): string | undefined

/**
* Get mdast object from cache
*/
get mdast(): Root | undefined

/**
* Get hast object from cache
*/
get hast(): Nodes | undefined

/**
* Get plain text of content from cache
*/
get plain(): string | undefined

/**
* Get meta object from cache
* @param path file path
* @returns resolved meta object if exists
*/
static get(path: string): File | undefined

/**
* Create meta object from file path
* @param options meta options
* @returns resolved meta object
*/
static async create({ path, config }: { path: string; config: Config }): Promise<File>
}
```

## MarkdownOptions

```ts
Expand Down
2 changes: 1 addition & 1 deletion src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class File extends VFile {
}

/**
* Get resolved data from cache
* Get parsed records from file
*/
get records(): unknown {
return this.data.data
Expand Down
15 changes: 9 additions & 6 deletions src/schemas/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { string } from './zod'

export interface FileOptions {
/**
* allow non-relative path
* allow non-relative path, if true, the value will be returned directly, if false, the value will be processed as a relative path
* @default true
*/
allowNonRelativePath?: boolean
Expand All @@ -13,10 +13,13 @@ export interface FileOptions {
* A file path relative to this file.
*/
export const file = ({ allowNonRelativePath = true }: FileOptions = {}) =>
string().transform<string>((value, { meta: { path, config }, addIssue }) => {
if (allowNonRelativePath && !isRelativePath(value)) return value
return processAsset(value, path, config.output.name, config.output.base).catch(err => {
addIssue({ code: 'custom', message: err.message })
string().transform<string>(async (value, { meta: { path, config }, addIssue }) => {
try {
if (allowNonRelativePath && !isRelativePath(value)) return value
return await processAsset(value, path, config.output.name, config.output.base)
} catch (err) {
const message = err instanceof Error ? err.message : String(err)
addIssue({ code: 'custom', message })
return null as never
})
}
})
Loading

0 comments on commit 467f5b2

Please sign in to comment.