Skip to content

Commit 7ee81f4

Browse files
authored
fix(api-reference): can not render operation without responses (#6317)
* fix: can not render operation without responses * docs(changeset): fix: can not render operation without responses * refactor: use new workspace types * fix: TS errors * fix: another TS error * fix: does not fallback to example key when no summary is provided * fix: a few tests and the hasMultipleExamples check * fix: doesn’t properly render first example
1 parent 64a1671 commit 7ee81f4

File tree

7 files changed

+129
-84
lines changed

7 files changed

+129
-84
lines changed

.changeset/light-turkeys-rush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@scalar/api-reference': patch
3+
---
4+
5+
fix: can not render operation without responses

packages/api-reference/src/features/example-responses/ExampleResponse.vue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
<script lang="ts" setup>
22
import { ScalarCodeBlock } from '@scalar/components'
33
import { getExampleFromSchema } from '@scalar/oas-utils/spec-getters'
4-
import type { OpenAPI } from '@scalar/openapi-types'
4+
import type { ExampleObject } from '@scalar/workspace-store/schemas/v3.1/strict/example'
5+
import type { MediaTypeObject } from '@scalar/workspace-store/schemas/v3.1/strict/media-header-encoding'
56
67
defineProps<{
7-
response: OpenAPI.ResponseObject
8+
response: MediaTypeObject | undefined
9+
example: ExampleObject
810
}>()
911
</script>
1012
<template>
1113
<!-- Example -->
1214
<ScalarCodeBlock
13-
v-if="response?.example !== undefined"
15+
v-if="example !== undefined"
1416
class="bg-b-2 -outline-offset-2"
15-
:content="response?.example"
17+
:content="example?.value"
1618
lang="json" />
1719

1820
<!-- Schema -->

packages/api-reference/src/features/example-responses/ExampleResponses.test.ts

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ describe('ExampleResponses', () => {
1212
description: 'Successful response',
1313
content: {
1414
'application/json': {
15-
example: { message: 'Success' },
15+
examples: {
16+
example1: { value: { message: 'Success' } },
17+
},
1618
},
1719
},
1820
},
@@ -28,6 +30,7 @@ describe('ExampleResponses', () => {
2830
expect(tabs[0].text()).toContain('200')
2931
expect(codeBlock.length).toBe(1)
3032
expect(wrapper.text()).toContain('Success')
33+
expect(wrapper.text()).not.toContain('value')
3134
expect(examplePicker.exists()).toBe(false)
3235
})
3336

@@ -76,7 +79,9 @@ describe('ExampleResponses', () => {
7679
description: 'XML response',
7780
content: {
7881
'application/xml': {
79-
example: '<user><name>John</name><age>30</age></user>',
82+
examples: {
83+
example1: { value: '<user><name>John</name><age>30</age></user>' },
84+
},
8085
},
8186
},
8287
},
@@ -89,7 +94,7 @@ describe('ExampleResponses', () => {
8994
const examplePicker = wrapper.findComponent({ name: 'ExamplePicker' })
9095

9196
expect(tabs.length).toBe(1)
92-
expect(tabs[0].text()).toContain('200')
97+
expect(tabs[0].text()).toContain('Status: 200')
9398
expect(codeBlock.length).toBe(1)
9499
expect(wrapper.text()).toContain('XML response')
95100
expect(wrapper.text()).toContain('<user><name>John</name><age>30</age></user>')
@@ -104,7 +109,9 @@ describe('ExampleResponses', () => {
104109
description: 'Plain text response',
105110
content: {
106111
'text/plain': {
107-
example: 'Hello world',
112+
examples: {
113+
example1: { value: 'Hello world' },
114+
},
108115
},
109116
},
110117
},
@@ -132,7 +139,9 @@ describe('ExampleResponses', () => {
132139
description: 'HTML response',
133140
content: {
134141
'text/html': {
135-
example: '<div>Hello <strong>world</strong></div>',
142+
examples: {
143+
example1: { value: '<div>Hello <strong>world</strong></div>' },
144+
},
136145
},
137146
},
138147
},
@@ -160,23 +169,29 @@ describe('ExampleResponses', () => {
160169
description: 'Success response',
161170
content: {
162171
'application/json': {
163-
example: { status: 'success' },
172+
examples: {
173+
example1: { value: { status: 'success' } },
174+
},
164175
},
165176
},
166177
},
167178
'400': {
168179
description: 'Error response',
169180
content: {
170181
'application/json': {
171-
example: { error: 'Bad request' },
182+
examples: {
183+
example1: { value: { error: 'Bad request' } },
184+
},
172185
},
173186
},
174187
},
175188
'500': {
176189
description: 'Server error',
177190
content: {
178191
'application/json': {
179-
example: { error: 'Internal server error' },
192+
examples: {
193+
example1: { value: { error: 'Internal server error' } },
194+
},
180195
},
181196
},
182197
},
@@ -207,23 +222,29 @@ describe('ExampleResponses', () => {
207222
description: 'Success response',
208223
content: {
209224
'application/json': {
210-
example: { status: 'success' },
225+
examples: {
226+
example1: { value: { status: 'success' } },
227+
},
211228
},
212229
},
213230
},
214231
'default': {
215232
description: 'Default error response',
216233
content: {
217234
'application/json': {
218-
example: { error: 'Unexpected error' },
235+
examples: {
236+
example1: { value: { error: 'Unexpected error' } },
237+
},
219238
},
220239
},
221240
},
222241
'404': {
223242
description: 'Not found error',
224243
content: {
225244
'application/json': {
226-
example: { error: 'Resource not found' },
245+
examples: {
246+
example1: { value: { error: 'Resource not found' } },
247+
},
227248
},
228249
},
229250
},
@@ -254,23 +275,29 @@ describe('ExampleResponses', () => {
254275
description: 'Not found error',
255276
content: {
256277
'application/json': {
257-
example: { error: 'Resource not found' },
278+
examples: {
279+
example1: { value: { error: 'Resource not found' } },
280+
},
258281
},
259282
},
260283
},
261284
'500': {
262285
description: 'Server error',
263286
content: {
264287
'application/json': {
265-
example: { error: 'Internal server error' },
288+
examples: {
289+
example1: { value: { error: 'Internal server error' } },
290+
},
266291
},
267292
},
268293
},
269294
'403': {
270295
description: 'Forbidden error',
271296
content: {
272297
'application/json': {
273-
example: { error: 'Access denied' },
298+
examples: {
299+
example1: { value: { error: 'Access denied' } },
300+
},
274301
},
275302
},
276303
},
@@ -301,15 +328,17 @@ describe('ExampleResponses', () => {
301328
description: 'OK',
302329
content: {
303330
'application/json': {
304-
example: { foo: 'bar' },
331+
examples: {
332+
example1: { value: { foo: 'bar' } },
333+
},
305334
},
306335
},
307336
},
308337
},
309338
},
310339
})
311340

312-
const copyButton = wrapper.find('.code-copy')
341+
const copyButton = wrapper.find('.copy-button')
313342
expect(copyButton.exists()).toBe(true)
314343

315344
await copyButton.trigger('click')
@@ -377,7 +406,9 @@ describe('ExampleResponses', () => {
377406
description: 'OK',
378407
content: {
379408
'*/*': {
380-
example: { message: 'Wildcard mimetype' },
409+
examples: {
410+
example1: { value: { message: 'Wildcard mimetype' } },
411+
},
381412
},
382413
},
383414
},

0 commit comments

Comments
 (0)