Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fastify-swagger

Package Overview
Dependencies
Maintainers
7
Versions
100
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fastify-swagger - npm Package Compare versions

Comparing version 3.1.2 to 3.2.0

examples/example-static-specification.js

56

dynamic.js

@@ -49,2 +49,3 @@ 'use strict'

const transform = opts.transform || null
const hiddenTag = opts.hiddenTag || 'X-HIDDEN'

@@ -110,18 +111,16 @@ if (opts.exposeRoute === true) {

if (!ref) {
const externalSchemas = Array.from(sharedSchemasMap.values())
const externalSchemas = Array.from(sharedSchemasMap.values())
ref = Ref({ clone: true, applicationUri: 'todo.com', externalSchemas })
swaggerObject.definitions = {
...swaggerObject.definitions,
...(ref.definitions().definitions)
}
// Swagger doesn't accept $id on /definitions schemas.
// The $ids are needed by Ref() to check the URI so we need
// to remove them at the end of the process
Object.values(swaggerObject.definitions)
.forEach(_ => { delete _.$id })
ref = Ref({ clone: true, applicationUri: 'todo.com', externalSchemas })
swaggerObject.definitions = {
...swaggerObject.definitions,
...(ref.definitions().definitions)
}
// Swagger doesn't accept $id on /definitions schemas.
// The $ids are needed by Ref() to check the URI so we need
// to remove them at the end of the process
Object.values(swaggerObject.definitions)
.forEach(_ => { delete _.$id })
swaggerObject.paths = {}

@@ -133,2 +132,6 @@ for (var route of routes) {

if (route.schema && route.schema.tags && route.schema.tags.includes(hiddenTag)) {
continue
}
const schema = transform

@@ -224,5 +227,4 @@ ? transform(route.schema)

swaggerMethod.responses = genResponse(schema ? schema.response : null)
if (swaggerRoute) {
swaggerObject.paths[url] = swaggerRoute
}
swaggerObject.paths[url] = swaggerRoute
}

@@ -288,13 +290,6 @@

if (resolved.type || resolved.$ref) {
responsesContainer[key] = {
schema: resolved
}
} else {
responsesContainer[key] = resolved
responsesContainer[key] = {
schema: resolved,
description: 'Default Response'
}
if (!responsesContainer[key].description) {
responsesContainer[key].description = 'Default Response'
}
})

@@ -403,8 +398,5 @@

if (jsonSchema.$ref) {
// $ref is in the format: #/definitions/<resolved definition>/<optional fragment>
const localReference = jsonSchema.$ref.split('/')[2]
return localRefResolve(externalSchemas[localReference], externalSchemas)
}
return jsonSchema
// $ref is in the format: #/definitions/<resolved definition>/<optional fragment>
const localReference = jsonSchema.$ref.split('/')[2]
return localRefResolve(externalSchemas[localReference], externalSchemas)
}
import { FastifyPlugin } from 'fastify';
import * as SwaggerSchema from 'swagger-schema-official';
interface FastifySwaggerOptions {
mode?: 'static' | 'dynamic';
/**
* Overwrite the swagger url end-point
* @default /documentation
*/
routePrefix?: string;
/**
* To expose the documentation api
* @default false
*/
exposeRoute?: boolean;
}
interface FastifyDynamicSwaggerOptions extends FastifySwaggerOptions {
mode?: 'dynamic';
swagger?: Partial<SwaggerSchema.Spec>;
/**
* Overwrite the route schema
*/
transform?: Function;
}
interface StaticPathSpec {
path: string;
postProcessor?: (spec: SwaggerSchema.Spec) => SwaggerSchema.Spec;
baseDir: string;
}
interface StaticDocumentSpec {
document: string;
}
interface FastifyStaticSwaggerOptions extends FastifySwaggerOptions {
mode: 'static';
specification: StaticPathSpec | StaticDocumentSpec;
}
declare module 'fastify' {

@@ -61,6 +23,47 @@ interface FastifyInstance {

type SwaggerOptions = (FastifyStaticSwaggerOptions | FastifyDynamicSwaggerOptions)
declare const fastifySwagger: FastifyPlugin<fastifySwagger.SwaggerOptions>
declare namespace fastifySwagger {
type SwaggerOptions = (FastifyStaticSwaggerOptions | FastifyDynamicSwaggerOptions)
declare const fastifySwagger: FastifyPlugin<SwaggerOptions>
interface FastifySwaggerOptions {
mode?: 'static' | 'dynamic';
/**
* Overwrite the swagger url end-point
* @default /documentation
*/
routePrefix?: string;
/**
* To expose the documentation api
* @default false
*/
exposeRoute?: boolean;
}
interface FastifyDynamicSwaggerOptions extends FastifySwaggerOptions {
mode?: 'dynamic';
swagger?: Partial<SwaggerSchema.Spec>;
hiddenTag?: string;
/**
* Overwrite the route schema
*/
transform?: Function;
}
interface StaticPathSpec {
path: string;
postProcessor?: (spec: SwaggerSchema.Spec) => SwaggerSchema.Spec;
baseDir: string;
}
interface StaticDocumentSpec {
document: string;
}
interface FastifyStaticSwaggerOptions extends FastifySwaggerOptions {
mode: 'static';
specification: StaticPathSpec | StaticDocumentSpec;
}
}
export = fastifySwagger;
export = fastifySwagger;
{
"name": "fastify-swagger",
"version": "3.1.2",
"version": "3.2.0",
"description": "Generate Swagger files automatically for Fastify.",

@@ -8,3 +8,3 @@ "main": "index.js",

"prepare": "node prepare-swagger-ui",
"test": "standard && tap test/*.js && npm run typescript",
"test": "standard && tap --100 test/*.js && npm run typescript",
"prepublishOnly": "npm run prepare",

@@ -42,3 +42,3 @@ "typescript": "tsd"

"swagger-parser": "^10.0.0",
"swagger-ui-dist": "3.28.0",
"swagger-ui-dist": "3.31.1",
"tap": "^14.10.7",

@@ -45,0 +45,0 @@ "tsd": "^0.13.1"

@@ -194,2 +194,3 @@ # fastify-swagger

},
hiddenTag: 'X-HIDDEN',
exposeRoute: true,

@@ -277,3 +278,5 @@ routePrefix: '/documentations'

### Hide a route
Sometimes you may need to hide a certain route from the documentation, just pass `{ hide: true }` to the schema object inside the route declaration.
Sometimes you may need to hide a certain route from the documentation, there is 2 alternatives:
- Pass `{ hide: true }` to the schema object inside the route declaration.
- Use the tag declared in `hiddenTag` options property inside the route declaration. Default is `X-HIDDEN`.

@@ -280,0 +283,0 @@ <a name="security"></a>

@@ -71,7 +71,3 @@ 'use strict'

const file = req.params['*']
if (file === '') {
reply.redirect(getRedirectPathForTheRootRoute(req.raw.url))
} else {
reply.sendFile(file)
}
reply.sendFile(file)
}

@@ -78,0 +74,0 @@ })

