Skip to content

Commit

Permalink
feat: support where & order in navigation & surround utils
Browse files Browse the repository at this point in the history
  • Loading branch information
farnabaz committed Nov 26, 2024
1 parent 9b4635e commit e8df390
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 8 deletions.
44 changes: 39 additions & 5 deletions src/runtime/app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Collections, PageCollections, CollectionQueryBuilder, SurroundOptions } from '@nuxt/content'
import type { Collections, PageCollections, CollectionQueryBuilder, SurroundOptions, SQLOperator } from '@nuxt/content'
import { collectionQureyBuilder } from './internal/query'
import { measurePerformance } from './internal/performance'
import { generateNavigationTree } from './internal/navigation'
Expand All @@ -7,16 +7,21 @@ import { generateSearchSections } from './internal/search'
import { fetchQuery } from './internal/api'
import { tryUseNuxtApp } from '#imports'

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

export const queryCollection = <T extends keyof Collections>(collection: T): CollectionQueryBuilder<Collections[T]> => {
return collectionQureyBuilder<T>(collection, (collection, sql) => executeContentQuery(collection, sql))
}

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

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

export async function queryCollectionSearchSections(collection: keyof Collections, opts?: { ignoredTags: string[] }) {
Expand Down Expand Up @@ -45,3 +50,32 @@ async function queryContentSqlClientWasm<T extends keyof Collections, Result = C

return rows as Result[]
}

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

const chainable: ChainablePromise<T, Result> = {
where(field, operator, value) {
queryBuilder.where(String(field), operator, value)
return chainable
},
order(field, direction) {
queryBuilder.order(String(field), direction)
return chainable
},
then(onfulfilled, onrejected) {
return fn(queryBuilder).then(onfulfilled, onrejected)
},
catch(onrejected) {
return this.then(undefined, onrejected)
},
finally(onfinally) {
return this.then(undefined, undefined).finally(onfinally)
},
get [Symbol.toStringTag]() {
return 'Promise'
},
}

return chainable
}
40 changes: 37 additions & 3 deletions src/runtime/nitro.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
import type { Collections, CollectionQueryBuilder, PageCollections, SurroundOptions } from '@nuxt/content'
import type { Collections, CollectionQueryBuilder, PageCollections, SurroundOptions, SQLOperator } from '@nuxt/content'
import type { H3Event } from 'h3'
import { collectionQureyBuilder } from './internal/query'
import { generateNavigationTree } from './internal/navigation'
import { generateItemSurround } from './internal/surround'
import { generateSearchSections } from './internal/search'
import { fetchQuery } from './internal/api'

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

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

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

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

export async function queryCollectionSearchSections(event: H3Event, collection: keyof Collections, opts?: { ignoredTags: string[] }) {
return generateSearchSections(queryCollectionWithEvent(event, collection), opts)
}

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

const chainable: ChainablePromise<T, Result> = {
where(field, operator, value) {
queryBuilder.where(String(field), operator, value)
return chainable
},
order(field, direction) {
queryBuilder.order(String(field), direction)
return chainable
},
then(onfulfilled, onrejected) {
return fn(queryBuilder).then(onfulfilled, onrejected)
},
catch(onrejected) {
return this.then(undefined, onrejected)
},
finally(onfinally) {
return this.then(undefined, undefined).finally(onfinally)
},
get [Symbol.toStringTag]() {
return 'Promise'
},
}

return chainable
}

0 comments on commit e8df390

Please sign in to comment.