Skip to content

Commit

Permalink
[schema] Validate reference filter and filterParams properties
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars committed Dec 18, 2019
1 parent 67f9ef6 commit 0ff5cad
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
Expand Up @@ -18,6 +18,9 @@ export const HELP_IDS = {
ARRAY_OF_NOT_UNIQUE: 'schema-array-of-invalid',
REFERENCE_TO_INVALID: 'schema-reference-to-invalid',
REFERENCE_TO_NOT_UNIQUE: 'schema-reference-to-invalid',
REFERENCE_INVALID_OPTIONS: 'schema-reference-invalid-options',
REFERENCE_INVALID_OPTIONS_LOCATION: 'schema-reference-options-nesting',
REFERENCE_INVALID_FILTER_PARAMS_COMBINATION: 'schema-reference-filter-params-combination',
SLUG_SLUGIFY_FN_RENAMED: 'slug-slugifyfn-renamed',
ASSET_METADATA_FIELD_INVALID: 'asset-metadata-field-invalid'
}
Expand Down
65 changes: 65 additions & 0 deletions packages/@sanity/schema/src/sanity/validation/types/reference.ts
@@ -1,6 +1,7 @@
import {error, HELP_IDS} from '../createValidationResult'
import {flatten, isPlainObject} from 'lodash'
import {getDupes} from '../utils/getDupes'
import {ValidationResult} from '../../typedefs'

function normalizeToProp(typeDef) {
if (Array.isArray(typeDef.to)) {
Expand Down Expand Up @@ -36,9 +37,73 @@ export default (typeDef, visitorContext) => {
)
}

problems.push(...getOptionErrors(typeDef))

return {
...typeDef,
to: (isValidTo ? normalizedTo : []).map(visitorContext.visit),
_problems: problems
}
}

function getOptionErrors(typeDef: any): ValidationResult[] {
const {options} = typeDef
const problems = [] as ValidationResult[]

problems.push(
...['filter', 'filterParams']
.filter(key => key in typeDef)
.map(key =>
error(
`\`${key}\` is not allowed on a reference type definition - did you mean \`options.${key}\`?`,
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
)
)
)

if (!options) {
return problems
}

if (!isPlainObject(options)) {
return problems.concat(
error(
'The reference type expects `options` to be an object',
HELP_IDS.REFERENCE_INVALID_OPTIONS
)
)
}

if (typeof options.filter === 'function' && typeof options.filterParams !== 'undefined') {
return problems.concat(
error(
'`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.',
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
)
)
}

if (typeof options.filter === 'function' || (!options.filter && !options.filterParams)) {
return problems
}

if (typeof options.filter !== 'string') {
return problems.concat(
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
)
}

if (typeof options.filterParams !== 'undefined' && !isPlainObject(options.filterParams)) {
return problems.concat(error(`If set, \`filterParams\` must be an object.`))
}

if (options.filterParams) {
return problems.concat(
Object.keys(options.filterParams)
.filter(key => key.startsWith('__') || key.startsWith('$'))
.map(key => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
)
}

return problems
}

0 comments on commit 0ff5cad

Please sign in to comment.