Skip to content

Commit 475a982

Browse files
committed
feat: support form data for request bodies
1 parent 2f02cb5 commit 475a982

File tree

4 files changed

+52
-8
lines changed

4 files changed

+52
-8
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
"[typescriptreact]": {
1616
"editor.defaultFormatter": "esbenp.prettier-vscode"
1717
},
18+
"prettier.enable": true,
1819
}

src/generateHooks.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,51 @@ export const createHook = ({
274274
const generateBodyProps = () => {
275275
if (definitionKey && !hasRequestBodyArrray) {
276276
const scheme = schemasComponents?.schemas?.[definitionKey] as SchemaObject;
277-
const generatedBodyProps = Object.keys(scheme.properties as SchemaObject)
277+
const schemProperties = Object.keys(scheme.properties as SchemaObject);
278+
if (
279+
operation.requestBody &&
280+
'content' in operation.requestBody &&
281+
Object.keys(operation.requestBody.content)[0] === 'multipart/form-data'
282+
) {
283+
let formData = `const body = new FormData()`;
284+
schemProperties.forEach((item) => {
285+
if (scheme.required?.includes(item)) {
286+
formData += `\nbody.append("${item}", props["${item}"]);`;
287+
} else {
288+
formData += `\n if (props["${item}"] != null) {\n body.append("${item}", props["${item}"]);\n}`;
289+
}
290+
});
291+
return formData;
292+
}
293+
294+
const generatedBodyProps = schemProperties
278295
.map((item: string) => `["${item}"]: props["${item}"]`)
279296
.join(',');
280297
return `const body = {${generatedBodyProps}}`;
281298
}
282299

283300
if (operation.requestBody && 'content' in operation.requestBody) {
284301
let generatedBodyProps = [];
285-
for (let contentType of Object.keys(operation.requestBody.content)) {
302+
let bodyData = '';
303+
const contentTypes = Object.keys(operation.requestBody.content);
304+
if (contentTypes.includes('multipart/form-data')) {
305+
bodyData += `const body = new FormData()`;
306+
for (let contentType of contentTypes) {
307+
const schema = operation.requestBody.content[contentType].schema!;
308+
if ('properties' in schema) {
309+
const schemaProperties = Object.keys(schema.properties || []);
310+
for (let item of schemaProperties) {
311+
if (schema.required?.includes(item)) {
312+
bodyData += `\nbody.append("${item}", props["${item}"].toString());`;
313+
} else {
314+
bodyData += `\n if (props["${item}"] != null) {\n body.append("${item}", props["${item}"].toString());\n}`;
315+
}
316+
}
317+
}
318+
}
319+
return bodyData;
320+
}
321+
for (let contentType of contentTypes) {
286322
if (
287323
contentType.startsWith('application/json') ||
288324
contentType.startsWith('application/ld+json') ||
@@ -296,10 +332,8 @@ export const createHook = ({
296332
}
297333
}
298334
}
299-
return `const body = {${generatedBodyProps.map((item) => `${item}: props.${item}`).join(',')}}`;
335+
return `const body = {${generatedBodyProps.map((item) => `${item}: props["${item}"]`).join(',')}}`;
300336
}
301-
302-
return `ERROR`;
303337
};
304338

305339
if (!requestBodyComponent && !paramsInPath.length && !queryParam && !headerParam) {

src/utils.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ export const getScalar = (item: SchemaObject) => {
3535
return getArray(item) + nullable;
3636

3737
case 'string':
38-
return (item.enum ? `"${item.enum.join(`" | "`)}"` : 'string') + nullable;
38+
if (item.format === 'binary') {
39+
return 'string | { name?: string; type?: string; uri: string }' + nullable;
40+
}
41+
if (item.enum) {
42+
return item.enum.join(`" | "`) + nullable;
43+
}
44+
return 'string' + nullable;
3945

4046
case 'object':
4147
return getObject(item) + nullable;
@@ -191,7 +197,8 @@ export const getResReqTypes = (
191197
if (
192198
contentType.startsWith('application/json') ||
193199
contentType.startsWith('application/ld+json') ||
194-
contentType.startsWith('application/octet-stream')
200+
contentType.startsWith('application/octet-stream') ||
201+
contentType.startsWith('multipart/form-data')
195202
) {
196203
const schema = res.content[contentType].schema!;
197204
return resolveValue(schema);

test/script.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { importSpecs } from '../dist/importSpecs.js';
22

33
importSpecs({
4+
sourceUrls: [
5+
{ name: 'openapi', url: 'https://api.diks.acc.lightbase.nl/_compas/structure.json?format=openapi' },
6+
],
47
sourceDirectory: 'test/specs-private',
58
exportDirectory: 'test/generated',
69
apiDirectory: '../../api',
7-
queryClientDir: '../../queryClient',
810
headerFilters: ['X-Parse-Session-Token', 'X-Golf-Platform', 'X-JWT-Assertion'],
911
});

0 commit comments

Comments
 (0)