Skip to content

Commit b910bb8

Browse files
committed
improve
1 parent 0e78373 commit b910bb8

File tree

3 files changed

+38
-65
lines changed

3 files changed

+38
-65
lines changed

apps/content/docs/openapi/plugins/openapi-reference.md

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { OpenAPIReferencePlugin } from '@orpc/openapi/plugins'
2020
const handler = new OpenAPIHandler(router, {
2121
plugins: [
2222
new OpenAPIReferencePlugin({
23+
docsProvider: 'swagger', // default: 'scalar'
2324
schemaConverters: [
2425
new ZodToJsonSchemaConverter(),
2526
],
@@ -37,30 +38,3 @@ const handler = new OpenAPIHandler(router, {
3738
::: info
3839
By default, the API reference client is served at the root path (`/`), and the OpenAPI specification is available at `/spec.json`. You can customize these paths by providing the `docsPath` and `specPath` options.
3940
:::
40-
41-
## Using Swagger UI
42-
43-
To use Swagger UI instead of the default Scalar interface:
44-
45-
```ts
46-
import { OpenAPIReferencePlugin } from '@orpc/openapi/plugins'
47-
48-
const plugin = new OpenAPIReferencePlugin({
49-
docsProvider: 'swagger', // Use Swagger UI instead of Scalar
50-
schemaConverters: [
51-
new ZodToJsonSchemaConverter(),
52-
],
53-
specGenerateOptions: {
54-
info: {
55-
title: 'ORPC Playground',
56-
version: '1.0.0',
57-
},
58-
},
59-
})
60-
61-
const handler = new OpenAPIHandler(router, {
62-
plugins: [plugin]
63-
})
64-
```
65-
66-

packages/openapi/src/plugins/openapi-reference.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ describe('openAPIReferencePlugin', () => {
219219
expect(response!.headers.get('content-type')).toBe('text/html')
220220

221221
const html = await response!.text()
222+
expect(html).toContain('swagger-ui-bundle.js')
223+
expect(html).toContain('swagger-ui.css')
224+
expect(html).toContain('SwaggerUIBundle')
222225
expect(html).toContain('__SWAGGER_CONFIG__')
223226
expect(html).toContain('tryItOutEnabled')
224227
})

packages/openapi/src/plugins/openapi-reference.ts

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAP
6464
/**
6565
* URL of the external CSS bundle for the reference UI (used by Swagger UI).
6666
*
67-
* @default 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui.css' (for Swagger UI)
67+
* @default 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui.css' (if swagger)
6868
*/
6969
docsCssUrl?: Value<Promisable<string>, [StandardHandlerInterceptorOptions<T>]>
7070

@@ -79,7 +79,7 @@ export interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAP
7979
config: Record<string, unknown> | undefined,
8080
spec: OpenAPI.Document,
8181
docsProvider: 'scalar' | 'swagger',
82-
cssUrl?: string
82+
cssUrl: string | undefined
8383
) => string
8484
}
8585

@@ -106,14 +106,14 @@ export class OpenAPIReferencePlugin<T extends Context> implements StandardHandle
106106
// Set default script URL based on UI type
107107
this.docsScriptUrl = options.docsScriptUrl ?? (
108108
this.docsProvider === 'swagger'
109-
? 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui-bundle.js'
109+
? 'https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js'
110110
: 'https://cdn.jsdelivr.net/npm/@scalar/api-reference'
111111
)
112112

113113
// Set CSS URL for Swagger UI
114114
this.docsCssUrl = options.docsCssUrl ?? (
115115
this.docsProvider === 'swagger'
116-
? 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui.css'
116+
? 'https://unpkg.com/swagger-ui-dist/swagger-ui.css'
117117
: undefined
118118
)
119119

@@ -124,8 +124,9 @@ export class OpenAPIReferencePlugin<T extends Context> implements StandardHandle
124124
const esc = (s: string) => s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
125125

126126
this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config, spec, docsProvider, cssUrl) => {
127+
let body: string
128+
127129
if (docsProvider === 'swagger') {
128-
// Swagger UI configuration
129130
const swaggerConfig = {
130131
dom_id: '#app',
131132
spec,
@@ -137,60 +138,55 @@ export class OpenAPIReferencePlugin<T extends Context> implements StandardHandle
137138
plugins: [
138139
'SwaggerUIBundle.plugins.DownloadUrl',
139140
],
140-
layout: 'StandaloneLayout',
141141
...config,
142142
}
143143

144-
return `
145-
<!doctype html>
146-
<html>
147-
<head>
148-
<meta charset="utf-8" />
149-
<meta name="viewport" content="width=device-width, initial-scale=1" />
150-
<title>${esc(title)}</title>
151-
${cssUrl ? `<link rel="stylesheet" type="text/css" href="${esc(cssUrl)}" />` : ''}
152-
${head}
153-
</head>
154-
<body>
155-
<div id="app"></div>
144+
body = `
145+
<body>
146+
<div id="app"></div>
156147
157-
<script src="${esc(scriptUrl)}"></script>
148+
<script src="${esc(scriptUrl)}"></script>
158149
159-
<script>
160-
SwaggerUIBundle(${stringifyJSON(swaggerConfig).replace(/"(SwaggerUIBundle\.[^"]+)"/g, '$1')})
161-
</script>
162-
</body>
163-
</html>
150+
<script>
151+
window.onload = () => {
152+
window.ui = SwaggerUIBundle(${stringifyJSON(swaggerConfig).replace(/"(SwaggerUIBundle\.[^"]+)"/g, '$1')})
153+
}
154+
</script>
155+
</body>
164156
`
165157
}
166158
else {
167-
// Scalar configuration (default)
168-
const finalConfig = {
159+
const scalarConfig = {
169160
content: stringifyJSON(spec),
170161
...config,
171162
}
172163

173-
return `
164+
body = `
165+
<body>
166+
<div id="app" data-config="${esc(stringifyJSON(scalarConfig))}"></div>
167+
168+
<script src="${esc(scriptUrl)}"></script>
169+
170+
<script>
171+
Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
172+
</script>
173+
</body>
174+
`
175+
}
176+
177+
return `
174178
<!doctype html>
175179
<html>
176180
<head>
177181
<meta charset="utf-8" />
178182
<meta name="viewport" content="width=device-width, initial-scale=1" />
179183
<title>${esc(title)}</title>
184+
${cssUrl ? `<link rel="stylesheet" type="text/css" href="${esc(cssUrl)}" />` : ''}
180185
${head}
181186
</head>
182-
<body>
183-
<div id="app" data-config="${esc(stringifyJSON(finalConfig))}"></div>
184-
185-
<script src="${esc(scriptUrl)}"></script>
186-
187-
<script>
188-
Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
189-
</script>
190-
</body>
187+
${body}
191188
</html>
192189
`
193-
}
194190
})
195191
}
196192

@@ -238,7 +234,7 @@ export class OpenAPIReferencePlugin<T extends Context> implements StandardHandle
238234
await value(this.docsConfig, options),
239235
await generateSpec(),
240236
this.docsProvider,
241-
this.docsCssUrl ? await value(this.docsCssUrl, options) : undefined,
237+
await value(this.docsCssUrl, options),
242238
)
243239

244240
return {

0 commit comments

Comments
 (0)