Skip to content

Commit

Permalink
feat: add result hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
GerryWilko committed Nov 23, 2023
1 parent 802666d commit 029bc0e
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
37 changes: 37 additions & 0 deletions docs/content/3.composables/1.query-content.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,40 @@ const count = await queryContent('articles')
// Returns
5 // number of articles
```

## `resultHook(hook)`

- `hook`
- Type: `(content: T) => HT`
- **Required**

Add a hook for to be executed on the results of the content query.

This hook is useful for simple transforms of returned content or validation of returned data with libraries such as `zod`.

```ts
// Some example front-matter on a content page
const articleSchema = z.object({
navigation: z.object({
nextBtn: z.string()
})
})

// Validate each returned article
const articles = await queryContent('articles')
.resultHook(c => articleSchema.parse(c))
.find()
```

You can also use `resultHook(hook)` to augment the returned content with new fields.

```ts
// Count of articles
const articles = await queryContent('articles')
.resultHook(c => {
...c,
newField: 'some-data'
})
.find()
```

6 changes: 3 additions & 3 deletions src/runtime/query/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ export function createQuery <T = ParsedContent> (fetcher: ContentQueryFetcher<T>

const resolveResultHooks = (result: any) => {
let res = result
for (let h of resultHooks) {
for (const h of resultHooks) {
res = h(res)
}
return res
}

const resolveResult = (result: any) => {
let ret: any
let ret = result
if (opts.legacy) {
if (result?.surround) {
return result.surround
Expand Down Expand Up @@ -68,7 +68,7 @@ export function createQuery <T = ParsedContent> (fetcher: ContentQueryFetcher<T>
return resolveResultHooks(ret)
}

return result
return ret
}

const query: any = {
Expand Down
5 changes: 5 additions & 0 deletions src/runtime/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,11 @@ export interface QueryBuilder<T = ParsedContentMeta> {
*/
locale(locale: string): QueryBuilder<T>

/**
* Add result hook to returned content
*/
resultHook<HT>(hook: (content: T) => HT): QueryBuilder<HT>

/**
* Retrieve query builder params
* @internal
Expand Down
13 changes: 13 additions & 0 deletions test/features/query/query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,17 @@ describe('Database Provider', () => {
expect(item._deleted).toBeUndefined()
})
})

test('Result Hook transform return', async () => {
const query = createQuery(pipelineFetcher, { legacy: true })
.where({ id: { $in: [1, 2] } })
.resultHook((c) => { return { transformedPath: c._path, exampleExtraField: 'hello' } })
const result = await query.find()

result.forEach((item: any) => {
expect(Object.keys(item)).toMatchObject(['transformedPath', 'exampleExtraField'])
assert(item.exampleExtraField === 'hello')
expect(item.id).toBeUndefined()
})
})
})

0 comments on commit 029bc0e

Please sign in to comment.