{"version":3,"file":"index.mjs","names":[],"sources":["../src/swagger/renderer.ts","../src/swagger/resource.ts","../src/index.ts"],"sourcesContent":["import type { SwaggerConfigs } from 'swagger-ui-dist'\n\ntype RequireOne<T, K extends keyof T = keyof T> = K extends keyof T ? PartialRequire<T, K> : never\ntype PartialRequire<O, K extends keyof O> = {\n  [P in K]-?: O[P]\n} & O\n\nexport type DistSwaggerUIOptions = {\n  configUrl?: SwaggerConfigs['configUrl']\n  deepLinking?: SwaggerConfigs['deepLinking']\n  presets?: string[]\n  plugins?: string[]\n  spec?: SwaggerConfigs['spec']\n  layout?: SwaggerConfigs['layout']\n  docExpansion?: SwaggerConfigs['docExpansion']\n  maxDisplayedTags?: SwaggerConfigs['maxDisplayedTags']\n  /**\n   * accepts function as a string.\n   *\n   * @example (a, b) => a.path.localeCompare(b.path)\n   */\n  operationsSorter?: string\n  /**\n   * accepts function as a string.\n   *\n   * @example (req) => req\n   */\n  requestInterceptor?: string\n  /**\n   * accepts function as a string.\n   *\n   * @example (res) => res\n   */\n  responseInterceptor?: string\n  persistAuthorization?: boolean\n  defaultModelsExpandDepth?: number\n  defaultModelExpandDepth?: number\n  defaultModelRendering?: 'example' | 'model' | undefined\n  displayRequestDuration?: boolean\n  filter?: boolean | string\n  showExtensions?: boolean\n  showCommonExtensions?: boolean\n  queryConfigEnabled?: boolean\n  displayOperationId?: boolean\n  /**\n   * accepts function as a string.\n   * swagger-ui accepts alpha in the tagsSorter, but this middleware does not support it.\n   *\n   * @example (a, b) => a.name.localeCompare(b.name)\n   */\n  tagsSorter?: string\n  /**\n   * accepts function as a string.\n   * @example () => { console.log('Swagger UI Loaded'); }\n   */\n  onComplete?: string\n  syntaxHighlight?: boolean | { activated: boolean; theme: string[] }\n  tryItOutEnabled?: boolean\n  requestSnippetsEnabled?: boolean\n  requestSnippets?: object\n  oauth2RedirectUrl?: string\n  showMutabledRequest?: boolean\n  request?: {\n    curlOptions?: string[]\n  }\n  supportedSubmitMethods?: string[]\n  validatorUrl?: string\n  withCredentials?: boolean\n  modelPropertyMacro?: string\n  parameterMacro?: string\n} & RequireOne<{\n  url?: SwaggerConfigs['url']\n  urls?: SwaggerConfigs['urls']\n}> // least one of `url` or `urls` is required because the output html will be broken if both are missing\n\nconst RENDER_TYPE = {\n  STRING_ARRAY: 'string_array',\n  STRING: 'string',\n  JSON_STRING: 'json_string',\n  RAW: 'raw',\n} as const\n\nconst RENDER_TYPE_MAP = {\n  configUrl: RENDER_TYPE.STRING,\n  deepLinking: RENDER_TYPE.RAW,\n  presets: RENDER_TYPE.STRING_ARRAY,\n  plugins: RENDER_TYPE.STRING_ARRAY,\n  spec: RENDER_TYPE.JSON_STRING,\n  url: RENDER_TYPE.STRING,\n  urls: RENDER_TYPE.JSON_STRING,\n  layout: RENDER_TYPE.STRING,\n  docExpansion: RENDER_TYPE.STRING,\n  maxDisplayedTags: RENDER_TYPE.RAW,\n  operationsSorter: RENDER_TYPE.RAW,\n  requestInterceptor: RENDER_TYPE.RAW,\n  responseInterceptor: RENDER_TYPE.RAW,\n  persistAuthorization: RENDER_TYPE.RAW,\n  defaultModelsExpandDepth: RENDER_TYPE.RAW,\n  defaultModelExpandDepth: RENDER_TYPE.RAW,\n  defaultModelRendering: RENDER_TYPE.STRING,\n  displayRequestDuration: RENDER_TYPE.RAW,\n  filter: RENDER_TYPE.RAW,\n  showExtensions: RENDER_TYPE.RAW,\n  showCommonExtensions: RENDER_TYPE.RAW,\n  queryConfigEnabled: RENDER_TYPE.RAW,\n  displayOperationId: RENDER_TYPE.RAW,\n  tagsSorter: RENDER_TYPE.RAW,\n  onComplete: RENDER_TYPE.RAW,\n  syntaxHighlight: RENDER_TYPE.JSON_STRING,\n  tryItOutEnabled: RENDER_TYPE.RAW,\n  requestSnippetsEnabled: RENDER_TYPE.RAW,\n  requestSnippets: RENDER_TYPE.JSON_STRING,\n  oauth2RedirectUrl: RENDER_TYPE.STRING,\n  showMutabledRequest: RENDER_TYPE.RAW,\n  request: RENDER_TYPE.JSON_STRING,\n  supportedSubmitMethods: RENDER_TYPE.JSON_STRING,\n  validatorUrl: RENDER_TYPE.STRING,\n  withCredentials: RENDER_TYPE.RAW,\n  modelPropertyMacro: RENDER_TYPE.RAW,\n  parameterMacro: RENDER_TYPE.RAW,\n} as const satisfies Record<\n  keyof DistSwaggerUIOptions,\n  (typeof RENDER_TYPE)[keyof typeof RENDER_TYPE]\n>\n\n// the output is embedded in an inline <script>, so also escape what could close it or break the literal\nconst toScriptLiteral = (value: unknown): string =>\n  JSON.stringify(value)\n    .replace(/</g, '\\\\u003c')\n    .replace(/>/g, '\\\\u003e')\n    .replace(/\\u2028/g, '\\\\u2028')\n    .replace(/\\u2029/g, '\\\\u2029')\n\nexport const renderSwaggerUIOptions = (options: DistSwaggerUIOptions): string => {\n  const optionsStrings = Object.entries(options)\n    .map(([k, v]) => {\n      const key = k as keyof typeof RENDER_TYPE_MAP\n\n      if (!RENDER_TYPE_MAP[key] || v === undefined) {\n        return ''\n      }\n\n      switch (RENDER_TYPE_MAP[key]) {\n        case RENDER_TYPE.STRING:\n          return `${key}: ${toScriptLiteral(String(v))}`\n        case RENDER_TYPE.STRING_ARRAY:\n          if (!Array.isArray(v)) {\n            return ''\n          }\n          return `${key}: [${v.map((ve) => `${ve}`).join(',')}]`\n        case RENDER_TYPE.JSON_STRING:\n          return `${key}: ${toScriptLiteral(v)}`\n        case RENDER_TYPE.RAW:\n          return `${key}: ${v}`\n        default:\n          return ''\n      }\n    })\n    .filter((item) => item !== '')\n    .join(',')\n\n  return optionsStrings\n}\n","export interface AssetURLs {\n  css: string[]\n  js: string[]\n}\n\nconst DEFAULT_CDN_BASE = 'https://cdn.jsdelivr.net/npm'\n\ntype ResourceConfig = {\n  /** CDN base URL, e.g. https://unpkg.com for internal network mirror */\n  baseUrl?: string\n  version?: string\n}\n\nexport const remoteAssets = ({\n  baseUrl = DEFAULT_CDN_BASE,\n  version,\n}: ResourceConfig): AssetURLs => {\n  const url = `${baseUrl.replace(/\\/$/, '')}/swagger-ui-dist${\n    version !== undefined ? `@${version}` : ''\n  }`\n\n  return {\n    css: [`${url}/swagger-ui.css`],\n    js: [`${url}/swagger-ui-bundle.js`],\n  }\n}\n","import type { Env, MiddlewareHandler } from 'hono'\nimport { html, raw } from 'hono/html'\nimport type { DistSwaggerUIOptions } from './swagger/renderer'\nimport { renderSwaggerUIOptions } from './swagger/renderer'\nimport type { AssetURLs } from './swagger/resource'\nimport { remoteAssets } from './swagger/resource'\n\ntype OriginalSwaggerUIOptions = {\n  /** CDN base URL, e.g. https://unpkg.com for internal network mirror */\n  baseUrl?: string\n  version?: string\n  /**\n   * manuallySwaggerUIHtml is a string that is used to render SwaggerUI.\n   * If this is set, all other options will be ignored except version.\n   * The string will be inserted into the body of the HTML.\n   * This is useful when you want to fully customize the UI.\n   *\n   * @example\n   * ```ts\n   * const swaggerUI = SwaggerUI({\n   *   manuallySwaggerUIHtml: (asset) => `\n   *   <div>\n   *     <div id=\"swagger-ui\"></div>\n   *     ${asset.css.map((url) => `<link rel=\"stylesheet\" href=\"${url}\" />`)}\n   *     ${asset.js.map((url) => `<script src=\"${url}\" crossorigin=\"anonymous\"></script>`)}\n   *     <script>\n   *       window.onload = () => {\n   *         window.ui = SwaggerUIBundle({\n   *           dom_id: '#swagger-ui',\n   *           url: 'https://petstore.swagger.io/v2/swagger.json',\n   *         })\n   *       }\n   *     </script>\n   *   </div>\n   *   `,\n   * })\n   * ```\n   */\n  manuallySwaggerUIHtml?: (asset: AssetURLs) => string\n  title?: string\n}\n\ntype SwaggerUIOptions = OriginalSwaggerUIOptions & DistSwaggerUIOptions\n\nconst SwaggerUI = ({ baseUrl, version, ...options }: SwaggerUIOptions): string => {\n  const asset = remoteAssets({\n    baseUrl: baseUrl,\n    version: version,\n  })\n\n  if (options.manuallySwaggerUIHtml) {\n    return options.manuallySwaggerUIHtml(asset)\n  }\n\n  const optionsStrings = renderSwaggerUIOptions(options)\n\n  return `\n    <div>\n      <div id=\"swagger-ui\"></div>\n      ${asset.css.map((url) => html`<link rel=\"stylesheet\" href=\"${url}\" />`)}\n      ${asset.js.map((url) => html`<script src=\"${url}\" crossorigin=\"anonymous\"></script>`)}\n      <script>\n        window.onload = () => {\n          window.ui = SwaggerUIBundle({\n            dom_id: '#swagger-ui',${optionsStrings},\n          })\n        }\n      </script>\n    </div>\n  `\n}\n\nconst middleware =\n  <E extends Env>(options: SwaggerUIOptions): MiddlewareHandler<E> =>\n  async (c) => {\n    const title = options?.title ?? 'SwaggerUI'\n    return c.html(html`\n      <!doctype html>\n      <html lang=\"en\">\n        <head>\n          <meta charset=\"utf-8\" />\n          <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n          <meta name=\"description\" content=\"SwaggerUI\" />\n          <title>${title}</title>\n        </head>\n        <body>\n          ${raw(SwaggerUI(options))}\n        </body>\n      </html>\n    `)\n  }\n\nexport { middleware as swaggerUI, SwaggerUI }\nexport type { SwaggerUIOptions }\n"],"mappings":"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"}