Skip to content

Commit b9c9808

Browse files
feat: support OpenAPI 3.1 (#78)
Co-authored-by: Artem Zakharchenko <[email protected]>
1 parent efaeefc commit b9c9808

File tree

3 files changed

+28
-19
lines changed

3 files changed

+28
-19
lines changed

src/open-api/from-open-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const supportedHttpMethods = Object.keys(
2020
* await fromOpenApi(specification)
2121
*/
2222
export async function fromOpenApi(
23-
document: string | OpenAPI.Document | OpenAPIV3.Document | OpenAPIV2.Document,
23+
document: string | OpenAPI.Document | OpenAPIV2.Document,
2424
): Promise<Array<HttpHandler>> {
2525
const parsedDocument =
2626
typeof document === 'string' ? parse(document) : document

src/open-api/utils/get-servers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { OpenAPIV2, OpenAPIV3, OpenAPI } from 'openapi-types'
1+
import { OpenAPIV2, OpenAPI } from 'openapi-types'
22

33
/**
44
* Returns the list of servers specified in the given OpenAPI document.
55
*/
66
export function getServers(
7-
document: OpenAPI.Document | OpenAPIV2.Document | OpenAPIV3.Document,
7+
document: OpenAPI.Document | OpenAPIV2.Document,
88
): Array<string> {
99
if ('basePath' in document && typeof document.basePath !== 'undefined') {
1010
return [document.basePath]

src/open-api/utils/open-api-utils.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { ResponseResolver } from 'msw'
2-
import { OpenAPIV3 } from 'openapi-types'
2+
import { OpenAPI, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'
33
import { seedSchema } from '@yellow-ticket/seed-json-schema'
44
import { toString } from './to-string.js'
55
import { STATUS_CODES } from './status-codes.js'
66

77
export function createResponseResolver(
8-
operation: OpenAPIV3.OperationObject,
8+
operation: OpenAPI.Operation,
99
): ResponseResolver {
1010
return ({ request }) => {
1111
const { responses } = operation
@@ -25,7 +25,7 @@ export function createResponseResolver(
2525
})
2626
}
2727

28-
let responseObject: OpenAPIV3.ResponseObject
28+
let responseObject: OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject
2929

3030
const url = new URL(request.url)
3131
const explicitResponseStatus = url.searchParams.get('response')
@@ -45,8 +45,12 @@ export function createResponseResolver(
4545
responseObject = responseByStatus
4646
} else {
4747
const fallbackResponse =
48-
(responses['200'] as OpenAPIV3.ResponseObject) ||
49-
(responses.default as OpenAPIV3.ResponseObject)
48+
(responses['200'] as
49+
| OpenAPIV3.ResponseObject
50+
| OpenAPIV3_1.ResponseObject) ||
51+
(responses.default as
52+
| OpenAPIV3.ResponseObject
53+
| OpenAPIV3_1.ResponseObject)
5054

5155
if (!fallbackResponse) {
5256
return new Response('Not Implemented', {
@@ -73,7 +77,7 @@ export function createResponseResolver(
7377
*/
7478
export function toHeaders(
7579
request: Request,
76-
responseObject: OpenAPIV3.ResponseObject,
80+
responseObject: OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject,
7781
): Headers | undefined {
7882
const { content } = responseObject
7983
if (!content) {
@@ -123,9 +127,9 @@ export function toHeaders(
123127
const headers = new Headers()
124128

125129
for (const [headerName, headerObject] of Object.entries(responseHeaders)) {
126-
const headerSchema = (headerObject as OpenAPIV3.HeaderObject).schema as
127-
| OpenAPIV3.SchemaObject
128-
| undefined
130+
const headerSchema = (
131+
headerObject as OpenAPIV3.HeaderObject | OpenAPIV3_1.HeaderObject
132+
).schema as OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject | undefined
129133

130134
if (!headerSchema) {
131135
continue
@@ -152,7 +156,7 @@ export function toHeaders(
152156
*/
153157
export function toBody(
154158
request: Request,
155-
responseObject: OpenAPIV3.ResponseObject,
159+
responseObject: OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject,
156160
): RequestInit['body'] {
157161
const { content } = responseObject
158162

@@ -163,7 +167,10 @@ export function toBody(
163167
// See what "Content-Type" the request accepts.
164168
const acceptedContentTypes = getAcceptedContentTypes(request.headers)
165169

166-
let mediaTypeObject: OpenAPIV3.MediaTypeObject | undefined
170+
let mediaTypeObject:
171+
| OpenAPIV3.MediaTypeObject
172+
| OpenAPIV3_1.MediaTypeObject
173+
| undefined
167174
const responseContentTypes = Object.keys(content)
168175

169176
// Lookup the first response content type that satisfies
@@ -213,16 +220,17 @@ export function toBody(
213220
if (exampleName) {
214221
const exampleByName = mediaTypeObject.examples[exampleName] as
215222
| OpenAPIV3.ExampleObject
223+
| OpenAPIV3_1.ExampleObject
216224
| undefined
217225
return exampleByName
218226
? exampleByName.value
219227
: `Cannot find example by name "${exampleName}"`
220228
}
221229

222230
// Otherwise, use the first example.
223-
const firstExample = Object.values(
224-
mediaTypeObject.examples,
225-
)[0] as OpenAPIV3.ExampleObject
231+
const firstExample = Object.values(mediaTypeObject.examples)[0] as
232+
| OpenAPIV3.ExampleObject
233+
| OpenAPIV3_1.ExampleObject
226234

227235
if (typeof firstExample.value === 'object') {
228236
return JSON.stringify(firstExample.value)
@@ -236,8 +244,9 @@ export function toBody(
236244
* @note `example` is always nested under `schema`.
237245
* `examples` is a sibling to `schema`.
238246
*/
239-
const schemaExample = (mediaTypeObject.schema as OpenAPIV3.SchemaObject)
240-
?.example
247+
const schemaExample = (
248+
mediaTypeObject.schema as OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject
249+
)?.example
241250

242251
if (schemaExample) {
243252
if (typeof schemaExample === 'object') {

0 commit comments

Comments
 (0)