-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
Copy pathvalidateQueryPaths.ts
98 lines (90 loc) · 2.65 KB
/
validateQueryPaths.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
89
90
91
92
93
94
95
96
97
98
// @ts-strict-ignore
import type { SanitizedCollectionConfig } from '../../collections/config/types.js'
import type { FlattenedField } from '../../fields/config/types.js'
import type { SanitizedGlobalConfig } from '../../globals/config/types.js'
import type { Operator, PayloadRequest, Where, WhereField } from '../../types/index.js'
import type { EntityPolicies } from './types.js'
import { QueryError } from '../../errors/QueryError.js'
import { validOperatorSet } from '../../types/constants.js'
import { validateSearchParam } from './validateSearchParams.js'
type Args = {
errors?: { path: string }[]
overrideAccess: boolean
policies?: EntityPolicies
polymorphicJoin?: boolean
req: PayloadRequest
versionFields?: FlattenedField[]
where: Where
} & (
| {
collectionConfig: SanitizedCollectionConfig
globalConfig?: never | undefined
}
| {
collectionConfig?: never | undefined
globalConfig: SanitizedGlobalConfig
}
)
const flattenWhere = (query: Where): WhereField[] => {
const flattenedConstraints: WhereField[] = []
for (const [key, val] of Object.entries(query)) {
if ((key === 'and' || key === 'or') && Array.isArray(val)) {
for (const subVal of val) {
flattenedConstraints.push(...flattenWhere(subVal))
}
} else {
flattenedConstraints.push({ [key]: val })
}
}
return flattenedConstraints
}
export async function validateQueryPaths({
collectionConfig,
errors = [],
globalConfig,
overrideAccess,
policies = {
collections: {},
globals: {},
},
polymorphicJoin,
req,
versionFields,
where,
}: Args): Promise<void> {
const fields = versionFields || (globalConfig || collectionConfig).flattenedFields
if (typeof where === 'object') {
const whereFields = flattenWhere(where)
// We need to determine if the whereKey is an AND, OR, or a schema path
const promises = []
for (const constraint of whereFields) {
for (const path in constraint) {
for (const operator in constraint[path]) {
const val = constraint[path][operator]
if (validOperatorSet.has(operator as Operator)) {
promises.push(
validateSearchParam({
collectionConfig,
errors,
fields,
globalConfig,
operator,
overrideAccess,
path,
policies,
polymorphicJoin,
req,
val,
versionFields,
}),
)
}
}
}
}
await Promise.all(promises)
if (errors.length > 0) {
throw new QueryError(errors)
}
}
}