-
-
Notifications
You must be signed in to change notification settings - Fork 604
/
query.ts
88 lines (74 loc) · 3.12 KB
/
query.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import type { QueryBuilder, SortOptions } from '../types'
import { ParsedContent } from '../types'
import { ContentQueryBuilder, ContentQueryBuilderParams, ContentQueryFetcher } from '../types/query'
import { ensureArray } from './match/utils'
const arrayParams = ['sort', 'where', 'only', 'without']
interface QueryOptions {
initialParams?: ContentQueryBuilderParams
legacy?: boolean
}
export function createQuery <T = ParsedContent>(fetcher: ContentQueryFetcher<T>, opts: QueryOptions & { legacy: true }): QueryBuilder<T>
export function createQuery <T = ParsedContent>(fetcher: ContentQueryFetcher<T>, opts: QueryOptions & { legacy: false }): ContentQueryBuilder<T>
export function createQuery <T = ParsedContent> (fetcher: ContentQueryFetcher<T>, opts: QueryOptions = {}) {
const queryParams: ContentQueryBuilderParams = {}
for (const key of Object.keys(opts.initialParams || {})) {
queryParams[key] = arrayParams.includes(key) ? ensureArray(opts.initialParams![key]) : opts.initialParams![key]
}
/**
* Factory function to create a parameter setter
*/
const $set = (key: string, fn: (...values: any[]) => any = v => v) => {
return (...values: any[]) => {
queryParams[key] = fn(...values)
return query
}
}
const resolveResult = (result: any) => {
if (opts.legacy) {
if (result?.surround) {
return result.surround
}
if (!result) {
return result
}
if ((result as any)?.dirConfig) {
result.result = {
_path: (result as any).dirConfig?._path,
...(result.result as T),
_dir: (result as any).dirConfig
}
}
return result?._path || Array.isArray(result) || !Object.prototype.hasOwnProperty.call(result, 'result') ? result : result?.result
}
return result
}
const query: any = {
params: () => ({
...queryParams,
...(queryParams.where ? { where: [...ensureArray(queryParams.where)] } : {}),
...(queryParams.sort ? { sort: [...ensureArray(queryParams.sort)] } : {})
}),
only: $set('only', ensureArray),
without: $set('without', ensureArray),
where: $set('where', (q: any) => [...ensureArray(queryParams.where), ...ensureArray(q)]),
sort: $set('sort', (sort: SortOptions) => [...ensureArray(queryParams.sort), ...ensureArray(sort)]),
limit: $set('limit', v => parseInt(String(v), 10)),
skip: $set('skip', v => parseInt(String(v), 10)),
// find
find: () => fetcher(query as unknown as ContentQueryBuilder<T>).then(resolveResult),
findOne: () => fetcher($set('first')(true)).then(resolveResult),
count: () => fetcher($set('count')(true)).then(resolveResult),
// locale
locale: (_locale: string) => query.where({ _locale }),
withSurround: $set('surround', (surroundQuery, options) => ({ query: surroundQuery, ...options })),
withDirConfig: () => $set('dirConfig')(true)
}
if (opts.legacy) {
// @ts-ignore
query.findSurround = (surroundQuery, options) => {
return query.withSurround(surroundQuery, options).findOne().then(resolveResult)
}
return query as QueryBuilder<T>
}
return query as ContentQueryBuilder<T>
}