honojs-middleware/packages/swagger-ui/src/swagger/renderer.ts

151 lines
4.5 KiB
TypeScript
Raw Normal View History

import type { SwaggerConfigs } from 'swagger-ui-dist'
type RequireOne<T, K extends keyof T = keyof T> = K extends keyof T ? PartialRequire<T, K> : never
type PartialRequire<O, K extends keyof O> = {
[P in K]-?: O[P]
} & O
export type DistSwaggerUIOptions = {
configUrl?: SwaggerConfigs['configUrl']
deepLinking?: SwaggerConfigs['deepLinking']
presets?: string[]
plugins?: string[]
spec?: SwaggerConfigs['spec']
layout?: SwaggerConfigs['layout']
docExpansion?: SwaggerConfigs['docExpansion']
maxDisplayedTags?: SwaggerConfigs['maxDisplayedTags']
/**
* accepts function as a string.
*
* @example (a, b) => a.path.localeCompare(b.path)
*/
operationsSorter?: string
/**
* accepts function as a string.
*
* @example (req) => req
*/
requestInterceptor?: string
/**
* accepts function as a string.
*
* @example (res) => res
*/
responseInterceptor?: string
persistAuthorization?: boolean
defaultModelsExpandDepth?: number
defaultModelExpandDepth?: number
defaultModelRendering?: 'example' | 'model' | undefined
displayRequestDuration?: boolean
filter?: boolean | string
showExtensions?: boolean
showCommonExtensions?: boolean
queryConfigEnabled?: boolean
displayOperationId?: boolean
/**
* accepts function as a string.
* swagger-ui accepts alpha in the tagsSorter, but this middleware does not support it.
*
* @example (a, b) => a.name.localeCompare(b.name)
*/
tagsSorter?: string
/**
* accepts function as a string.
* @example () => { console.log('Swagger UI Loaded'); }
*/
onComplete?: string
syntaxHighlight?: boolean | { activated: boolean; theme: string[] }
tryItOutEnabled?: boolean
requestSnippetsEnabled?: boolean
requestSnippets?: object
oauth2RedirectUrl?: string
showMutabledRequest?: boolean
request?: {
curlOptions?: string[]
}
supportedSubmitMethods?: string[]
validatorUrl?: string
withCredentials?: boolean
modelPropertyMacro?: string
parameterMacro?: string
} & RequireOne<{
url?: SwaggerConfigs['url']
urls?: SwaggerConfigs['urls']
}> // least one of `url` or `urls` is required because the output html will be broken if both are missing
const RENDER_TYPE = {
STRING_ARRAY: 'string_array',
STRING: 'string',
JSON_STRING: 'json_string',
RAW: 'raw',
} as const
const RENDER_TYPE_MAP = {
configUrl: RENDER_TYPE.STRING,
deepLinking: RENDER_TYPE.RAW,
presets: RENDER_TYPE.STRING_ARRAY,
plugins: RENDER_TYPE.STRING_ARRAY,
spec: RENDER_TYPE.JSON_STRING,
url: RENDER_TYPE.STRING,
urls: RENDER_TYPE.JSON_STRING,
layout: RENDER_TYPE.STRING,
docExpansion: RENDER_TYPE.STRING,
maxDisplayedTags: RENDER_TYPE.RAW,
operationsSorter: RENDER_TYPE.RAW,
requestInterceptor: RENDER_TYPE.RAW,
responseInterceptor: RENDER_TYPE.RAW,
persistAuthorization: RENDER_TYPE.RAW,
defaultModelsExpandDepth: RENDER_TYPE.RAW,
defaultModelExpandDepth: RENDER_TYPE.RAW,
defaultModelRendering: RENDER_TYPE.STRING,
displayRequestDuration: RENDER_TYPE.RAW,
filter: RENDER_TYPE.RAW,
showExtensions: RENDER_TYPE.RAW,
showCommonExtensions: RENDER_TYPE.RAW,
queryConfigEnabled: RENDER_TYPE.RAW,
displayOperationId: RENDER_TYPE.RAW,
tagsSorter: RENDER_TYPE.RAW,
onComplete: RENDER_TYPE.RAW,
syntaxHighlight: RENDER_TYPE.JSON_STRING,
tryItOutEnabled: RENDER_TYPE.RAW,
requestSnippetsEnabled: RENDER_TYPE.RAW,
requestSnippets: RENDER_TYPE.JSON_STRING,
oauth2RedirectUrl: RENDER_TYPE.STRING,
showMutabledRequest: RENDER_TYPE.RAW,
request: RENDER_TYPE.JSON_STRING,
supportedSubmitMethods: RENDER_TYPE.JSON_STRING,
validatorUrl: RENDER_TYPE.STRING,
withCredentials: RENDER_TYPE.RAW,
modelPropertyMacro: RENDER_TYPE.RAW,
parameterMacro: RENDER_TYPE.RAW,
} as const satisfies Record<
keyof DistSwaggerUIOptions,
(typeof RENDER_TYPE)[keyof typeof RENDER_TYPE]
>
export const renderSwaggerUIOptions = (options: DistSwaggerUIOptions) => {
const optionsStrings = Object.entries(options)
.map(([k, v]) => {
const key = k as keyof typeof RENDER_TYPE_MAP
if (RENDER_TYPE_MAP[key] === RENDER_TYPE.STRING) {
return `${key}: '${v}'`
}
if (RENDER_TYPE_MAP[key] === RENDER_TYPE.STRING_ARRAY) {
if (!Array.isArray(v)) {
return ''
}
return `${key}: [${v.map((ve) => `${ve}`).join(',')}]`
}
if (RENDER_TYPE_MAP[key] === RENDER_TYPE.JSON_STRING) {
return `${key}: ${JSON.stringify(v)}`
}
if (RENDER_TYPE_MAP[key] === RENDER_TYPE.RAW) {
return `${key}: ${v}`
}
return ''
})
.join(',')
return optionsStrings
}