2023-11-04 17:18:20 +08:00
|
|
|
import type { SwaggerConfigs } from 'swagger-ui-dist'
|
|
|
|
|
2023-12-29 20:49:35 +08:00
|
|
|
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
|
|
|
|
|
2023-11-04 17:18:20 +08:00
|
|
|
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']
|
2024-07-10 09:20:52 +08:00
|
|
|
/**
|
|
|
|
* accepts function as a string.
|
|
|
|
*
|
|
|
|
* @example (a, b) => a.path.localeCompare(b.path)
|
|
|
|
*/
|
2023-11-04 17:18:20 +08:00
|
|
|
operationsSorter?: string
|
2024-07-10 09:20:52 +08:00
|
|
|
/**
|
|
|
|
* accepts function as a string.
|
|
|
|
*
|
|
|
|
* @example (req) => req
|
|
|
|
*/
|
2023-11-04 17:18:20 +08:00
|
|
|
requestInterceptor?: string
|
2024-07-10 09:20:52 +08:00
|
|
|
/**
|
|
|
|
* accepts function as a string.
|
|
|
|
*
|
|
|
|
* @example (res) => res
|
|
|
|
*/
|
2023-11-04 17:18:20 +08:00
|
|
|
responseInterceptor?: string
|
2023-11-20 13:08:12 +08:00
|
|
|
persistAuthorization?: boolean
|
2024-06-20 05:07:43 +08:00
|
|
|
defaultModelsExpandDepth?: number
|
|
|
|
defaultModelExpandDepth?: number
|
2024-07-10 09:20:52 +08:00
|
|
|
defaultModelRendering?: 'example' | 'model' | undefined
|
2024-06-20 05:07:43 +08:00
|
|
|
displayRequestDuration?: boolean
|
|
|
|
filter?: boolean | string
|
|
|
|
showExtensions?: boolean
|
|
|
|
showCommonExtensions?: boolean
|
2024-07-10 09:20:52 +08:00
|
|
|
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
|
2023-12-29 20:49:35 +08:00
|
|
|
} & 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
|
2023-11-04 17:18:20 +08:00
|
|
|
|
|
|
|
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,
|
2023-11-20 13:08:12 +08:00
|
|
|
persistAuthorization: RENDER_TYPE.RAW,
|
2024-06-20 05:07:43 +08:00
|
|
|
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,
|
2024-07-10 09:20:52 +08:00
|
|
|
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,
|
2023-11-04 17:18:20 +08:00
|
|
|
} 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) {
|
2024-01-29 21:53:43 +08:00
|
|
|
if (!Array.isArray(v)) {
|
|
|
|
return ''
|
|
|
|
}
|
2023-11-04 17:18:20 +08:00
|
|
|
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
|
|
|
|
}
|