Skip to content
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
18 changes: 18 additions & 0 deletions src/runtime/internal/event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { H3Event } from 'h3'

/**
* The event a `nuxt/server` handler receives (Nuxt 4.6+).
* Declared here instead of imported, `nuxt/server` does not resolve on older Nuxt versions.
*/
export interface RequestEvent {
readonly req: Request
url: URL
readonly res: {
status?: number
statusText?: string
readonly headers: Headers
}
readonly context: Record<string, unknown>
}

export type ContentEvent = H3Event | RequestEvent
4 changes: 2 additions & 2 deletions src/runtime/nitro.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as server from './server'
import type { Collections, CollectionQueryBuilder } from '@nuxt/content'
import type { H3Event } from 'h3'
import type { ContentEvent } from './internal/event'

/**
* `@nuxt/content/nitro` import is deprecated and will be removed in the next major version.
Expand All @@ -10,7 +10,7 @@ import type { H3Event } from 'h3'
/**
* @deprecated Import from `@nuxt/content/server` instead
*/
export const queryCollection = <T extends keyof Collections>(event: H3Event, collection: T): CollectionQueryBuilder<Collections[T]> => {
export const queryCollection = <T extends keyof Collections>(event: ContentEvent, collection: T): CollectionQueryBuilder<Collections[T]> => {
return server.queryCollection(event, collection)
}

Expand Down
18 changes: 10 additions & 8 deletions src/runtime/server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { H3Event } from 'h3'
import type { ContentEvent } from './internal/event'
import { collectionQueryBuilder } from './internal/query'
import { generateNavigationTree } from './internal/navigation'
import { generateItemSurround } from './internal/surround'
Expand All @@ -7,6 +8,7 @@ import { fetchQuery } from './internal/api'
import type { Collections, CollectionQueryBuilder, PageCollections, SurroundOptions, SQLOperator, QueryGroupFunction } from '@nuxt/content'

export type { GenerateSearchSectionsOptions, Section } from './internal/search'
export type { ContentEvent, RequestEvent } from './internal/event'

interface ChainablePromise<T extends keyof PageCollections, R> extends Promise<R> {
where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise<T, R>
Expand All @@ -15,37 +17,37 @@ interface ChainablePromise<T extends keyof PageCollections, R> extends Promise<R
order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise<T, R>
}

export const queryCollection = <T extends keyof Collections>(event: H3Event, collection: T): CollectionQueryBuilder<Collections[T]> => {
return collectionQueryBuilder<T>(collection, (collection, sql) => fetchQuery(event, collection, sql))
export const queryCollection = <T extends keyof Collections>(event: ContentEvent, collection: T): CollectionQueryBuilder<Collections[T]> => {
return collectionQueryBuilder<T>(collection, (collection, sql) => fetchQuery(event as H3Event, collection, sql))
}

export function queryCollectionNavigation<T extends keyof PageCollections>(event: H3Event, collection: T, fields?: Array<keyof PageCollections[T]>) {
export function queryCollectionNavigation<T extends keyof PageCollections>(event: ContentEvent, collection: T, fields?: Array<keyof PageCollections[T]>) {
return chainablePromise(event, collection, qb => generateNavigationTree(qb, fields))
}

export function queryCollectionItemSurroundings<T extends keyof PageCollections>(event: H3Event, collection: T, path: string, opts?: SurroundOptions<keyof PageCollections[T]>) {
export function queryCollectionItemSurroundings<T extends keyof PageCollections>(event: ContentEvent, collection: T, path: string, opts?: SurroundOptions<keyof PageCollections[T]>) {
return chainablePromise(event, collection, qb => generateItemSurround(qb, path, opts))
}

export function queryCollectionSearchSections<T extends keyof PageCollections, const K extends keyof PageCollections[T]>(
event: H3Event,
event: ContentEvent,
collection: T,
opts: Omit<GenerateSearchSectionsOptions, 'extraFields'> & { extraFields: K[] },
): ChainablePromise<T, Array<Section & Pick<PageCollections[T], K>>>
export function queryCollectionSearchSections<T extends keyof PageCollections>(
event: H3Event,
event: ContentEvent,
collection: T,
opts?: GenerateSearchSectionsOptions,
): ChainablePromise<T, Section[]>
export function queryCollectionSearchSections<T extends keyof PageCollections>(
event: H3Event,
event: ContentEvent,
collection: T,
opts?: GenerateSearchSectionsOptions,
) {
return chainablePromise(event, collection, qb => generateSearchSections(qb, opts))
}

function chainablePromise<T extends keyof PageCollections, Result>(event: H3Event, collection: T, fn: (qb: CollectionQueryBuilder<PageCollections[T]>) => Promise<Result>) {
function chainablePromise<T extends keyof PageCollections, Result>(event: ContentEvent, collection: T, fn: (qb: CollectionQueryBuilder<PageCollections[T]>) => Promise<Result>) {
const queryBuilder = queryCollection(event, collection)

const chainable: ChainablePromise<T, Result> = {
Expand Down
8 changes: 8 additions & 0 deletions test/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,13 @@ describe('basic', async () => {
expect(doc.arrayField).toContain('item2')
expect(doc.numberField).toBe(1)
})

test('retrieve document from a `nuxt/server` handler', async () => {
const doc = await $fetch('/api/content/get?path=/')
const { content, navigation } = await $fetch<{ content: unknown, navigation: unknown[] }>('/api/content/nuxt-server?path=/')

expect(content).toEqual(doc)
expect(navigation.length).toBeGreaterThan(0)
})
})
})
10 changes: 10 additions & 0 deletions test/fixtures/basic/server/api/content/nuxt-server.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineEventHandler, getQuery } from 'nuxt/server'

export default defineEventHandler(async (event) => {
const path = getQuery<{ path?: string }>(event).path || '/'

const content = await queryCollection(event, 'content').path(path).first()
const navigation = await queryCollectionNavigation(event, 'content')

return { content, navigation }
})
Loading