Skip to content

Instantly share code, notes, and snippets.

@miraris
Last active June 1, 2018 11:56
Show Gist options
  • Save miraris/23d05a7ba4d0cd7215d711f61db19a45 to your computer and use it in GitHub Desktop.
Save miraris/23d05a7ba4d0cd7215d711f61db19a45 to your computer and use it in GitHub Desktop.
A poor man’s Postgraphile args validator plugin implementation
/**
* The pagination args validator
* @param {number} opts
*/
function validator (opts) {
const options = opts || {}
const min = options.min || 1
const max = options.max || 100
return (args) => {
if (!args.first && !args.last) {
throw new Error('Must specify a `first` or `last` range')
}
// Validate conflicting args are not present
if (args.first && args.last) {
throw new Error('Can not use both `first` and `last` together')
}
if (args.before && args.after) {
throw new Error('Can not use both `before` and `after` together')
}
// Validate requested limits do not exceed allowable range
if (args.first > max || args.last > max) {
throw new Error(`Can not request more than ${max} records at a time`)
}
if (args.first < min || args.last < min) {
throw new Error(`Can not request less than ${min} records at a time`)
}
}
}
/**
* The pagination args validator plugin
* @param builder
*/
module.exports = function PageArgsValidator (builder) {
builder.hook(
'GraphQLObjectType:fields:field', (
field, {
pgSql: sql
}, {
scope: {
isPgFieldConnection,
isPgFieldSimpleCollection,
pgIntrospection: table,
pgFieldIntrospection, // smart comments
fieldName
}
}
) => {
if (
!(isPgFieldConnection || isPgFieldSimpleCollection)
) {
return field
}
const defaultResolver = obj => obj[fieldName]
const {
resolve: oldResolve = defaultResolver,
...rest
} = field
return {
...rest,
// resolver which wraps the old resolver
async resolve (...resolveParams) {
const RESOLVE_ARGS_INDEX = 1
const validate = validator({
min: 1,
max: pgFieldIntrospection.tags.paginationCap || 20
})
// validate the args on the connection field
validate(resolveParams[RESOLVE_ARGS_INDEX])
// call and return the old resolver
return oldResolve(...resolveParams)
}
}
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment