Skip to content

Commit 428c75f

Browse files
author
Stefan Cooper
committed
fix: union when there are multiple request/response types defined
Contributes to #314 Signed-off-by: Stefan Cooper <[email protected]>
1 parent a590fe8 commit 428c75f

File tree

4 files changed

+495
-19
lines changed

4 files changed

+495
-19
lines changed

src/schema-routes/schema-routes.ts

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -331,16 +331,30 @@ export class SchemaRoutes {
331331

332332
/* content: { "multipart/form-data": { schema: {...} }, "application/json": { schema: {...} } } */
333333

334-
/* for example: dataType = "multipart/form-data" */
334+
// Check if there are multiple media types with schemas
335+
const schemasWithDataTypes = [];
335336
for (const dataType in content) {
336337
if (content[dataType]?.schema) {
337-
return {
338+
schemasWithDataTypes.push({
338339
...content[dataType].schema,
339340
dataType,
340-
};
341+
});
341342
}
342343
}
343344

345+
// If there's only one schema, return it directly
346+
if (schemasWithDataTypes.length === 1) {
347+
return schemasWithDataTypes[0];
348+
}
349+
350+
// If there are multiple schemas, create a oneOf schema to generate a union type
351+
if (schemasWithDataTypes.length > 1) {
352+
return {
353+
oneOf: schemasWithDataTypes,
354+
dataType: schemasWithDataTypes[0].dataType, // Use the first dataType for compatibility
355+
};
356+
}
357+
344358
return null;
345359
};
346360

@@ -357,24 +371,46 @@ export class SchemaRoutes {
357371
this.schemaParserFabric.schemaUtils.getSchemaRefType(requestInfo);
358372

359373
if (schema) {
360-
const content = this.schemaParserFabric.getInlineParseContent(
361-
schema,
362-
typeName,
363-
[operationId],
364-
);
365-
const foundedSchemaByName = parsedSchemas.find(
366-
(parsedSchema) =>
367-
this.typeNameFormatter.format(parsedSchema.name) === content,
368-
);
369-
const foundSchemaByContent = parsedSchemas.find((parsedSchema) =>
370-
lodash.isEqual(parsedSchema.content, content),
371-
);
374+
// If we have a oneOf schema (multiple media types), handle it specially
375+
if (schema.oneOf) {
376+
// Process each schema in the oneOf array
377+
const unionTypes = schema.oneOf.map(subSchema => {
378+
return this.schemaParserFabric.getInlineParseContent(
379+
subSchema,
380+
typeName,
381+
[operationId],
382+
);
383+
});
384+
385+
// Filter out any duplicates or Any types
386+
const filteredTypes = this.schemaParserFabric.schemaUtils.filterSchemaContents(
387+
unionTypes,
388+
(content) => content !== this.config.Ts.Keyword.Any
389+
);
390+
391+
// Create a union type
392+
return this.config.Ts.UnionType(filteredTypes);
393+
} else {
394+
// Handle single schema as before
395+
const content = this.schemaParserFabric.getInlineParseContent(
396+
schema,
397+
typeName,
398+
[operationId],
399+
);
400+
const foundedSchemaByName = parsedSchemas.find(
401+
(parsedSchema) =>
402+
this.typeNameFormatter.format(parsedSchema.name) === content,
403+
);
404+
const foundSchemaByContent = parsedSchemas.find((parsedSchema) =>
405+
lodash.isEqual(parsedSchema.content, content),
406+
);
372407

373-
const foundSchema = foundedSchemaByName || foundSchemaByContent;
408+
const foundSchema = foundedSchemaByName || foundSchemaByContent;
374409

375-
return foundSchema
376-
? this.typeNameFormatter.format(foundSchema.name)
377-
: content;
410+
return foundSchema
411+
? this.typeNameFormatter.format(foundSchema.name)
412+
: content;
413+
}
378414
}
379415

380416
if (refTypeInfo) {

0 commit comments

Comments
 (0)