import type { Env, MiddlewareHandler } from 'hono' import { html } from 'hono/html' import type { DistSwaggerUIOptions } from './swagger/renderer' import { renderSwaggerUIOptions } from './swagger/renderer' import type { AssetURLs } from './swagger/resource' import { remoteAssets } from './swagger/resource' type OriginalSwaggerUIOptions = { version?: string /** * manuallySwaggerUIHtml is a string that is used to render SwaggerUI. * If this is set, all other options will be ignored except version. * The string will be inserted into the body of the HTML. * This is useful when you want to fully customize the UI. * * @example * ```ts * const swaggerUI = SwaggerUI({ * manuallySwaggerUIHtml: (asset) => ` *
*
* ${asset.css.map((url) => ``)} * ${asset.js.map((url) => ``)} * *
* `, * }) * ``` */ manuallySwaggerUIHtml?: (asset: AssetURLs) => string title?: string } type SwaggerUIOptions = OriginalSwaggerUIOptions & DistSwaggerUIOptions const SwaggerUI = (options: SwaggerUIOptions): string => { const asset = remoteAssets({ version: options?.version }) delete options.version if (options.manuallySwaggerUIHtml) { return options.manuallySwaggerUIHtml(asset) } const optionsStrings = renderSwaggerUIOptions(options) return `
${asset.css.map((url) => html``)} ${asset.js.map((url) => html``)}
` } const middleware = (options: SwaggerUIOptions): MiddlewareHandler => async (c) => { const title = options?.title ?? 'SwaggerUI' return c.html(/* html */ ` ${title} ${SwaggerUI(options)} `) } export { middleware as swaggerUI, SwaggerUI } export { SwaggerUIOptions }