Skip to content

Commit e8df390

Browse files
committed
feat: support where & order in navigation & surround utils
1 parent 9b4635e commit e8df390

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

src/runtime/app.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Collections, PageCollections, CollectionQueryBuilder, SurroundOptions } from '@nuxt/content'
1+
import type { Collections, PageCollections, CollectionQueryBuilder, SurroundOptions, SQLOperator } from '@nuxt/content'
22
import { collectionQureyBuilder } from './internal/query'
33
import { measurePerformance } from './internal/performance'
44
import { generateNavigationTree } from './internal/navigation'
@@ -7,16 +7,21 @@ import { generateSearchSections } from './internal/search'
77
import { fetchQuery } from './internal/api'
88
import { tryUseNuxtApp } from '#imports'
99

10+
interface ChainablePromise<T extends keyof PageCollections, R> extends Promise<R> {
11+
where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise<T, R>
12+
order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise<T, R>
13+
}
14+
1015
export const queryCollection = <T extends keyof Collections>(collection: T): CollectionQueryBuilder<Collections[T]> => {
1116
return collectionQureyBuilder<T>(collection, (collection, sql) => executeContentQuery(collection, sql))
1217
}
1318

14-
export async function queryCollectionNavigation<T extends keyof PageCollections>(collection: T, fields?: Array<keyof PageCollections[T]>) {
15-
return generateNavigationTree(queryCollection(collection), fields)
19+
export function queryCollectionNavigation<T extends keyof PageCollections>(collection: T, fields?: Array<keyof PageCollections[T]>) {
20+
return chainablePromise(collection, qb => generateNavigationTree(qb, fields))
1621
}
1722

18-
export async function queryCollectionItemSurroundings<T extends keyof PageCollections>(collection: T, path: string, opts?: SurroundOptions<keyof PageCollections[T]>) {
19-
return generateItemSurround(queryCollection(collection), path, opts)
23+
export function queryCollectionItemSurroundings<T extends keyof PageCollections>(collection: T, path: string, opts?: SurroundOptions<keyof PageCollections[T]>) {
24+
return chainablePromise(collection, qb => generateItemSurround(qb, path, opts))
2025
}
2126

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

4651
return rows as Result[]
4752
}
53+
54+
function chainablePromise<T extends keyof PageCollections, Result>(collection: T, fn: (qb: CollectionQueryBuilder<PageCollections[T]>) => Promise<Result>) {
55+
const queryBuilder = queryCollection(collection)
56+
57+
const chainable: ChainablePromise<T, Result> = {
58+
where(field, operator, value) {
59+
queryBuilder.where(String(field), operator, value)
60+
return chainable
61+
},
62+
order(field, direction) {
63+
queryBuilder.order(String(field), direction)
64+
return chainable
65+
},
66+
then(onfulfilled, onrejected) {
67+
return fn(queryBuilder).then(onfulfilled, onrejected)
68+
},
69+
catch(onrejected) {
70+
return this.then(undefined, onrejected)
71+
},
72+
finally(onfinally) {
73+
return this.then(undefined, undefined).finally(onfinally)
74+
},
75+
get [Symbol.toStringTag]() {
76+
return 'Promise'
77+
},
78+
}
79+
80+
return chainable
81+
}

src/runtime/nitro.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,57 @@
1-
import type { Collections, CollectionQueryBuilder, PageCollections, SurroundOptions } from '@nuxt/content'
1+
import type { Collections, CollectionQueryBuilder, PageCollections, SurroundOptions, SQLOperator } from '@nuxt/content'
22
import type { H3Event } from 'h3'
33
import { collectionQureyBuilder } from './internal/query'
44
import { generateNavigationTree } from './internal/navigation'
55
import { generateItemSurround } from './internal/surround'
66
import { generateSearchSections } from './internal/search'
77
import { fetchQuery } from './internal/api'
88

9+
interface ChainablePromise<T extends keyof PageCollections, R> extends Promise<R> {
10+
where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise<T, R>
11+
order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise<T, R>
12+
}
13+
914
export const queryCollectionWithEvent = <T extends keyof Collections>(event: H3Event, collection: T): CollectionQueryBuilder<Collections[T]> => {
1015
return collectionQureyBuilder<T>(collection, (collection, sql) => fetchQuery(event, collection, sql))
1116
}
1217

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

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

2126
export async function queryCollectionSearchSections(event: H3Event, collection: keyof Collections, opts?: { ignoredTags: string[] }) {
2227
return generateSearchSections(queryCollectionWithEvent(event, collection), opts)
2328
}
29+
30+
function chainablePromise<T extends keyof PageCollections, Result>(event: H3Event, collection: T, fn: (qb: CollectionQueryBuilder<PageCollections[T]>) => Promise<Result>) {
31+
const queryBuilder = queryCollectionWithEvent(event, collection)
32+
33+
const chainable: ChainablePromise<T, Result> = {
34+
where(field, operator, value) {
35+
queryBuilder.where(String(field), operator, value)
36+
return chainable
37+
},
38+
order(field, direction) {
39+
queryBuilder.order(String(field), direction)
40+
return chainable
41+
},
42+
then(onfulfilled, onrejected) {
43+
return fn(queryBuilder).then(onfulfilled, onrejected)
44+
},
45+
catch(onrejected) {
46+
return this.then(undefined, onrejected)
47+
},
48+
finally(onfinally) {
49+
return this.then(undefined, undefined).finally(onfinally)
50+
},
51+
get [Symbol.toStringTag]() {
52+
return 'Promise'
53+
},
54+
}
55+
56+
return chainable
57+
}

0 commit comments

Comments
 (0)