Socket
Socket
Sign inDemoInstall

@fastify/swagger

Package Overview
Dependencies
Maintainers
20
Versions
38
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 8.14.0 to 9.0.0-pre.fv5.1

2

index.js

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

module.exports = fp(fastifySwagger, {
fastify: '4.x',
fastify: '5.x',
name: '@fastify/swagger'

@@ -31,0 +31,0 @@ })

@@ -118,32 +118,2 @@ 'use strict'

function transformDefsToComponents (jsonSchema) {
if (typeof jsonSchema === 'object' && jsonSchema !== null) {
// Handle patternProperties, that is not part of OpenAPI definitions
if (jsonSchema.patternProperties) {
jsonSchema.additionalProperties = Object.values(jsonSchema.patternProperties)[0]
delete jsonSchema.patternProperties
} else if (jsonSchema.const !== undefined) {
// OAS 3.1 supports `const` but it is not supported by `swagger-ui`
// https://swagger.io/docs/specification/data-models/keywords/
jsonSchema.enum = [jsonSchema.const]
delete jsonSchema.const
}
Object.keys(jsonSchema).forEach(function (key) {
if (key === 'properties') {
Object.keys(jsonSchema[key]).forEach(function (prop) {
jsonSchema[key][prop] = transformDefsToComponents(jsonSchema[key][prop])
})
} else if (key === '$ref') {
jsonSchema[key] = jsonSchema[key].replace('definitions', 'components/schemas')
} else if (key === '$id' || key === '$schema') {
delete jsonSchema[key]
} else {
jsonSchema[key] = transformDefsToComponents(jsonSchema[key])
}
})
}
return jsonSchema
}
function convertExamplesArrayToObject (examples) {

@@ -164,3 +134,3 @@ return examples.reduce((examplesObject, example, index) => {

function plainJsonObjectToOpenapi3 (container, jsonSchema, externalSchemas, securityIgnores = []) {
const obj = transformDefsToComponents(resolveLocalRef(jsonSchema, externalSchemas))
const obj = convertJsonSchemaToOpenapi3(resolveLocalRef(jsonSchema, externalSchemas))
let toOpenapiProp

@@ -297,3 +267,3 @@ switch (container) {

function resolveBodyParams (body, schema, consumes, ref) {
const resolved = transformDefsToComponents(ref.resolve(schema))
const resolved = convertJsonSchemaToOpenapi3(ref.resolve(schema))
if ((Array.isArray(consumes) && consumes.length === 0) || consumes === undefined) {

@@ -319,3 +289,3 @@ consumes = ['application/json']

const schemasPath = '#/components/schemas/'
let resolved = transformDefsToComponents(ref.resolve(schema))
let resolved = convertJsonSchemaToOpenapi3(ref.resolve(schema))

@@ -346,3 +316,3 @@ // if the resolved definition is in global schema

const rawJsonSchema = fastifyResponseJson[statusCode]
const resolved = transformDefsToComponents(ref.resolve(rawJsonSchema))
const resolved = convertJsonSchemaToOpenapi3(ref.resolve(rawJsonSchema))

@@ -473,20 +443,78 @@ /**

function prepareOpenapiSchemas (schemas, ref) {
return Object.entries(schemas)
.reduce((res, [name, schema]) => {
const _ = { ...schema }
const resolved = transformDefsToComponents(ref.resolve(_, { externalSchemas: [schemas] }))
function convertJsonSchemaToOpenapi3 (jsonSchema) {
if (typeof jsonSchema !== 'object' || jsonSchema === null) {
return jsonSchema
}
// 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
// definitions are added by resolve but they are replace by components.schemas
delete resolved.$id
delete resolved.definitions
if (Array.isArray(jsonSchema)) {
return jsonSchema.map(convertJsonSchemaToOpenapi3)
}
res[name] = resolved
return res
}, {})
const openapiSchema = { ...jsonSchema }
for (const key of Object.keys(openapiSchema)) {
const value = openapiSchema[key]
if (key === '$id' || key === '$schema' || key === 'definitions') {
// TODO: this breaks references to the definition properties
delete openapiSchema[key]
continue
}
if (key === '$ref') {
openapiSchema.$ref = value.replace('definitions', 'components/schemas')
continue
}
if (key === 'const') {
// OAS 3.1 supports `const` but it is not supported by `swagger-ui`
// https://swagger.io/docs/specification/data-models/keywords/
// TODO: check if enum property already exists
// TODO: this breaks references to the const property
openapiSchema.enum = [openapiSchema.const]
delete openapiSchema.const
continue
}
if (key === 'patternProperties') {
// TODO: check if additionalProperties property already exists
// TODO: this breaks references to the additionalProperties properties
// TODO: patternProperties actually allowed in the openapi schema, but should
// always start with "x-" prefix
openapiSchema.additionalProperties = Object.values(openapiSchema.patternProperties)[0]
delete openapiSchema.patternProperties
continue
}
if (key === 'properties') {
openapiSchema[key] = {}
for (const propertyName of Object.keys(value)) {
const propertyJsonSchema = value[propertyName]
const propertyOpenapiSchema = convertJsonSchemaToOpenapi3(propertyJsonSchema)
openapiSchema[key][propertyName] = propertyOpenapiSchema
}
continue
}
openapiSchema[key] = convertJsonSchemaToOpenapi3(value)
}
return openapiSchema
}
function prepareOpenapiSchemas (jsonSchemas, ref) {
const openapiSchemas = {}
for (const schemaName of Object.keys(jsonSchemas)) {
const jsonSchema = { ...jsonSchemas[schemaName] }
const resolvedJsonSchema = ref.resolve(jsonSchema, { externalSchemas: [jsonSchemas] })
const openapiSchema = convertJsonSchemaToOpenapi3(resolvedJsonSchema)
resolveSchemaExamplesRecursive(openapiSchema)
openapiSchemas[schemaName] = openapiSchema
}
return openapiSchemas
}
module.exports = {

@@ -493,0 +521,0 @@ prepareDefaultOptions,

@@ -24,3 +24,3 @@ # Migration

| uiConfig | {} | Configuration options for [Swagger UI](https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md). Must be literal values, see [#5710](https://github.com/swagger-api/swagger-ui/issues/5710).|
| uiHooks | {} | Additional hooks for the documentation's routes. You can provide the `onRequest` and `preHandler` hooks with the same [route's options](https://fastify.dev/docs/latest/Routes/#options) interface.|
| uiHooks | {} | Additional hooks for the documentation's routes. You can provide the `onRequest` and `preHandler` hooks with the same [route's options](https://fastify.dev/docs/latest/Reference/Routes/#options) interface.|

@@ -27,0 +27,0 @@ The `baseDir` option is new and is only needed if external spec files should be

{
"name": "@fastify/swagger",
"version": "8.14.0",
"version": "9.0.0-pre.fv5.1",
"description": "Serve Swagger/OpenAPI documentation for Fastify, supporting dynamic generation",

@@ -43,20 +43,20 @@ "main": "index.js",

"@apidevtools/swagger-parser": "^10.1.0",
"@fastify/cookie": "^9.0.4",
"@fastify/pre-commit": "^2.0.2",
"@types/node": "^20.1.0",
"fastify": "^4.0.0",
"fluent-json-schema": "^4.0.0",
"joi": "^17.6.0",
"joi-to-json": "^4.0.0",
"qs": "^6.10.3",
"standard": "^17.0.0",
"tap": "^16.2.0",
"tsd": "^0.30.1"
"@fastify/cookie": "^10.0.0-pre.fv5.1",
"@fastify/pre-commit": "^2.1.0",
"@types/node": "^20.12.8",
"fastify": "^5.0.0-alpha.3",
"fluent-json-schema": "^5.0.0",
"joi": "^17.13.1",
"joi-to-json": "^4.2.1",
"qs": "^6.12.1",
"standard": "^17.1.0",
"tap": "18.7.2",
"tsd": "^0.31.0"
},
"dependencies": {
"fastify-plugin": "^4.0.0",
"fastify-plugin": "^5.0.0-pre.fv5.1",
"json-schema-resolver": "^2.0.0",
"openapi-types": "^12.0.0",
"rfdc": "^1.3.0",
"yaml": "^2.2.2"
"openapi-types": "^12.1.3",
"rfdc": "^1.3.1",
"yaml": "^2.4.2"
},

@@ -63,0 +63,0 @@ "standard": {

@@ -11,3 +11,3 @@ # @fastify/swagger

Following plugins serve swagger/openapi front-ends based on the swagger definitions generated by this plugin:
Following plugins serve Swagger/OpenAPI front-ends based on the swagger definitions generated by this plugin:

@@ -21,2 +21,3 @@ - [@fastify/swagger-ui](https://github.com/fastify/fastify-swagger-ui)

## Install
```

@@ -44,4 +45,5 @@ npm i @fastify/swagger

## Usage
Add it to your project with `register`, pass it some options, call the `swagger` API, and you are done!
Add it to your project with `register`, pass it some options, call the `swagger` API, and you are done! Below an example of how to configure the OpenAPI v3 specification with Fastify Swagger:
```js

@@ -51,3 +53,4 @@ const fastify = require('fastify')()

await fastify.register(require('@fastify/swagger'), {
swagger: {
openapi: {
openapi: '3.0.0',
info: {

@@ -58,10 +61,8 @@ title: 'Test swagger',

},
externalDocs: {
url: 'https://swagger.io',
description: 'Find more info here'
},
host: 'localhost',
schemes: ['http'],
consumes: ['application/json'],
produces: ['application/json'],
servers: [
{
url: 'http://localhost:3000',
description: 'Development server'
}
],
tags: [

@@ -71,20 +72,14 @@ { name: 'user', description: 'User related end-points' },

],
definitions: {
User: {
type: 'object',
required: ['id', 'email'],
properties: {
id: { type: 'string', format: 'uuid' },
firstName: { type: 'string' },
lastName: { type: 'string' },
email: {type: 'string', format: 'email' }
components: {
securitySchemes: {
apiKey: {
type: 'apiKey',
name: 'apiKey',
in: 'header'
}
}
},
securityDefinitions: {
apiKey: {
type: 'apiKey',
name: 'apiKey',
in: 'header'
}
externalDocs: {
url: 'https://swagger.io',
description: 'Find more info here'
}

@@ -99,2 +94,3 @@ }

summary: 'qwerty',
security: [{ apiKey: [] }],
params: {

@@ -136,10 +132,5 @@ type: 'object',

}
},
security: [
{
"apiKey": []
}
]
}
}
}, (req, reply) => {})
}, (req, reply) => { })

@@ -149,2 +140,19 @@ await fastify.ready()

```
<a name="usage.fastify.autoload"></a>
### With `@fastify/autoload`
You need to register `@fastify/swagger` before registering routes.
```js
const fastify = require('fastify')()
const fastify = fastify()
await fastify.register(require('@fastify/swagger'))
fastify.register(require("@fastify/autoload"), {
dir: path.join(__dirname, 'routes')
})
await fastify.ready()
fastify.swagger()
```
<a name="api"></a>

@@ -151,0 +159,0 @@ ## API

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

t.rejects(fastify.register(fastifySwagger, config), new Error('specification.document is not an object'))
t.rejects(async () => await fastify.register(fastifySwagger, config), new Error('specification.document is not an object'))
})

@@ -191,0 +191,0 @@

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

const openapiObject = fastify.swagger()
t.same(openapiObject.components.schemas, openapiOption.openapi.components.schemas)
t.match(openapiObject.components.schemas, openapiOption.openapi.components.schemas)
delete openapiOption.openapi.components.schemas // remove what we just added

@@ -113,0 +113,0 @@ })

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

fastify.register(async (instance) => {
instance.addSchema({ $id: 'Order', type: 'object', properties: { id: { type: 'integer' } } })
instance.addSchema({ $id: 'Order', type: 'object', properties: { id: { type: 'integer', examples: [25] } } })
instance.post('/', { schema: { body: { $ref: 'Order#' }, response: { 200: { $ref: 'Order#' } } } }, () => {})

@@ -32,2 +32,3 @@ })

t.match(Object.keys(openapiObject.components.schemas), ['Order'])
t.equal(openapiObject.components.schemas.Order.properties.id.example, 25)

@@ -72,3 +73,3 @@ await Swagger.validate(openapiObject)

fastify.register(async (instance) => {
instance.addSchema({ $id: 'OrderItem', type: 'object', properties: { id: { type: 'integer' } } })
instance.addSchema({ $id: 'OrderItem', type: 'object', properties: { id: { type: 'integer' } }, examples: [{ id: 1 }] })
instance.addSchema({ $id: 'ProductItem', type: 'object', properties: { id: { type: 'integer' } } })

@@ -90,2 +91,3 @@ instance.addSchema({ $id: 'Order', type: 'object', properties: { products: { type: 'array', items: { $ref: 'OrderItem' } } } })

t.equal(schemas.Order.properties.products.items.$ref, '#/components/schemas/OrderItem')
t.match(schemas.OrderItem.example, { id: 1 })

@@ -100,3 +102,3 @@ await Swagger.validate(openapiObject)

instance.addSchema({ $id: 'schemaA', type: 'object', properties: { id: { type: 'integer' } } })
instance.addSchema({ $id: 'schemaB', type: 'object', properties: { id: { type: 'string' } } })
instance.addSchema({ $id: 'schemaB', type: 'object', properties: { id: { type: 'string', examples: ['ABC'] } } })
instance.addSchema({ $id: 'schemaC', type: 'object', properties: { a: { type: 'array', items: { $ref: 'schemaA' } } } })

@@ -120,2 +122,3 @@ instance.addSchema({ $id: 'schemaD', type: 'object', properties: { b: { $ref: 'schemaB' }, c: { $ref: 'schemaC' } } })

t.equal(schemas.schemaD.properties.c.$ref, '#/components/schemas/schemaC')
t.equal(schemas.schemaB.properties.id.example, 'ABC')

@@ -122,0 +125,0 @@ await Swagger.validate(openapiObject)

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

t.ok(definedPath)
t.same(definedPath.responses[200].content, {
t.match(definedPath.responses[200].content, {
'*/*': {

@@ -238,3 +238,3 @@ schema: {

t.ok(definedPath)
t.same(definedPath.requestBody.content, {
t.match(definedPath.requestBody.content, {
'application/x-www-form-urlencoded': {

@@ -428,3 +428,3 @@ schema: {

t.ok(cookiesPath)
t.same(cookiesPath.parameters, [
t.match(cookiesPath.parameters, [
{

@@ -451,3 +451,3 @@ required: false,

t.ok(querystringPath)
t.same(querystringPath.parameters, [
t.match(querystringPath.parameters, [
{

@@ -454,0 +454,0 @@ required: false,

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

t.same(definedPath.responses['200'].description, 'Description and all status-code based properties are working')
t.strictSame(definedPath.responses['200'].content, {
t.match(definedPath.responses['200'].content, {
'application/json': {

@@ -179,3 +179,3 @@ schema: {

t.same(definedPath.responses['4XX'].description, 'Default Response')
t.strictSame(definedPath.responses['4XX'].content, {
t.match(definedPath.responses['4XX'].content, {
'application/json': {

@@ -190,3 +190,3 @@ schema: {

})
t.strictSame(definedPath.responses[300].content, {
t.match(definedPath.responses[300].content, {
'application/json': {

@@ -492,3 +492,3 @@ schema: {

t.same(definedPath.responses.default, {
t.match(definedPath.responses.default, {
description: 'Default Response',

@@ -571,3 +571,3 @@ content: {

t.same(definedPath.responses[200], {
t.match(definedPath.responses[200], {
description: 'Expected Response',

@@ -630,3 +630,3 @@ content: {

t.same(definedPath.responses[200], {
t.match(definedPath.responses[200], {
description: 'Expected Response',

@@ -687,3 +687,3 @@ content: {

const definedPath = api.paths['/'].post
t.same(definedPath.requestBody, {
t.match(definedPath.requestBody, {
content: {

@@ -750,3 +750,3 @@ 'application/json': {

const definedPath = api.paths['/'].post
t.same(definedPath.requestBody, {
t.match(definedPath.requestBody, {
content: {

@@ -810,3 +810,3 @@ 'application/json': {

const definedPath = api.paths['/'].post
t.same(definedPath.requestBody, {
t.match(definedPath.requestBody, {
content: {

@@ -865,3 +865,3 @@ 'application/json': {

const definedPath = api.paths['/'].post
t.same(definedPath.requestBody, {
t.match(definedPath.requestBody, {
description: 'Body description',

@@ -868,0 +868,0 @@ content: {

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

const swaggerObject = fastify.swagger()
t.same(swaggerObject.definitions, swaggerOption.swagger.definitions)
t.match(swaggerObject.definitions, swaggerOption.swagger.definitions)
delete swaggerOption.swagger.definitions // remove what we just added

@@ -101,0 +101,0 @@ })

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

t.same(definedPath.responses.default, {
t.match(definedPath.responses.default, {
description: 'Default Response',

@@ -425,3 +425,3 @@ schema: {

t.same(definedPath.parameters[0].schema, {
t.match(definedPath.parameters[0].schema, {
type: 'object',

@@ -431,3 +431,3 @@ additionalProperties: { type: 'string' }

t.same(definedPath.responses[200], {
t.match(definedPath.responses[200], {
description: 'Expected Response',

@@ -477,3 +477,3 @@ schema: {

const definedPath = api.paths['/'].post
t.same(definedPath.parameters[0].schema, {
t.match(definedPath.parameters[0].schema, {
type: 'object',

@@ -530,3 +530,3 @@ properties: {

t.same(definedPath.parameters[0].description, 'Body description')
t.same(definedPath.parameters[0].schema, {
t.match(definedPath.parameters[0].schema, {
type: 'object',

@@ -704,3 +704,3 @@ description: 'Body description',

t.strictSame(definedPath.parameters[0].schema, {
t.match(definedPath.parameters[0].schema, {
type: 'object',

@@ -752,3 +752,3 @@ properties: {

t.strictSame(definedPath.parameters[0].schema, {
t.match(definedPath.parameters[0].schema, {
type: 'object',

@@ -755,0 +755,0 @@ properties: {

Sorry, the diff of this file is not supported yet

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