@fastify/swagger-ui
Advanced tools
Comparing version 3.1.0 to 4.0.0
@@ -48,1 +48,35 @@ 'use strict' | ||
}) | ||
test.describe('Check redirection and url handling of static assets', () => { | ||
test('Check static/index.html redirects', async ({ page }) => { | ||
const jsonResponsePromise = page.waitForResponse(/json/) | ||
await page.goto(`${URL_DOCUMENTATION}/static/index.html`) | ||
// Check if the page is redirected to /documentation | ||
const url = await page.url() | ||
expect(url).toContain(`${URL_DOCUMENTATION}`) | ||
expect(url).not.toContain('static/index.html') | ||
// Check if the page has requested the json spec, and if so has it succeeded | ||
const jsonResponse = await jsonResponsePromise | ||
expect(jsonResponse.ok()).toBe(true) | ||
}) | ||
test('Check root UI without slash loads json spec', async ({ page }) => { | ||
const jsonResponsePromise = page.waitForResponse(/json/) | ||
await page.goto(`${URL_DOCUMENTATION}`) | ||
// Check if the page has requested the json spec, and if so has it succeeded | ||
const jsonResponse = await jsonResponsePromise | ||
expect(jsonResponse.ok()).toBe(true) | ||
}) | ||
test('Check root UI with trailing slash loads json spec', async ({ page }) => { | ||
const jsonResponsePromise = page.waitForResponse(/json/) | ||
await page.goto(`${URL_DOCUMENTATION}/`) | ||
// Check if the page has requested the json spec, and if so has it succeeded | ||
const jsonResponse = await jsonResponsePromise | ||
expect(jsonResponse.ok()).toBe(true) | ||
}) | ||
}) |
'use strict' | ||
function indexHtml (opts) { | ||
return `<!-- HTML for static distribution bundle build --> | ||
return (url) => `<!-- HTML for static distribution bundle build --> | ||
<!DOCTYPE html> | ||
@@ -10,10 +10,10 @@ <html lang="en"> | ||
<title>${opts.theme?.title || 'Swagger UI'}</title> | ||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" /> | ||
<link rel="stylesheet" type="text/css" href="./index.css" /> | ||
${opts.theme && opts.theme.css ? opts.theme.css.map(css => `<link rel="stylesheet" type="text/css" href="./theme/${css.filename}" />\n`).join('') : ''} | ||
<link rel="stylesheet" type="text/css" href="${url}${opts.staticPrefix}/swagger-ui.css" /> | ||
<link rel="stylesheet" type="text/css" href="${url}${opts.staticPrefix}/index.css" /> | ||
${opts.theme && opts.theme.css ? opts.theme.css.map(css => `<link rel="stylesheet" type="text/css" href="${url}${opts.staticPrefix}/theme/${css.filename}" />\n`).join('') : ''} | ||
${opts.theme && opts.theme.favicon | ||
? opts.theme.favicon.map(favicon => `<link rel="${favicon.rel}" type="${favicon.type}" href="./theme/${favicon.filename}" sizes="${favicon.sizes}" />\n`).join('') | ||
? opts.theme.favicon.map(favicon => `<link rel="${favicon.rel}" type="${favicon.type}" href="${url}${opts.staticPrefix}/theme/${favicon.filename}" sizes="${favicon.sizes}" />\n`).join('') | ||
: ` | ||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" /> | ||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" /> | ||
<link rel="icon" type="image/png" href="${url}${opts.staticPrefix}/favicon-32x32.png" sizes="32x32" /> | ||
<link rel="icon" type="image/png" href="${url}${opts.staticPrefix}/favicon-16x16.png" sizes="16x16" /> | ||
`} | ||
@@ -24,6 +24,6 @@ </head> | ||
<div id="swagger-ui"></div> | ||
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script> | ||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script> | ||
<script src="./swagger-initializer.js" charset="UTF-8"> </script> | ||
${opts.theme && opts.theme.js ? opts.theme.js.map(js => `<script src="./theme/${js.filename}" charset="UTF-8"> </script>\n`).join('') : ''} | ||
<script src="${url}${opts.staticPrefix}/swagger-ui-bundle.js" charset="UTF-8"> </script> | ||
<script src="${url}${opts.staticPrefix}/swagger-ui-standalone-preset.js" charset="UTF-8"> </script> | ||
<script src="${url}${opts.staticPrefix}/swagger-initializer.js" charset="UTF-8"> </script> | ||
${opts.theme && opts.theme.js ? opts.theme.js.map(js => `<script src="${url}${opts.staticPrefix}/theme/${js.filename}" charset="UTF-8"> </script>\n`).join('') : ''} | ||
</body> | ||
@@ -30,0 +30,0 @@ </html> |
@@ -13,15 +13,2 @@ 'use strict' | ||
function getRedirectPathForTheRootRoute (url) { | ||
let redirectPath | ||
if (url.length !== 0 && url[url.length - 1] === '/') { | ||
redirectPath = `.${staticPrefix}/index.html` | ||
} else { | ||
const urlPathParts = url.split('/') | ||
redirectPath = `./${urlPathParts[urlPathParts.length - 1]}${staticPrefix}/index.html` | ||
} | ||
return redirectPath | ||
} | ||
function fastifySwagger (fastify, opts, done) { | ||
@@ -70,12 +57,2 @@ let staticCSP = false | ||
fastify.route({ | ||
url: '/', | ||
method: 'GET', | ||
schema: { hide: true }, | ||
...hooks, | ||
handler: (req, reply) => { | ||
reply.redirect(getRedirectPathForTheRootRoute(req.raw.url)) | ||
} | ||
}) | ||
if (opts.theme) { | ||
@@ -132,6 +109,6 @@ const themePrefix = `${staticPrefix}/theme` | ||
const indexHtmlContent = indexHtml(opts) | ||
const indexHtmlContent = indexHtml({ ...opts, staticPrefix }) | ||
fastify.route({ | ||
url: `${staticPrefix}/index.html`, | ||
url: '/', | ||
method: 'GET', | ||
@@ -143,6 +120,16 @@ schema: { hide: true }, | ||
.header('content-type', 'text/html; charset=utf-8') | ||
.send(indexHtmlContent) | ||
.send(indexHtmlContent(req.url.replace(/\/$/, ''))) // remove trailing slash, as staticPrefix has a leading slash | ||
} | ||
}) | ||
fastify.route({ | ||
url: `${staticPrefix}/index.html`, | ||
method: 'GET', | ||
schema: { hide: true }, | ||
...hooks, | ||
handler: (req, reply) => { | ||
reply.redirect(req.url.replace(/\/static\/index\.html$/, '/')) | ||
} | ||
}) | ||
const swaggerInitializerContent = swaggerInitializer(opts) | ||
@@ -149,0 +136,0 @@ |
@@ -31,4 +31,6 @@ 'use strict' | ||
function resolveUrl(url) { | ||
const anchor = document.createElement('a') | ||
anchor.href = url | ||
var currentHref = window.location.href; | ||
currentHref = currentHref.endsWith('/') ? currentHref : currentHref + '/'; | ||
var anchor = document.createElement('a'); | ||
anchor.href = currentHref + url; | ||
return anchor.href | ||
@@ -51,4 +53,4 @@ } | ||
}, config, { | ||
url: resolveUrl('./json').replace('static/json', 'json'), | ||
oauth2RedirectUrl: resolveUrl('./oauth2-redirect.html') | ||
url: resolveUrl('./json'), | ||
oauth2RedirectUrl: resolveUrl('./static/oauth2-redirect.html') | ||
}); | ||
@@ -55,0 +57,0 @@ |
{ | ||
"name": "@fastify/swagger-ui", | ||
"version": "3.1.0", | ||
"version": "4.0.0", | ||
"description": "Serve Swagger-ui for Fastify", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -34,3 +34,3 @@ 'use strict' | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -61,3 +61,3 @@ t.equal(res.statusCode, 200) | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -98,3 +98,3 @@ t.equal(res.statusCode, 200) | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -138,3 +138,3 @@ t.equal(res.statusCode, 200) | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -179,3 +179,3 @@ t.equal(res.statusCode, 200) | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -220,3 +220,3 @@ t.equal(res.statusCode, 200) | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -223,0 +223,0 @@ t.equal(res.statusCode, 200) |
@@ -103,4 +103,4 @@ 'use strict' | ||
test('/documentation should redirect to ./documentation/static/index.html', async (t) => { | ||
t.plan(3) | ||
test('/documentation should display index html', async (t) => { | ||
t.plan(4) | ||
const fastify = Fastify() | ||
@@ -121,9 +121,10 @@ await fastify.register(fastifySwagger, swaggerOption) | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './documentation/static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers.location, undefined) | ||
t.equal(typeof res.payload, 'string') | ||
t.equal('text/html; charset=utf-8', res.headers['content-type']) | ||
}) | ||
test('/documentation/ should redirect to ./static/index.html', async (t) => { | ||
t.plan(3) | ||
test('/documentation/ should display index html ', async (t) => { | ||
t.plan(4) | ||
const fastify = Fastify() | ||
@@ -144,9 +145,10 @@ await fastify.register(fastifySwagger, swaggerOption) | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers.location, undefined) | ||
t.equal(typeof res.payload, 'string') | ||
t.equal('text/html; charset=utf-8', res.headers['content-type']) | ||
}) | ||
test('/v1/documentation should redirect to ./documentation/static/index.html', async (t) => { | ||
t.plan(3) | ||
test('/v1/documentation should display index html', async (t) => { | ||
t.plan(4) | ||
const fastify = Fastify() | ||
@@ -167,9 +169,10 @@ await fastify.register(fastifySwagger, swaggerOption) | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './documentation/static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers.location, undefined) | ||
t.equal(typeof res.payload, 'string') | ||
t.equal('text/html; charset=utf-8', res.headers['content-type']) | ||
}) | ||
test('/v1/documentation/ should redirect to ./static/index.html', async (t) => { | ||
t.plan(3) | ||
test('/v1/documentation/ should display index html', async (t) => { | ||
t.plan(4) | ||
const fastify = Fastify() | ||
@@ -190,9 +193,10 @@ await fastify.register(fastifySwagger, swaggerOption) | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers.location, undefined) | ||
t.equal(typeof res.payload, 'string') | ||
t.equal('text/html; charset=utf-8', res.headers['content-type']) | ||
}) | ||
test('/v1/foobar should redirect to ./foobar/static/index.html - in plugin', async (t) => { | ||
t.plan(3) | ||
test('/v1/foobar should display index html', async (t) => { | ||
t.plan(4) | ||
const fastify = Fastify() | ||
@@ -202,3 +206,3 @@ | ||
await fastify.register(fastifySwagger, swaggerOption) | ||
await fastify.register(fastifySwaggerUi, { routePrefix: '/foobar' }) | ||
await fastify.register(fastifySwaggerUi, { routePrefix: '/foobar', noRedirect: true }) | ||
@@ -217,9 +221,10 @@ fastify.get('/', () => {}) | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './foobar/static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers.location, undefined) | ||
t.equal(typeof res.payload, 'string') | ||
t.equal('text/html; charset=utf-8', res.headers['content-type']) | ||
}) | ||
test('/v1/foobar/ should redirect to ./static/index.html - in plugin', async (t) => { | ||
t.plan(3) | ||
test('/v1/foobar/ should display index html', async (t) => { | ||
t.plan(4) | ||
const fastify = Fastify() | ||
@@ -243,9 +248,10 @@ | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers.location, undefined) | ||
t.equal(typeof res.payload, 'string') | ||
t.equal('text/html; charset=utf-8', res.headers['content-type']) | ||
}) | ||
test('with routePrefix: \'/\' should redirect to ./static/index.html', async (t) => { | ||
t.plan(3) | ||
test('with routePrefix: \'/\' should display index html', async (t) => { | ||
t.plan(4) | ||
const fastify = Fastify() | ||
@@ -262,5 +268,6 @@ | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers.location, undefined) | ||
t.equal(typeof res.payload, 'string') | ||
t.equal('text/html; charset=utf-8', res.headers['content-type']) | ||
}) | ||
@@ -287,6 +294,6 @@ | ||
method: 'GET', | ||
url: '/documentation/' | ||
url: '/documentation/static/index.html' | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
t.equal(res.headers.location, '/documentation/') | ||
} | ||
@@ -494,16 +501,2 @@ | ||
test('/documentation/ should redirect to ./static/index.html', async (t) => { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
await fastify.register(fastifySwagger, swaggerOption) | ||
await fastify.register(fastifySwaggerUi) | ||
const res = await fastify.inject({ | ||
method: 'GET', | ||
url: '/documentation/' | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
}) | ||
test('/documentation/* should not return module files when baseDir not set', async (t) => { | ||
@@ -536,4 +529,4 @@ t.plan(1) | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers['content-type'], 'text/html; charset=utf-8') | ||
}) | ||
@@ -555,4 +548,21 @@ | ||
}) | ||
t.equal(res.statusCode, 302) | ||
t.equal(res.headers.location, './static/index.html') | ||
t.equal(res.statusCode, 200) | ||
t.equal(res.headers['content-type'], 'text/html; charset=utf-8') | ||
}) | ||
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="/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) | ||
}) |
@@ -23,3 +23,3 @@ 'use strict' | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -67,3 +67,3 @@ | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -124,3 +124,3 @@ | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -162,3 +162,3 @@ | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -206,3 +206,3 @@ | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -243,3 +243,3 @@ | ||
method: 'GET', | ||
url: '/documentation/static/index.html' | ||
url: '/documentation' | ||
}) | ||
@@ -246,0 +246,0 @@ |
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 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 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 not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2566303
8588