From 958a14b7a256b9927485847710b08b2ef5c38d9b Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 20 Feb 2026 01:14:43 +0200 Subject: [PATCH 1/3] Add -o/--options support to generate-swagger This is useful when using custom AJV options as that can effect JSON schema parsing by AJV --- generate-swagger.js | 11 ++++++++++- help/generate-swagger.txt | 4 ++++ test/generate-swagger.test.js | 22 ++++++++++++++++++++++ test/swaggerplugindir/plugin.js | 14 ++++++++++---- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/generate-swagger.js b/generate-swagger.js index 9ef87eeb..090c8227 100644 --- a/generate-swagger.js +++ b/generate-swagger.js @@ -13,6 +13,9 @@ const { } = require('./util') const fp = require('fastify-plugin') const { loadEnvQuitely } = require('./env-loader') +const deepmerge = require('@fastify/deepmerge')({ + cloneProtoObject (obj) { return obj } +}) let Fastify = null @@ -66,7 +69,13 @@ async function runFastify (opts) { return module.exports.stop(e) } - const fastify = Fastify(opts.options) + let options = {} + + if (opts.options && file.options) { + options = deepmerge(options, file.options) + } + + const fastify = Fastify(options) const pluginOptions = {} if (opts.prefix) { diff --git a/help/generate-swagger.txt b/help/generate-swagger.txt index 06ebf355..c641f846 100644 --- a/help/generate-swagger.txt +++ b/help/generate-swagger.txt @@ -6,3 +6,7 @@ OPTS --yaml=true generate in YAML format + + -o, --options + [env: FASTIFY_OPTIONS] + Use custom options diff --git a/test/generate-swagger.test.js b/test/generate-swagger.test.js index f03ff405..792f19a8 100644 --- a/test/generate-swagger.test.js +++ b/test/generate-swagger.test.js @@ -28,3 +28,25 @@ test('should generate swagger in yaml format', async (t) => { t.assert.ifError(err) } }) + +test('should not use custom options by default', async (t) => { + t.plan(1) + + try { + const swagger = JSON.parse(await generateSwagger([swaggerplugin])) + t.assert.equal(swagger.info.description, 'Body limit: 1048576') + } catch (err) { + t.assert.ifError(err) + } +}) + +test('should use custom options', async (t) => { + t.plan(1) + + try { + const swagger = JSON.parse(await generateSwagger(['-o', swaggerplugin])) + t.assert.equal(swagger.info.description, 'Body limit: 2097152') + } catch (err) { + t.assert.ifError(err) + } +}) diff --git a/test/swaggerplugindir/plugin.js b/test/swaggerplugindir/plugin.js index fee6af1e..ac7278a3 100644 --- a/test/swaggerplugindir/plugin.js +++ b/test/swaggerplugindir/plugin.js @@ -8,10 +8,11 @@ module.exports = fp(function (fastify, opts, next) { return `\ openapi: 3.0.3 info: -version: 8.1.0 -title: "@fastify/swagger" + version: 8.1.0 + title: "@fastify/swagger" + description: "Body limit: ${fastify.initialConfig.bodyLimit}" components: -schemas: {} + schemas: {} paths: "/": get: @@ -29,7 +30,8 @@ paths: openapi: '3.0.3', info: { version: '8.1.0', - title: '@fastify/swagger' + title: '@fastify/swagger', + description: `Body limit: ${fastify.initialConfig.bodyLimit}` }, components: { schemas: {} @@ -59,3 +61,7 @@ paths: }) next() }) + +module.exports.options = { + bodyLimit: 2097152 +} From 3cb0835779d52d008184813eec98e35b1d6e37fc Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Mon, 2 Mar 2026 10:50:02 +0200 Subject: [PATCH 2/3] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e857cf7f..0d14dff9 100644 --- a/README.md +++ b/README.md @@ -318,10 +318,14 @@ Finally, there will be a new `README.md` file, which provides internal informati ### generate-swagger -if your project uses `@fastify/swagger`, `fastify-cli` can generate and write out the resulting Swagger/OpenAPI schema for you. +If your project uses `@fastify/swagger`, `fastify-cli` can generate and write out the resulting Swagger/OpenAPI schema for you. `fastify generate-swagger app.js` +To generate in YAML format add `--yaml=true`, to use the custom options from the main plugin file add `-o/--options`. + +The schema is written to stdout. + ### linting `fastify-cli` is unopinionated on the choice of linter. We recommend you add a linter, like so: From 45256b67fc5a3fb4032a4484de1c7b554e2a1218 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Mon, 2 Mar 2026 16:01:05 +0200 Subject: [PATCH 3/3] Add support for custom decorator and async decorator to generate-swagger --- README.md | 4 +++- generate-swagger.js | 5 ++-- help/generate-swagger.txt | 3 +++ test/generate-swagger.test.js | 11 +++++++++ test/swaggerplugindir/plugin.js | 42 +++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d14dff9..5cbb18f3 100644 --- a/README.md +++ b/README.md @@ -322,7 +322,9 @@ If your project uses `@fastify/swagger`, `fastify-cli` can generate and write ou `fastify generate-swagger app.js` -To generate in YAML format add `--yaml=true`, to use the custom options from the main plugin file add `-o/--options`. +To generate in YAML format add `--yaml=true`, to use the custom options from the +main plugin file add `-o/--options`. To use a custom decorator (The +`@fastify/swagger` `decorator` option), use `--decorator`. The schema is written to stdout. diff --git a/generate-swagger.js b/generate-swagger.js index 090c8227..41149c88 100644 --- a/generate-swagger.js +++ b/generate-swagger.js @@ -48,10 +48,11 @@ async function generateSwagger (args) { process.exit(1) } + const decorator = extraOpts.decorator || 'swagger' if (extraOpts.yaml) { - return fastify.swagger({ yaml: true }) + return await fastify[decorator]({ yaml: true }) } else { - return JSON.stringify(fastify.swagger(), undefined, 2) + return JSON.stringify(await fastify[decorator](), undefined, 2) } } finally { fastify.close() diff --git a/help/generate-swagger.txt b/help/generate-swagger.txt index c641f846..fb97dea5 100644 --- a/help/generate-swagger.txt +++ b/help/generate-swagger.txt @@ -7,6 +7,9 @@ OPTS --yaml=true generate in YAML format + --decorator + Use a custom swagger decorator name + -o, --options [env: FASTIFY_OPTIONS] Use custom options diff --git a/test/generate-swagger.test.js b/test/generate-swagger.test.js index 792f19a8..cc82127f 100644 --- a/test/generate-swagger.test.js +++ b/test/generate-swagger.test.js @@ -50,3 +50,14 @@ test('should use custom options', async (t) => { t.assert.ifError(err) } }) + +test('should use custom decorator', async (t) => { + t.plan(1) + + try { + const swagger = JSON.parse(await generateSwagger(['--decorator', 'alternateSwagger', swaggerplugin])) + t.assert.equal(swagger.info.title, '@fastify/swagger alternate') + } catch (err) { + t.assert.ifError(err) + } +}) diff --git a/test/swaggerplugindir/plugin.js b/test/swaggerplugindir/plugin.js index ac7278a3..08e971af 100644 --- a/test/swaggerplugindir/plugin.js +++ b/test/swaggerplugindir/plugin.js @@ -59,6 +59,48 @@ paths: } } }) + + fastify.decorate('alternateSwagger', function (opts) { + if (opts && opts.yaml) { + return `\ +openapi: 3.0.3 +info: + version: 8.1.0 + title: "@fastify/swagger alternate" +components: + schemas: {} +paths: +"/alternate": + get: + responses: + '200': + description: Default Response +` + } else { + return { + openapi: '3.0.3', + info: { + version: '8.1.0', + title: '@fastify/swagger alternate', + }, + components: { + schemas: {} + }, + paths: { + '/alternate': { + get: { + responses: { + 200: { + description: 'Default Response' + } + } + } + }, + } + } + } + }) + next() })