Skip to content

Commit f975322

Browse files
Copilotmrlubos
andcommitted
fix: contentMediaType schema property generates Blob | File for file uploads
Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>
1 parent 4a897c5 commit f975322

5 files changed

Lines changed: 118 additions & 0 deletions

File tree

packages/openapi-ts-tests/main/test/3.1.x.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@ describe(`OpenAPI ${version}`, () => {
193193
}),
194194
description: 'handles binary content',
195195
},
196+
{
197+
config: createConfig({
198+
input: 'content-media-type.yaml',
199+
output: 'content-media-type',
200+
}),
201+
description: 'handles contentMediaType schema property for file uploads',
202+
},
196203
{
197204
config: createConfig({
198205
input: 'content-types.yaml',
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export type { ClientOptions, FileUploadRequest, FileUploadRequestTyped, UploadFileData, UploadFileResponses, UploadFileTypedData, UploadFileTypedResponses } from './types.gen';
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export type ClientOptions = {
4+
baseUrl: `${string}://${string}` | (string & {});
5+
};
6+
7+
export type FileUploadRequest = {
8+
/**
9+
* Binary file content
10+
*/
11+
file: Blob | File;
12+
};
13+
14+
export type FileUploadRequestTyped = {
15+
/**
16+
* Binary file content with explicit string type
17+
*/
18+
file: Blob | File;
19+
};
20+
21+
export type UploadFileData = {
22+
body?: FileUploadRequest;
23+
path?: never;
24+
query?: never;
25+
url: '/upload';
26+
};
27+
28+
export type UploadFileResponses = {
29+
/**
30+
* OK
31+
*/
32+
200: unknown;
33+
};
34+
35+
export type UploadFileTypedData = {
36+
body?: FileUploadRequestTyped;
37+
path?: never;
38+
query?: never;
39+
url: '/upload-typed';
40+
};
41+
42+
export type UploadFileTypedResponses = {
43+
/**
44+
* OK
45+
*/
46+
200: unknown;
47+
};

packages/shared/src/openApi/3.1.x/parser/schema.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Context } from '../../../ir/context';
2+
import { isMediaTypeFileLike } from '../../../ir/mediaType';
23
import type { IR } from '../../../ir/types';
34
import { addItemsToSchema } from '../../../ir/utils';
45
import type {
@@ -231,6 +232,11 @@ const parseSchemaMeta = ({
231232

232233
if (schema.format) {
233234
irSchema.format = schema.format;
235+
} else if (
236+
schema.contentMediaType &&
237+
isMediaTypeFileLike({ mediaType: schema.contentMediaType })
238+
) {
239+
irSchema.format = 'binary';
234240
}
235241

236242
if (schema.maximum !== undefined) {
@@ -1364,6 +1370,15 @@ export const schemaToIrSchema = ({
13641370
});
13651371
}
13661372

1373+
// infer string with binary format based on contentMediaType
1374+
if (schema.contentMediaType && isMediaTypeFileLike({ mediaType: schema.contentMediaType })) {
1375+
return parseType({
1376+
context,
1377+
schema: { ...schema, type: 'string' } as SchemaWithRequired<SchemaObject, 'type'>,
1378+
state,
1379+
});
1380+
}
1381+
13671382
return parseUnknown({ context, schema });
13681383
};
13691384

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
openapi: 3.1.0
2+
info:
3+
title: OpenAPI 3.1.0 contentMediaType example
4+
version: '1'
5+
paths:
6+
/upload:
7+
post:
8+
operationId: uploadFile
9+
requestBody:
10+
content:
11+
multipart/form-data:
12+
schema:
13+
$ref: '#/components/schemas/FileUploadRequest'
14+
responses:
15+
'200':
16+
description: OK
17+
/upload-typed:
18+
post:
19+
operationId: uploadFileTyped
20+
requestBody:
21+
content:
22+
multipart/form-data:
23+
schema:
24+
$ref: '#/components/schemas/FileUploadRequestTyped'
25+
responses:
26+
'200':
27+
description: OK
28+
components:
29+
schemas:
30+
FileUploadRequest:
31+
type: object
32+
required:
33+
- file
34+
properties:
35+
file:
36+
contentMediaType: application/octet-stream
37+
description: Binary file content
38+
FileUploadRequestTyped:
39+
type: object
40+
required:
41+
- file
42+
properties:
43+
file:
44+
type: string
45+
contentMediaType: application/octet-stream
46+
description: Binary file content with explicit string type

0 commit comments

Comments
 (0)