Skip to content

Commit dd98687

Browse files
Alan-ChaErikWittern
authored andcommitted
Non-nullable properties in GraphQL object types
Signed-off-by: Alan Cha <[email protected]>
1 parent 13b2453 commit dd98687

File tree

8 files changed

+51
-22
lines changed

8 files changed

+51
-22
lines changed

packages/openapi-to-graphql/lib/schema_builder.js

Lines changed: 13 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/lib/schema_builder.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/lib/utils.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export declare const mitigations: {
1717
UNSUPPORTED_JSON_SCHEMA_KEYWORD: string;
1818
UNION_MEMBER_NON_OBJECT: string;
1919
AMBIGUOUS_UNION_MEMBERS: string;
20+
CANNOT_GET_FIELD_TYPE: string;
2021
UNRESOLVABLE_LINK: string;
2122
AMBIGUOUS_LINK: string;
2223
LINK_NAME_COLLISION: string;

packages/openapi-to-graphql/lib/utils.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/lib/utils.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/openapi-to-graphql/src/schema_builder.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ function createOrReuseList({
475475
translationLog(`Reuse GraphQLList '${def.graphQLInputObjectTypeName}'`)
476476
return def.graphQLInputObjectType as GraphQLList<any>
477477
}
478-
478+
479479
// Create new List Object Type
480480
translationLog(`Create GraphQLList '${def.graphQLTypeName}'`)
481481

@@ -600,7 +600,7 @@ function createFields({
600600
// Create fields for properties
601601
for (let fieldTypeKey in fieldTypeDefinitions) {
602602
const fieldTypeDefinition = fieldTypeDefinitions[fieldTypeKey]
603-
const schema = fieldTypeDefinition.schema
603+
const fieldSchema = fieldTypeDefinition.schema
604604

605605
// Get object type describing the property
606606
const objectType = getGraphQLType({
@@ -611,11 +611,8 @@ function createFields({
611611
isInputObjectType
612612
})
613613

614-
// Determine if this property is required in mutations
615-
const reqMutationProp =
616-
isInputObjectType &&
617-
'required' in def.schema && // The full schema, not subschema, will contain the required property
618-
def.schema.required.includes(fieldTypeKey)
614+
const requiredProperty =
615+
'required' in def.schema && def.schema.required.includes(fieldTypeKey) // The full schema, not field schema, will contain the required property
619616

620617
// Finally, add the object type to the fields (using sanitized field name)
621618
if (objectType) {
@@ -629,12 +626,21 @@ function createFields({
629626
data.saneMap
630627
)
631628
fields[sanePropName] = {
632-
type: reqMutationProp
629+
type: requiredProperty
633630
? new GraphQLNonNull(objectType)
634631
: (objectType as GraphQLOutputType),
635632

636-
description: schema.description
633+
description: fieldSchema.description
637634
}
635+
} else {
636+
handleWarning({
637+
typeKey: 'CANNOT_GET_FIELD_TYPE',
638+
message:
639+
`Cannot obtain GraphQL type for field '${fieldTypeKey}' in ` +
640+
`GraphQL type '${JSON.stringify(def.schema)}'.`,
641+
data,
642+
log: translationLog
643+
})
638644
}
639645
}
640646

packages/openapi-to-graphql/src/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const mitigations = {
2626
UNSUPPORTED_JSON_SCHEMA_KEYWORD: `Ignore keyword and continue.`,
2727
UNION_MEMBER_NON_OBJECT: `Ignore union member type and continue.`,
2828
AMBIGUOUS_UNION_MEMBERS: `Ignore issue and continue.`,
29+
CANNOT_GET_FIELD_TYPE: `Ignore field and continue.`,
2930

3031
// Links
3132
UNRESOLVABLE_LINK: `Ignore link.`,

packages/openapi-to-graphql/test/example_api.test.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,8 +1901,11 @@ test('Option idFormats', () => {
19011901
fields {
19021902
name
19031903
type {
1904-
name
19051904
kind
1905+
ofType {
1906+
name
1907+
kind
1908+
}
19061909
}
19071910
}
19081911
}
@@ -1922,8 +1925,11 @@ test('Option idFormats', () => {
19221925
).toEqual({
19231926
name: 'patentId',
19241927
type: {
1925-
name: 'ID',
1926-
kind: 'SCALAR'
1928+
kind: 'NON_NULL',
1929+
ofType: {
1930+
name: 'ID',
1931+
kind: 'SCALAR'
1932+
}
19271933
}
19281934
})
19291935
})
@@ -1933,7 +1939,7 @@ test('Option idFormats', () => {
19331939
test('Required properties for input object types', () => {
19341940
const userInputType = createdSchema.getType('UserInput')
19351941

1936-
// The exclamation mark shows that it is a required property
1942+
// The exclamation mark shows that it is a required (non-nullable) property
19371943
expect(userInputType.toConfig().fields.address.type.toString()).toEqual(
19381944
'AddressInput!'
19391945
)
@@ -2186,6 +2192,14 @@ test('Query string arguments are not created when they are provided through requ
21862192
})
21872193
})
21882194

2195+
test('Non-nullable properties for object types', () => {
2196+
const coordinates = createdSchema.getType('Coordinates')
2197+
2198+
// The exclamation mark shows that it is a required (non-nullable) property
2199+
expect(coordinates.toConfig().fields.lat.type.toString()).toEqual('Float!')
2200+
expect(coordinates.toConfig().fields.long.type.toString()).toEqual('Float!')
2201+
})
2202+
21892203
test('Option genericPayloadArgName', () => {
21902204
const query = `{
21912205
__schema {

0 commit comments

Comments
 (0)