diff --git a/lib/index-html.js b/lib/index-html.js index 2e83015..132b29a 100644 --- a/lib/index-html.js +++ b/lib/index-html.js @@ -1,32 +1,35 @@ 'use strict' function indexHtml (opts) { - return (url) => ` - - - - - ${opts.theme?.title || 'Swagger UI'} - - - ${opts.theme && opts.theme.css ? opts.theme.css.map(css => `\n`).join('') : ''} - ${opts.theme && opts.theme.favicon -? opts.theme.favicon.map(favicon => `\n`).join('') -: ` - - - `} - - - -
- - - - ${opts.theme && opts.theme.js ? opts.theme.js.map(js => `\n`).join('') : ''} - - - ` + return (hasTrailingSlash) => { + const prefix = hasTrailingSlash ? `.${opts.staticPrefix}` : `.${opts.prefix}${opts.staticPrefix}` + return ` + + + + + ${opts.theme?.title || 'Swagger UI'} + + + ${opts.theme && opts.theme.css ? opts.theme.css.map(css => `\n`).join('') : ''} + ${opts.theme && opts.theme.favicon + ? opts.theme.favicon.map(favicon => `\n`).join('') + : ` + + + `} + + + +
+ + + + ${opts.theme && opts.theme.js ? opts.theme.js.map(js => `\n`).join('') : ''} + + + ` + } } module.exports = indexHtml diff --git a/lib/routes.js b/lib/routes.js index bb6e4aa..3b206d5 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -112,9 +112,10 @@ function fastifySwagger (fastify, opts, done) { schema: { hide: true }, ...hooks, handler: (req, reply) => { + const hasTrailingSlash = /\/$/.test(req.url) reply .header('content-type', 'text/html; charset=utf-8') - .send(indexHtmlContent(req.url.replace(/\/$/, ''))) // remove trailing slash, as staticPrefix has a leading slash + .send(indexHtmlContent(hasTrailingSlash)) // trailing slash alters the relative urls generated in the html } }) diff --git a/test/route.test.js b/test/route.test.js index 03fd690..5664f36 100644 --- a/test/route.test.js +++ b/test/route.test.js @@ -548,8 +548,59 @@ test('/documentation should display index html with correct asset urls', async ( url: '/documentation' }) - t.equal(res.payload.includes('href="/documentation/static/index.css"'), true) - t.equal(res.payload.includes('src="/documentation/static/theme/theme-js.js"'), true) - t.equal(res.payload.includes('href="/documentation/index.css"'), false) - t.equal(res.payload.includes('src="/documentation/theme/theme-js.js"'), false) + t.equal(res.payload.includes('href="./documentation/static/index.css"'), true) + t.equal(res.payload.includes('src="./documentation/static/theme/theme-js.js"'), true) + t.equal(res.payload.includes('href="./documentation/index.css"'), false) + t.equal(res.payload.includes('src="./documentation/theme/theme-js.js"'), false) +}) + +test('/documentation/ should display index html with correct asset urls', async (t) => { + t.plan(4) + const fastify = Fastify() + await fastify.register(fastifySwagger, swaggerOption) + await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] } }) + + const res = await fastify.inject({ + method: 'GET', + url: '/documentation/' + }) + + t.equal(res.payload.includes('href="./static/index.css"'), true) + t.equal(res.payload.includes('src="./static/theme/theme-js.js"'), true) + t.equal(res.payload.includes('href="./index.css"'), false) + t.equal(res.payload.includes('src="./theme/theme-js.js"'), false) +}) + +test('/docs should display index html with correct asset urls when documentation prefix is set', async (t) => { + t.plan(4) + const fastify = Fastify() + await fastify.register(fastifySwagger, swaggerOption) + await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] }, routePrefix: '/docs' }) + + const res = await fastify.inject({ + method: 'GET', + url: '/docs' + }) + + t.equal(res.payload.includes('href="./docs/static/index.css"'), true) + t.equal(res.payload.includes('src="./docs/static/theme/theme-js.js"'), true) + t.equal(res.payload.includes('href="./docs/index.css"'), false) + t.equal(res.payload.includes('src="./docs/theme/theme-js.js"'), false) +}) + +test('/docs/ should display index html with correct asset urls when documentation prefix is set', async (t) => { + t.plan(4) + const fastify = Fastify() + await fastify.register(fastifySwagger, swaggerOption) + await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] }, routePrefix: '/docs' }) + + const res = await fastify.inject({ + method: 'GET', + url: '/docs/' + }) + + t.equal(res.payload.includes('href="./static/index.css"'), true) + t.equal(res.payload.includes('src="./static/theme/theme-js.js"'), true) + t.equal(res.payload.includes('href="./index.css"'), false) + t.equal(res.payload.includes('src="./theme/theme-js.js"'), false) })