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

@fastify/swagger

Package Overview
Dependencies
Maintainers
20
Versions
41
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 8.15.0

20

index.d.ts

@@ -61,2 +61,8 @@ import { FastifyPluginCallback, FastifySchema, RouteOptions, onRequestHookHandler, preHandlerHookHandler } from 'fastify';

type SwaggerDocumentObject = {
swaggerObject: Partial<OpenAPIV2.Document>;
} | {
openapiObject: Partial<OpenAPIV3.Document | OpenAPIV3_1.Document>;
}
type SwaggerTransform = <S extends FastifySchema = FastifySchema>({

@@ -66,4 +72,3 @@ schema,

route,
swaggerObject,
openapiObject,
...documentObject
}: {

@@ -73,6 +78,6 @@ schema: S;

route: RouteOptions;
swaggerObject: Partial<OpenAPIV2.Document>;
openapiObject: Partial<OpenAPIV3.Document | OpenAPIV3_1.Document>;
}) => { schema: FastifySchema; url: string }
} & SwaggerDocumentObject) => { schema: FastifySchema; url: string }
type SwaggerTransformObject = (documentObject: SwaggerDocumentObject) => Partial<OpenAPIV2.Document> | Partial<OpenAPIV3.Document | OpenAPIV3_1.Document>;
type FastifySwagger = FastifyPluginCallback<fastifySwagger.SwaggerOptions>

@@ -153,6 +158,3 @@

*/
transformObject?: ({ swaggerObject, openapiObject }: {
swaggerObject: Partial<OpenAPIV2.Document>;
openapiObject: Partial<OpenAPIV3.Document | OpenAPIV3_1.Document>;
}) => Partial<OpenAPIV2.Document> | Partial<OpenAPIV3.Document | OpenAPIV3_1.Document>;
transformObject?: SwaggerTransformObject;

@@ -159,0 +161,0 @@ refResolver?: {

@@ -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": "8.15.0",
"description": "Serve Swagger/OpenAPI documentation for Fastify, supporting dynamic generation",

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

"fastify": "^4.0.0",
"fluent-json-schema": "^4.0.0",
"fluent-json-schema": "^5.0.0",
"joi": "^17.6.0",

@@ -54,3 +54,3 @@ "joi-to-json": "^4.0.0",

"tap": "^16.2.0",
"tsd": "^0.30.1"
"tsd": "^0.31.0"
},

@@ -57,0 +57,0 @@ "dependencies": {

@@ -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

@@ -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)

@@ -223,4 +223,3 @@ import fastify, { FastifySchema, RouteOptions } from 'fastify';

route,
swaggerObject,
openapiObject,
...documentObject
}) => {

@@ -230,6 +229,3 @@ schema satisfies FastifySchema;

route satisfies RouteOptions;
swaggerObject satisfies Partial<OpenAPIV2.Document>;
openapiObject satisfies Partial<
OpenAPIV3.Document | OpenAPIV3_1.Document
>;
documentObject satisfies { swaggerObject: Partial<OpenAPIV2.Document> } | { openapiObject: Partial<OpenAPIV3.Document | OpenAPIV3_1.Document> };
return { schema, url };

@@ -236,0 +232,0 @@ },

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