Skip to content

Commit

Permalink
Alias schema.query to schema.querystring (#1690) (#1694)
Browse files Browse the repository at this point in the history
  • Loading branch information
raghavmac authored and Eomm committed Jun 9, 2019
1 parent 41a94c3 commit bdc137e
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/Fluent-Schema.md
Expand Up @@ -43,7 +43,7 @@ const headersJsonSchema = S.object()

const schema = {
body: bodyJsonSchema.valueOf(),
querystring: queryStringJsonSchema.valueOf(),
querystring: queryStringJsonSchema.valueOf(), // (or) query: queryStringJsonSchema.valueOf()
params: paramsJsonSchema.valueOf(),
headers: headersJsonSchema.valueOf()
}
Expand Down
2 changes: 1 addition & 1 deletion docs/Routes.md
Expand Up @@ -16,7 +16,7 @@ They need to be in

* `body`: validates the body of the request if it is a POST or a
PUT.
* `querystring`: validates the querystring. This can be a complete JSON
* `querystring` or `query`: validates the querystring. This can be a complete JSON
Schema object, with the property `type` of `object` and `properties` object of parameters, or
simply the values of what would be contained in the `properties` object as shown below.
* `params`: validates the params.
Expand Down
2 changes: 1 addition & 1 deletion docs/Validation-and-Serialization.md
Expand Up @@ -14,7 +14,7 @@ Fastify uses a schema-based approach, and even if it is not mandatory we recomme
### Validation
The route validation internally relies upon [Ajv](https://www.npmjs.com/package/ajv), which is a high-performance JSON schema validator. Validating the input is very easy: just add the fields that you need inside the route schema, and you are done! The supported validations are:
- `body`: validates the body of the request if it is a POST or a PUT.
- `querystring`: validates the query string. This can be a complete JSON Schema object (with a `type` property of `'object'` and a `'properties'` object containing parameters) or a simpler variation in which the `type` and `properties` attributes are forgone and the query parameters are listed at the top level (see the example below).
- `querystring` or `query`: validates the query string. This can be a complete JSON Schema object (with a `type` property of `'object'` and a `'properties'` object containing parameters) or a simpler variation in which the `type` and `properties` attributes are forgone and the query parameters are listed at the top level (see the example below).
- `params`: validates the route params.
- `headers`: validates the request headers.

Expand Down
1 change: 1 addition & 0 deletions lib/errors.js
Expand Up @@ -53,6 +53,7 @@ createError('FST_ERR_SEND_INSIDE_ONERR', 'You cannot use `send` inside the `onEr
createError('FST_ERR_SCH_MISSING_ID', `Missing schema $id property`)
createError('FST_ERR_SCH_ALREADY_PRESENT', `Schema with id '%s' already declared!`)
createError('FST_ERR_SCH_NOT_PRESENT', `Schema with id '%s' does not exist!`)
createError('FST_ERR_SCH_DUPLICATE', `Schema with '%s' already present!`)

/**
* wrapThenable
Expand Down
12 changes: 11 additions & 1 deletion lib/schemas.js
Expand Up @@ -6,7 +6,8 @@ const {
codes: {
FST_ERR_SCH_MISSING_ID,
FST_ERR_SCH_ALREADY_PRESENT,
FST_ERR_SCH_NOT_PRESENT
FST_ERR_SCH_NOT_PRESENT,
FST_ERR_SCH_DUPLICATE
}
} = require('./errors')

Expand Down Expand Up @@ -38,6 +39,15 @@ Schemas.prototype.resolve = function (id) {
}

Schemas.prototype.resolveRefs = function (routeSchemas, dontClearId) {
// alias query to querystring schema
if (routeSchemas.query) {
// check if our schema has both querystring and query
if (routeSchemas.querystring) {
throw new FST_ERR_SCH_DUPLICATE('querystring')
}
routeSchemas.querystring = routeSchemas.query
}

// let's check if our schemas have a custom prototype
for (const key of ['headers', 'querystring', 'params', 'body']) {
if (typeof routeSchemas[key] === 'object' && Object.getPrototypeOf(routeSchemas[key]) !== Object.prototype) {
Expand Down
57 changes: 57 additions & 0 deletions test/internals/validation.test.js
Expand Up @@ -74,6 +74,37 @@ test('build schema - payload schema', t => {
t.is(typeof opts[symbols.bodySchema], 'function')
})

test('build schema - query schema', t => {
t.plan(2)
const opts = {
schema: {
query: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
validation.build(opts, schema => ajv.compile(schema), new Schemas())
t.type(opts[symbols.querystringSchema].schema.type, 'string')
t.is(typeof opts[symbols.querystringSchema], 'function')
})

test('build schema - query schema abbreviated', t => {
t.plan(2)
const opts = {
schema: {
query: {
hello: { type: 'string' }
}
}
}
validation.build(opts, schema => ajv.compile(schema), new Schemas())
t.type(opts[symbols.querystringSchema].schema.type, 'string')
t.is(typeof opts[symbols.querystringSchema], 'function')
})

test('build schema - querystring schema', t => {
t.plan(2)
const opts = {
Expand Down Expand Up @@ -105,6 +136,32 @@ test('build schema - querystring schema abbreviated', t => {
t.is(typeof opts[symbols.querystringSchema], 'function')
})

test('build schema - must throw if querystring and query schema exist', t => {
t.plan(2)
try {
const opts = {
schema: {
query: {
type: 'object',
properties: {
hello: { type: 'string' }
}
},
querystring: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
validation.build(opts, schema => ajv.compile(schema), new Schemas())
} catch (err) {
t.is(err.code, 'FST_ERR_SCH_DUPLICATE')
t.is(err.message, 'FST_ERR_SCH_DUPLICATE: Schema with \'querystring\' already present!')
}
})

test('build schema - params schema', t => {
t.plan(1)
const opts = {
Expand Down

0 comments on commit bdc137e

Please sign in to comment.