Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate unions from oneOf return type #330

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/openapi-to-graphql/src/oas_3_tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,13 @@ export function getSchemaTargetGraphQLType<TSource, TContext, TArgs>(
schema: SchemaObject,
data: PreprocessingData<TSource, TContext, TArgs>
): string | null {
if (schema.oneOf) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I don't think we can do this as oneOf and allOf does not necessitate union or object.

For example, this is an example provided by json-schema:

{
   "type": "number",
   "oneOf": [
     { "multipleOf": 5 },
     { "multipleOf": 3 }
   ]
 }

Additionally, even if oneOf contains a number of schemas, we still need to make a number of checks to see if we can still create a union as JSON schema oneOf is a lot more flexible than GraphQL union type.

For example, according to the specification, GraphQL unions cannot be composed of other unions

The member types of a Union type must all be Object base types; Scalar, Interface and Union types must not be member types of a Union. Similarly, wrapping types must not be member types of a Union.

That is why we have this check, to see if we have cases of nested oneOf/allOf.

return 'union'
}

if (schema.allOf) {
return 'object'
}
// CASE: object
if (schema.type === 'object' || typeof schema.properties === 'object') {
// TODO: additionalProperties is more like a flag than a type itself
Expand Down
8 changes: 2 additions & 6 deletions packages/openapi-to-graphql/src/preprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1504,14 +1504,10 @@ function createDataDefFromOneOf<TSource, TContext, TArgs>(
if (
oneOfData.allTargetGraphQLTypes.every(memberTargetGraphQLType => {
return memberTargetGraphQLType === 'object'
}) &&
oneOfData.allProperties.length > 0 // Redundant check
})
) {
// Ensure that parent schema is compatiable with oneOf
if (
def.targetGraphQLType === null ||
def.targetGraphQLType === 'object'
) {
if (def.targetGraphQLType === 'union') {
def.subDefinitions = []

collapsedSchema.oneOf.forEach(memberSchema => {
Expand Down