Skip to content

Commit

Permalink
Add support for allOf directive from OpenAPI v3. Addresses issue yara…
Browse files Browse the repository at this point in the history
  • Loading branch information
blncoxauto committed Apr 22, 2020
1 parent 4796b5e commit 8399861
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swagger-to-graphql",
"version": "4.0.2",
"version": "4.0.2-allOf",
"author": "Roman Krivtsov",
"repository": {
"type": "git",
Expand Down
4 changes: 3 additions & 1 deletion src/json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface RootGraphQLSchema {
interface CommonSchema {
description?: string;
title?: string;
allOf?: JSONSchemaNoBody[];
}

export interface BodySchema extends CommonSchema {
Expand Down Expand Up @@ -59,7 +60,8 @@ export const isObjectType = (
): jsonSchema is ObjectSchema =>
!isBodyType(jsonSchema) &&
(Object.keys(jsonSchema).includes('properties') ||
jsonSchema.type === 'object');
jsonSchema.type === 'object' ||
jsonSchema.allOf !== undefined);

export const isArrayType = (
jsonSchema: JSONSchemaType,
Expand Down
23 changes: 23 additions & 0 deletions src/typeMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const jsonSchemaTypeToGraphQL = <IsInputType extends boolean>(
required: boolean,
): IsInputType extends true ? GraphQLInputType : GraphQLOutputType => {
const baseType = ((): GraphQLType => {

if (isBodyType(jsonSchema)) {
return jsonSchemaTypeToGraphQL(
title,
Expand Down Expand Up @@ -194,6 +195,28 @@ export const createGraphQLType = (
jsonSchema = { ...jsonSchema, title };
}

if (jsonSchema.allOf) {
let result: JSONSchemaType = {
type: 'object',
required: [],
properties: {}
}

// Merge object type properties
jsonSchema.allOf.map(item => {
if (isObjectType(item) && item.properties) {

This comment has been minimized.

Copy link
@jpruden92

jpruden92 Apr 26, 2020

I have the same problem as you. swagger-to-graphql doesn't support allOf. I have tried your commit with https://www.botswagger.com/swaggers/tmb.json but it doesn't work. Item has a model like this:

{ allOf: [ { properties: [Object], type: 'object', title: 'FeatureBase' }, { properties: [Object], type: 'object' } ]

isObjectType(result) ? result.properties = {
...result.properties,
...item.properties
} : undefined
} else {
throw new Error(`Unsupported allOf case ${item}`)
}
});

return createGraphQLType(result, title, isInputType, gqlTypes);
}

if (isArrayType(jsonSchema)) {
const itemsSchema = Array.isArray(jsonSchema.items)
? jsonSchema.items[0]
Expand Down
17 changes: 17 additions & 0 deletions test/fixture-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,21 @@ describe('Fixture', () => {
expect(graphschema).to.equal(expected);
});
});

describe('OpenAPI3 - allOf, someOf, oneOf', () => {
const swaggerSchema = `test/fixtures/handle-allOf.yaml`;
const graphqlFile = `test/fixtures/handle-allOf.graphql`;
it(`handles allOf - should convert to ${graphqlFile}`, async () => {
const schema = await graphQLSchema({
swaggerSchema,
callBackend() {
return new Promise(() => {});
},
});
const graphschema = graphql.printSchema(schema);
const expected = fs.readFileSync(graphqlFile, 'utf8');
expect(graphschema).to.equal(expected);
});
});

});
29 changes: 29 additions & 0 deletions test/fixtures/handle-allOf.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
type Mutation {
allOfTest_put(body: param_allOfTest_put_bodyInput): TestBody1!
}

input param_allOfTest_put_bodyInput {
int1: String
string1: String
enum1: String
bool1: Boolean
int3: String
string3: String
enum3: String
bool3: Boolean
}

type Query {
allOfTest_get: [TestBody1!]!
}

type TestBody1 {
int1: String
string1: String
enum1: String
bool1: Boolean
int2: String
string2: String
enum2: String
bool2: Boolean
}
147 changes: 147 additions & 0 deletions test/fixtures/handle-allOf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
openapi: 3.0.0
info:
description: "This is a test schema to test allOf functionality in Swagger"
version: 1.0.0
title: swagger-to-graphql OpenAPI allOf support
tags:
- name: test
description: This is a test
- name: openapi
description: This supports OpenAPI v3
paths:
/allOf:
get:
summary: Test that allOf works for schema resolution
operationId: allOfTest_get
responses:
"200":
description: Test Response
content:
application/json:
schema:
type: array
items:
- $ref: "#/components/schemas/TestCombinedSchema"
"400":
description: Invalid ID supplied
"404":
description: Pet not found
put:
summary: Put test
operationId: allOfTest_put
requestBody:
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/TestSchema1"
- $ref: "#/components/schemas/TestSchema3"
responses:
"200":
description: Test Response
content:
application/json:
schema:
$ref: "#/components/schemas/TestCombinedSchema"
"400":
description: Invalid ID supplied
"404":
description: Pet not found

servers:
- url: http://foo.bar/v3
components:
parameters:
testParam1:
name: testParam1
in: path
description: A test string parameter
required: true
schema:
type: string
testParam2:
name: testParam2
in: path
description: A test integer parameter
required: true
schema:
type: integer
format: int64
requestBodies:
TestBody1:
content:
application/json:
schema:
$ref: "#/components/schemas/TestCombinedSchema"
description: List of user object
required: true
TestBody2:
content:
application/json:
schema:
type: array
items:
allOf:
- $ref: "#/components/schemas/TestSchema1"
- $ref: "#/components/schemas/TestSchema2"
description: List of user object
required: true
schemas:
TestSchema1:
type: object
properties:
int1:
type: integer
format: int64
string1:
type: string
format: date-time
enum1:
type: string
enum:
- aaaa
- bbbb
- cccc
bool1:
type: boolean
default: false
TestSchema2:
type: object
properties:
int2:
type: integer
format: int64
string2:
type: string
format: date-time
enum2:
type: string
enum:
- aaaa
- bbbb
- cccc
bool2:
type: boolean
default: false
TestSchema3:
type: object
properties:
int3:
type: integer
format: int64
string3:
type: string
format: date-time
enum3:
type: string
enum:
- aaaa
- bbbb
- cccc
bool3:
type: boolean
default: false
TestCombinedSchema:
allOf:
- $ref: "#/components/schemas/TestSchema1"
- $ref: "#/components/schemas/TestSchema2"

0 comments on commit 8399861

Please sign in to comment.