Skip to content

Commit

Permalink
Store object with no properties in arbitray JSON type
Browse files Browse the repository at this point in the history
Signed-off-by: Alan Cha <[email protected]>
  • Loading branch information
Alan-Cha authored and ErikWittern committed Jul 31, 2019
1 parent 2a258bd commit de0a5f8
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 104 deletions.
29 changes: 0 additions & 29 deletions packages/openapi-to-graphql/lib/resolver_builder.js

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

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/resolver_builder.js.map

Large diffs are not rendered by default.

9 changes: 2 additions & 7 deletions packages/openapi-to-graphql/lib/schema_builder.js

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

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/schema_builder.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/utils.js

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

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/utils.js.map

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

43 changes: 0 additions & 43 deletions packages/openapi-to-graphql/src/resolver_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,6 @@ export function getResolver({

resolveData.responseHeaders = response.headers

responseBody = stringifyObjectsWithNoProperties(
responseBody,
operation.responseDefinition
)

// Deal with the fact that the server might send unsanitized data
let saneData = Oas3Tools.sanitizeObjKeys(responseBody)

Expand Down Expand Up @@ -904,41 +899,3 @@ function graphQLErrorWithExtensions(
): GraphQLError {
return new GraphQLError(message, null, null, null, null, null, extensions)
}

/**
* Ideally, all objects should be defined with properties. However, if they are
* not, then we can at least stringify the data.
*
* This function recursively ensures that objects have properties, if not
* stringify the data to match the mitigation.
*/
function stringifyObjectsWithNoProperties(
data: any,
dataDef: DataDefinition
): any {
if (typeof dataDef !== 'undefined') {
if (dataDef.type === 'array') {
data = data.map(element => {
return stringifyObjectsWithNoProperties(
element,
dataDef.subDefinitions as DataDefinition
)
})
} else if (dataDef.type === 'object') {
if (typeof dataDef.schema.properties !== 'undefined') {
Object.keys(data).forEach(propertyName => {
data[propertyName] = stringifyObjectsWithNoProperties(
data[propertyName],
dataDef.subDefinitions[propertyName]
)
})

// Schema does not have properties defined, therefore stringify
} else {
return JSON.stringify(data)
}
}
}

return data
}
9 changes: 2 additions & 7 deletions packages/openapi-to-graphql/src/schema_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,7 @@ function createOrReuseOt({
* cannot create a GraphQL Object Type for it because in GraphQL, all Object
* Type properties must be named.
*
* Instead, stringify the response.
*
* NOTE: there is a similar check in the resolver_builder.ts so that the
* response data is properly stringified.
*
* See stringifyObjectsWithNoProperties() function
* Instead, store response in an arbitray JSON type.
*/
if (typeof def.schema.properties === 'undefined') {
handleWarning({
Expand All @@ -226,7 +221,7 @@ function createOrReuseOt({
data,
log: translationLog
})
return GraphQLString
return GraphQLJSON
}

const description =
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const mitigations = {
UNRESOLVABLE_REFERENCE: `The schema will not be resolved.`,
UNSUPPORTED_HTTP_SECURITY_SCHEME: `Ignore security scheme.`,
NON_APPLICATION_JSON_SCHEMA: `Ignore schema`,
OBJECT_MISSING_PROPERTIES: `The (sub-)object will be stringified. The property will return a string in the interface.`,
OBJECT_MISSING_PROPERTIES: `The (sub-)object will be stored in an arbitray JSON type.`,

// Links
UNRESOLVABLE_LINK: `Ignore link.`,
Expand Down
48 changes: 35 additions & 13 deletions packages/openapi-to-graphql/test/example_api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,7 @@ test('Content property in parameter object', () => {
})
})

test('Stringify objects without defined properties', () => {
test('Handle objects without defined properties with arbitrary GraphQL JSON type', () => {
const query = `{
trashcan(username:"arlene") {
brand,
Expand All @@ -1272,28 +1272,50 @@ test('Stringify objects without defined properties', () => {
return graphql(createdSchema, query).then(result => {
expect(result).toEqual({
data: {
trashcan: {
brand: '"Garbage Emporium"',
contents: [
'{"type":"apple","message":"Half-eaten"}',
'{"type":"sock","message":"Lost one"}'
"trashcan": {
"brand": "Garbage Emporium",
"contents": [
{
"type": "apple",
"message": "Half-eaten"
},
{
"type": "sock",
"message": "Lost one"
}
]
},
trashcans: [
"trashcans": [
{
contents: [
'{"type":"apple","message":"Half-eaten"}',
'{"type":"sock","message":"Lost one"}'
"contents": [
{
"type": "apple",
"message": "Half-eaten"
},
{
"type": "sock",
"message": "Lost one"
}
]
},
{
contents: ['{"type":"sock","message":"Lost one"}']
"contents": [
{
"type": "sock",
"message": "Lost one"
}
]
},
{
contents: []
"contents": []
},
{
contents: ['{"type":"tissue","message":"Used"}']
"contents": [
{
"type": "tissue",
"message": "Used"
}
]
}
]
}
Expand Down

0 comments on commit de0a5f8

Please sign in to comment.