@@ -107,2 +107,20 @@ 'use strict'

const opts6 = {
schema: {
params: {
type: 'object',
properties: {
id: {
type: 'string',
description: 'user id'
},
key: {
type: 'string',
description: 'just some random key'
}
}
}
}
}
test('/documentation/json route', t => {

@@ -492,2 +510,3 @@ t.plan(2)

fastify.get('/example1', opts4, () => {})
fastify.get('/parameters/:id/:key', opts6, () => {})

@@ -494,0 +513,0 @@ fastify.inject({

'use strict'
const path = require('path')
const t = require('tap')

@@ -7,2 +8,3 @@ const test = t.test

const fastifySwagger = require('../index')
const fastifySwaggerDynamic = require('../dynamic')
const yaml = require('js-yaml')

@@ -47,14 +49,85 @@

test('swagger route returns yaml', t => {
t.plan(4)
test('registering plugin with invalid mode throws an error', t => {
const config = {
mode: 'error'
}
t.plan(1)
const fastify = Fastify()
fastify.register(fastifySwagger, {
fastify.register(fastifySwagger, config)
fastify.ready(err => {
t.equal(err.message, 'unsupported mode, should be one of [\'static\', \'dynamic\']')
})
})
test('unsupported file extension in specification.path throws an error', t => {
const config = {
mode: 'static',
specification: {
path: './examples/example-static-specification.yaml'
path: './examples/example-static-specification.js'
},
exposeRoute: true
}
t.plan(1)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
fastify.ready(err => {
t.equal(err.message, 'specification.path extension name is not supported, should be one from [\'.yaml\', \'.json\']')
})
})
test('non-string specification.baseDir throws an error ', t => {
const config = {
exposeRoute: true,
mode: 'static',
specification: {
path: './examples/example-static-specification.yaml',
baseDir: 1
}
}
t.plan(1)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
fastify.ready(err => {
t.equal(err.message, 'specification.baseDir should be string')
})
})
test('non-object specification.document throws an error', t => {
const config = {
exposeRoute: true,
mode: 'static',
specification: {
document: 'doc'
}
}
t.plan(1)
const fastify = new Fastify()
fastify.register(fastifySwagger, config)
fastify.ready(err => {
t.equal(err.message, 'specification.document is not an object')
})
})
test('swagger route returns yaml', t => {
const config = {
mode: 'static',
specification: {
path: './examples/example-static-specification.yaml'
},
exposeRoute: true
}
t.plan(4)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
// check that yaml is there

@@ -79,15 +152,16 @@ fastify.inject(

})
test('swagger route returns json', t => {
t.plan(2)
const fastify = Fastify()
fastify.register(fastifySwagger, {
const config = {
mode: 'static',
specification: {
type: 'file',
path: './examples/example-static-specification.yaml'
path: './examples/example-static-specification.json'
},
exposeRoute: true
})
}
t.plan(4)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
// check that json is there

@@ -101,8 +175,9 @@ fastify.inject(

t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/json; charset=utf-8')
try {
var payload = JSON.parse(res.payload)
t.matchSnapshot(JSON.stringify(payload, null, 2))
} catch (error) {
t.fail(error)
yaml.safeLoad(res.payload)
t.pass('valid swagger json')
} catch (err) {
t.fail(err)
}

@@ -114,6 +189,3 @@ }

test('postProcessor works, swagger route returns updated yaml', t => {
t.plan(5)
const fastify = Fastify()
fastify.register(fastifySwagger, {
const config = {
mode: 'static',

@@ -128,4 +200,8 @@ specification: {

exposeRoute: true
})
}
t.plan(5)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
// check that yaml is there

@@ -151,6 +227,4 @@ fastify.inject(

})
test('swagger route returns explicitly passed doc', t => {
t.plan(3)
const fastify = Fastify()
const document = {

@@ -163,3 +237,4 @@ info: {

}
fastify.register(fastifySwagger, {
const config = {
mode: 'static',

@@ -170,4 +245,8 @@ specification: {

exposeRoute: true
})
}
t.plan(3)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
// check that json is there

@@ -194,4 +273,2 @@ fastify.inject(

test('/documentation/:file should serve static file from the location of main specification file', t => {
t.plan(7)
const config = {

@@ -204,2 +281,4 @@ exposeRoute: true,

}
t.plan(7)
const fastify = new Fastify()

@@ -241,4 +320,2 @@ fastify.register(fastifySwagger, config)

test('/documentation/non-existing-file calls custom NotFoundHandler', t => {
t.plan(2)
const config = {

@@ -251,2 +328,4 @@ exposeRoute: true,

}
t.plan(2)
const fastify = new Fastify()

@@ -268,4 +347,2 @@ fastify.register(fastifySwagger, config)

test('/documentation/:file should be served from custom location', t => {
t.plan(3)
const config = {

@@ -279,2 +356,4 @@ exposeRoute: true,

}
t.plan(3)
const fastify = new Fastify()

@@ -297,4 +376,2 @@ fastify.register(fastifySwagger, config)

test('/documentation/:file should be served from custom location with trailing slash(es)', t => {
t.plan(3)
const config = {

@@ -308,2 +385,4 @@ exposeRoute: true,

}
t.plan(3)
const fastify = new Fastify()

@@ -324,1 +403,297 @@ fastify.register(fastifySwagger, config)

})
test('/documentation/yaml returns cache.swaggerString on second request in static mode', t => {
const config = {
mode: 'static',
specification: {
path: './examples/example-static-specification.yaml'
},
exposeRoute: true
}
t.plan(8)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
fastify.inject(
{
method: 'GET',
url: '/documentation/yaml'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/x-yaml')
try {
yaml.safeLoad(res.payload)
t.pass('valid swagger yaml')
} catch (err) {
t.fail(err)
}
}
)
fastify.inject(
{
method: 'GET',
url: '/documentation/yaml'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/x-yaml')
yaml.safeLoad(res.payload)
t.pass('valid swagger yaml')
}
)
})
test('/documentation/json returns cache.swaggerObject on second request in static mode', t => {
const config = {
mode: 'static',
specification: {
path: './examples/example-static-specification.json'
},
exposeRoute: true
}
t.plan(8)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
fastify.inject(
{
method: 'GET',
url: '/documentation/json'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/json; charset=utf-8')
t.pass('valid swagger json')
}
)
fastify.inject(
{
method: 'GET',
url: '/documentation/json'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/json; charset=utf-8')
t.pass('valid swagger json')
}
)
})
test('/documentation/yaml returns cache.swaggerString on second request in dynamic mode', t => {
const config = {
specification: {
path: './examples/example-static-specification.yaml'
},
exposeRoute: true
}
t.plan(8)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
fastify.inject(
{
method: 'GET',
url: '/documentation/yaml'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/x-yaml')
try {
yaml.safeLoad(res.payload)
t.pass('valid swagger yaml')
} catch (err) {
t.fail(err)
}
}
)
fastify.inject(
{
method: 'GET',
url: '/documentation/yaml'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/x-yaml')
try {
yaml.safeLoad(res.payload)
t.pass('valid swagger yaml')
} catch (err) {
t.fail(err)
}
}
)
})
test('/documentation/json returns cache.swaggerObject on second request in dynamic mode', t => {
const config = {
specification: {
path: './examples/example-static-specification.json'
},
exposeRoute: true
}
t.plan(8)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
fastify.inject(
{
method: 'GET',
url: '/documentation/json'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/json; charset=utf-8')
t.pass('valid swagger json')
}
)
fastify.inject(
{
method: 'GET',
url: '/documentation/json'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/json; charset=utf-8')
t.pass('valid swagger json')
}
)
})
test('swagger routes are not exposed', t => {
const config = {
mode: 'static',
specification: {
path: './examples/example-static-specification.json'
},
exposeRoute: false
}
t.plan(4)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
// check that yaml is there
fastify.inject(
{
method: 'GET',
url: '/documentation/json'
},
(err, res) => {
t.error(err)
t.is(typeof res.payload, 'string')
t.is(res.headers['content-type'], 'application/json; charset=utf-8')
t.pass('routes are not exposed')
}
)
})
test('inserts default opts in fastifySwagger', t => {
t.plan(1)
const fastify = Fastify()
const next = () => {}
fastify.register(() => (fastifySwagger(fastify, null, next)))
fastify.ready(() => {
t.pass('Inserted default option for fastifySwagger.')
})
})
test('inserts default package name', t => {
const config = {
mode: 'dynamic',
specification: {
path: './examples/example-static-specification.json'
},
exposeRoute: true
}
t.plan(2)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
const originalPathJoin = path.join
const testPackageJSON = path.join(__dirname, '../examples/test-package.json')
path.join = (...args) => {
if (args[1] === 'package.json') {
return testPackageJSON
}
return originalPathJoin(...args)
}
fastify.inject(
{
method: 'GET',
url: '/documentation/json'
},
(err, res) => {
t.error(err)
t.pass('Inserted default package name.')
}
)
})
test('throws an error if cannot parse package\'s JSON', t => {
const config = {
mode: 'dynamic',
specification: {
path: './examples/example-static-specification.json'
},
exposeRoute: true
}
t.plan(2)
const fastify = Fastify()
fastify.register(fastifySwagger, config)
const originalPathJoin = path.join
const testPackageJSON = path.join(__dirname, '')
path.join = (...args) => {
if (args[1] === 'package.json') {
return testPackageJSON
}
return originalPathJoin(...args)
}
fastify.inject(
{
method: 'GET',
url: '/documentation/json'
},
(err, res) => {
t.error(err)
t.equal(err, null)
}
)
})
test('inserts default opts in fastifySwaggerDynamic (dynamic.js)', t => {
t.plan(1)
const fastify = Fastify()
const next = () => {}
fastify.register(() => (fastifySwaggerDynamic(fastify, null, next)))
fastify.ready(() => {
t.pass('Inserted default option for fastifySwagger.')
})
})

@@ -368,3 +368,3 @@ 'use strict'

test('hide support', t => {
test('hide support - property', t => {
t.plan(2)

@@ -403,2 +403,70 @@ const fastify = Fastify()

test('hide support - tags Default', t => {
t.plan(2)
const fastify = Fastify()
fastify.register(fastifySwagger, swaggerInfo)
const opts = {
schema: {
tags: ['X-HIDDEN'],
body: {
type: 'object',
properties: {
hello: { type: 'string' },
obj: {
type: 'object',
properties: {
some: { type: 'string' }
}
}
}
}
}
}
fastify.get('/', opts, () => {})
fastify.ready(err => {
t.error(err)
const swaggerObject = fastify.swagger()
t.notOk(swaggerObject.paths['/'])
})
})
test('hide support - tags Custom', t => {
t.plan(2)
const fastify = Fastify()
fastify.register(fastifySwagger, { ...swaggerInfo, hiddenTag: 'NOP' })
const opts = {
schema: {
tags: ['NOP'],
body: {
type: 'object',
properties: {
hello: { type: 'string' },
obj: {
type: 'object',
properties: {
some: { type: 'string' }
}
}
}
}
}
}
fastify.get('/', opts, () => {})
fastify.ready(err => {
t.error(err)
const swaggerObject = fastify.swagger()
t.notOk(swaggerObject.paths['/'])
})
})
test('deprecated route', t => {

@@ -405,0 +473,0 @@ t.plan(3)

import fastify from 'fastify';
import fastifySwagger = require('../..');
import { SwaggerOptions } from '../..'

@@ -18,2 +19,12 @@ const app = fastify();

const fastifySwaggerOptions: SwaggerOptions = {
mode: 'static',
specification: {
document: 'path'
},
routePrefix: '/documentation',
exposeRoute: true,
}
app.register(fastifySwagger, fastifySwaggerOptions);
app.put('/some-route/:id', {

@@ -20,0 +31,0 @@ schema: {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc