| 'use strict' | ||
| const t = require('tap') | ||
| const test = t.test | ||
| const request = require('request') | ||
| const fastify = require('..')() | ||
| const schema = { | ||
| response: { | ||
| 200: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
| }, | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'number' | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| test('shorthand - output string', t => { | ||
| t.plan(1) | ||
| try { | ||
| fastify.get('/string', schema, function (req, reply) { | ||
| reply.code(200).send({ hello: 'world' }) | ||
| }) | ||
| t.pass() | ||
| } catch (e) { | ||
| t.fail() | ||
| } | ||
| }) | ||
| test('shorthand - output number', t => { | ||
| t.plan(1) | ||
| try { | ||
| fastify.get('/number', schema, function (req, reply) { | ||
| reply.code(201).send({ hello: 55 }) | ||
| }) | ||
| t.pass() | ||
| } catch (e) { | ||
| t.fail() | ||
| } | ||
| }) | ||
| test('wrong object for schema - output', t => { | ||
| t.plan(1) | ||
| try { | ||
| fastify.get('/wrong-object-for-schema', schema, function (req, reply) { | ||
| // will send { hello: null } | ||
| reply.code(201).send({ hello: 'world' }) | ||
| }) | ||
| t.pass() | ||
| } catch (e) { | ||
| t.fail() | ||
| } | ||
| }) | ||
| test('empty response', t => { | ||
| t.plan(1) | ||
| try { | ||
| // no checks | ||
| fastify.get('/empty', schema, function (req, reply) { | ||
| reply.code(204).send() | ||
| }) | ||
| t.pass() | ||
| } catch (e) { | ||
| t.fail() | ||
| } | ||
| }) | ||
| fastify.listen(0, err => { | ||
| t.error(err) | ||
| fastify.server.unref() | ||
| test('shorthand - string get ok', t => { | ||
| t.plan(4) | ||
| request({ | ||
| method: 'GET', | ||
| uri: 'http://localhost:' + fastify.server.address().port + '/string' | ||
| }, (err, response, body) => { | ||
| t.error(err) | ||
| t.strictEqual(response.statusCode, 200) | ||
| t.strictEqual(response.headers['content-length'], '' + body.length) | ||
| t.deepEqual(JSON.parse(body), { hello: 'world' }) | ||
| }) | ||
| }) | ||
| test('shorthand - number get ok', t => { | ||
| t.plan(4) | ||
| request({ | ||
| method: 'GET', | ||
| uri: 'http://localhost:' + fastify.server.address().port + '/number' | ||
| }, (err, response, body) => { | ||
| t.error(err) | ||
| t.strictEqual(response.statusCode, 201) | ||
| t.strictEqual(response.headers['content-length'], '' + body.length) | ||
| t.deepEqual(JSON.parse(body), { hello: 55 }) | ||
| }) | ||
| }) | ||
| test('shorthand - wrong-object-for-schema', t => { | ||
| t.plan(4) | ||
| request({ | ||
| method: 'GET', | ||
| uri: 'http://localhost:' + fastify.server.address().port + '/wrong-object-for-schema' | ||
| }, (err, response, body) => { | ||
| t.error(err) | ||
| t.strictEqual(response.statusCode, 201) | ||
| t.strictEqual(response.headers['content-length'], '' + body.length) | ||
| t.deepEqual(JSON.parse(body), { hello: null }) | ||
| }) | ||
| }) | ||
| }) |
@@ -35,6 +35,8 @@ <h1 align="center">Fastify</h1> | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| response: { | ||
| 200: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| } | ||
| } | ||
@@ -41,0 +43,0 @@ } |
+8
-6
@@ -22,3 +22,3 @@ <h1 align="center">Fastify</h1> | ||
| * `params`: validates the params. | ||
| * `out`: filter and generate a schema for the response, setting a | ||
| * `response`: filter and generate a schema for the response, setting a | ||
| schema allows us to have 10-20% more throughput. | ||
@@ -47,7 +47,9 @@ * `handler(request, reply)`: the function that will handle this request. | ||
| }, | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| 200: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -54,0 +56,0 @@ } |
+12
-8
@@ -19,6 +19,8 @@ <h1 align="center">Fastify</h1> | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| response: { | ||
| 200: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| } | ||
| } | ||
@@ -112,6 +114,8 @@ } | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| response: { | ||
| 200: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| } | ||
| } | ||
@@ -118,0 +122,0 @@ } |
@@ -50,7 +50,9 @@ <h1 align="center">Fastify</h1> | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| value: { type: 'string' }, | ||
| otherValue: { type: 'boolean' } | ||
| response: { | ||
| 200: { | ||
| type: 'object', | ||
| properties: { | ||
| value: { type: 'string' }, | ||
| otherValue: { type: 'boolean' } | ||
| } | ||
| } | ||
@@ -60,2 +62,23 @@ } | ||
| ``` | ||
| As you can see the response schema is based on the status code, if you want to use the same schema for multiple status codes you can use `'2xx'`, for example: | ||
| ```js | ||
| const schema = { | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| value: { type: 'string' }, | ||
| otherValue: { type: 'boolean' } | ||
| } | ||
| }, | ||
| 201: { | ||
| type: 'object', | ||
| properties: { | ||
| value: { type: 'string' } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| *If you need a custom serializer in a very specific part of your code, you can always set one with `reply.serializer(...)`.* | ||
@@ -62,0 +85,0 @@ |
@@ -6,7 +6,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| 200: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -13,0 +15,0 @@ } |
@@ -7,7 +7,9 @@ 'use strict' | ||
| schema: { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -14,0 +16,0 @@ } |
@@ -12,7 +12,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -19,0 +21,0 @@ } |
@@ -14,7 +14,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -21,0 +23,0 @@ } |
@@ -5,7 +5,9 @@ const fastify = require('../fastify')() | ||
| schema: { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -12,0 +14,0 @@ } |
+1
-1
@@ -89,3 +89,3 @@ /* eslint-disable no-useless-return */ | ||
| // Here we are assuming that the custom serializer is a json serializer | ||
| const str = this._serializer ? this._serializer(payload) : serialize(this.handle, payload) | ||
| const str = this._serializer ? this._serializer(payload) : serialize(this.handle, payload, this.res.statusCode) | ||
| if (!this.res.getHeader('Content-Length')) { | ||
@@ -92,0 +92,0 @@ this.res.setHeader('Content-Length', Buffer.byteLength(str)) |
+29
-9
@@ -10,4 +10,4 @@ 'use strict' | ||
| const querystringSchema = Symbol('querystring-schema') | ||
| const outputSchema = Symbol('output-schema') | ||
| const paramsSchema = Symbol('params-schema') | ||
| const responseSchema = Symbol('response-schema') | ||
@@ -17,12 +17,21 @@ const schemas = require('./schemas.json') | ||
| function getValidatorForStatusCodeSchema (statusCodeDefinition) { | ||
| return fastJsonStringify(statusCodeDefinition) | ||
| } | ||
| function getResponseSchema (responseSchemaDefinition) { | ||
| var statusCodes = Object.keys(responseSchemaDefinition) | ||
| return statusCodes.reduce(function (r, statusCode) { | ||
| r[statusCode] = getValidatorForStatusCodeSchema(responseSchemaDefinition[statusCode]) | ||
| return r | ||
| }, {}) | ||
| } | ||
| function build (opts) { | ||
| if (!opts.schema) { | ||
| opts[outputSchema] = fastSafeStringify | ||
| return | ||
| } | ||
| if (opts.schema.out) { | ||
| opts[outputSchema] = fastJsonStringify(opts.schema.out) | ||
| } else { | ||
| opts[outputSchema] = fastSafeStringify | ||
| if (opts.schema.response) { | ||
| opts[responseSchema] = getResponseSchema(opts.schema.response) | ||
| } | ||
@@ -66,4 +75,15 @@ | ||
| function serialize (handle, data) { | ||
| return handle[outputSchema](data) | ||
| function serialize (handle, data, statusCode) { | ||
| var responseSchemaDef = handle[responseSchema] | ||
| if (!responseSchemaDef) { | ||
| return fastSafeStringify(data) | ||
| } | ||
| if (responseSchemaDef[statusCode]) { | ||
| return responseSchemaDef[statusCode](data) | ||
| } | ||
| var fallbackStatusCode = (statusCode + '')[0] + 'xx' | ||
| if (responseSchemaDef[fallbackStatusCode]) { | ||
| return responseSchemaDef[fallbackStatusCode](data) | ||
| } | ||
| return fastSafeStringify(data) | ||
| } | ||
@@ -84,2 +104,2 @@ | ||
| module.exports = { build, validate, serialize, isValidLogger } | ||
| module.exports.symbols = { bodySchema, querystringSchema, outputSchema, paramsSchema } | ||
| module.exports.symbols = { bodySchema, querystringSchema, responseSchema, paramsSchema } |
+1
-1
| { | ||
| "name": "fastify", | ||
| "version": "0.20.1", | ||
| "version": "0.21.0", | ||
| "description": "Fast and low overhead web framework, for Node.js", | ||
@@ -5,0 +5,0 @@ "main": "fastify.js", |
@@ -9,7 +9,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -16,0 +18,0 @@ } |
@@ -8,7 +8,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -15,0 +17,0 @@ } |
@@ -9,7 +9,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -16,0 +18,0 @@ } |
@@ -9,7 +9,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -16,0 +18,0 @@ } |
+14
-10
@@ -10,7 +10,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -22,7 +24,9 @@ } | ||
| const numberSchema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'number' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'number' | ||
| } | ||
| } | ||
@@ -29,0 +33,0 @@ } |
@@ -9,4 +9,6 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'null' | ||
| response: { | ||
| '2xx': { | ||
| type: 'null' | ||
| } | ||
| } | ||
@@ -13,0 +15,0 @@ } |
+7
-5
@@ -12,7 +12,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -19,0 +21,0 @@ } |
@@ -11,3 +11,3 @@ 'use strict' | ||
| t.plan(4) | ||
| t.is(typeof symbols.outputSchema, 'symbol') | ||
| t.is(typeof symbols.responseSchema, 'symbol') | ||
| t.is(typeof symbols.bodySchema, 'symbol') | ||
@@ -22,3 +22,3 @@ t.is(typeof symbols.querystringSchema, 'symbol') | ||
| validation.build(opts) | ||
| t.is(typeof opts[symbols.outputSchema], 'function') | ||
| t.is(typeof opts[symbols.responseSchema], 'undefined') | ||
| }) | ||
@@ -30,13 +30,21 @@ | ||
| validation.build(opts) | ||
| t.is(typeof opts[symbols.outputSchema], 'function') | ||
| t.is(typeof opts[symbols.responseSchema], 'undefined') | ||
| }) | ||
| test('build schema - output schema', t => { | ||
| t.plan(1) | ||
| t.plan(2) | ||
| const opts = { | ||
| schema: { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'string' } | ||
| } | ||
| }, | ||
| 201: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { type: 'number' } | ||
| } | ||
| } | ||
@@ -47,3 +55,4 @@ } | ||
| validation.build(opts) | ||
| t.is(typeof opts[symbols.outputSchema], 'function') | ||
| t.is(typeof opts[symbols.responseSchema]['2xx'], 'function') | ||
| t.is(typeof opts[symbols.responseSchema]['201'], 'function') | ||
| }) | ||
@@ -50,0 +59,0 @@ |
@@ -10,7 +10,9 @@ 'use strict' | ||
| const schema = { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -17,0 +19,0 @@ } |
@@ -15,7 +15,9 @@ 'use strict' | ||
| schema: { | ||
| out: { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| response: { | ||
| '2xx': { | ||
| type: 'object', | ||
| properties: { | ||
| hello: { | ||
| type: 'string' | ||
| } | ||
| } | ||
@@ -22,0 +24,0 @@ } |
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
181033
2.74%82
1.23%4936
3.52%