Skip to content

Commit

Permalink
Merge pull request #67 from peterc1731/fix/nullability
Browse files Browse the repository at this point in the history
fix: allow nullable input objects and arrays
  • Loading branch information
jonnydgreen authored Oct 12, 2024
2 parents be7e2f2 + e948cd7 commit 773e505
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 21 deletions.
12 changes: 9 additions & 3 deletions lib/validators/json-schema-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,22 @@ class JSONSchemaValidator extends Validator {
if (isInputObjectType(namedType)) {
if (isListType(type)) {
const items = { ...builtValidationSchema.items, $ref: `https://mercurius.dev/validation/${namedType.name}` }
builtValidationSchema = { ...builtValidationSchema, type: 'array', items }
builtValidationSchema = { ...builtValidationSchema, type: 'array', items, nullable: !isNonNull }
} else {
builtValidationSchema = { ...builtValidationSchema, type: 'object', $ref: `https://mercurius.dev/validation/${namedType.name}` }
builtValidationSchema = {
...builtValidationSchema,
type: 'object',
$ref: `https://mercurius.dev/validation/${namedType.name}`,
nullable: !isNonNull
}
}
// If we have an array of scalars, set the array type and infer the items
} else if (isListType(type)) {
let items = { ...inferJSONSchemaType(namedType, isNonNull, this[kOpts].customTypeInferenceFn), ...builtValidationSchema.items }
if (typeValidation !== null) {
items = { ...items, ...typeValidation.items }
}
builtValidationSchema = { ...builtValidationSchema, type: 'array', items }
builtValidationSchema = { ...builtValidationSchema, type: 'array', items, nullable: !isNonNull }
}

// Merge with existing validation
Expand Down Expand Up @@ -106,6 +111,7 @@ class JSONSchemaValidator extends Validator {
let typeValidationSchema = {
$id: `https://mercurius.dev/validation/${typeName}`,
type: 'object',
nullable: true,
properties: {}
}

Expand Down
15 changes: 10 additions & 5 deletions test/advanced-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ t.test('Advanced', t => {
$id: 'https://mercurius.dev/validation/ArrayFilters/values',
items: {
type: ['string', 'null']
}
},
nullable: true
},
data: []
}
Expand Down Expand Up @@ -224,7 +225,8 @@ t.test('Advanced', t => {
$id: 'https://mercurius.dev/validation/Query/messages/arrayScalarFilters',
items: {
type: ['string', 'null']
}
},
nullable: true
},
data: [
''
Expand All @@ -245,7 +247,8 @@ t.test('Advanced', t => {
type: 'array',
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
}
},
nullable: true
},
data: []
}
Expand Down Expand Up @@ -553,7 +556,8 @@ t.test('Advanced', t => {
$id: 'https://mercurius.dev/validation/Query/messages/arrayScalarFilters',
items: {
type: ['string', 'null']
}
},
nullable: true
},
data: [
''
Expand All @@ -574,7 +578,8 @@ t.test('Advanced', t => {
type: 'array',
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
}
},
nullable: true
},
data: []
}
Expand Down
25 changes: 18 additions & 7 deletions test/directive-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ t.test('With directives', t => {
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
},
nullable: true,
minItems: 2
},
data: [{ filters: [{ text: '' }] }]
Expand Down Expand Up @@ -848,7 +849,8 @@ t.test('With directives', t => {
minItems: 2,
items: {
type: 'string'
}
},
nullable: false
},
data: [
''
Expand All @@ -869,6 +871,7 @@ t.test('With directives', t => {
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
},
nullable: false,
minItems: 2
},
data: [{ values: [''], filters: [{ text: '' }] }]
Expand Down Expand Up @@ -1080,6 +1083,7 @@ t.test('With directives', t => {
minProperties: 1,
$id: 'https://mercurius.dev/validation/Filters',
type: 'object',
nullable: true,
properties: {
text: {
type: ['string', 'null'],
Expand Down Expand Up @@ -1173,6 +1177,7 @@ t.test('With directives', t => {
minProperties: 2,
$id: 'https://mercurius.dev/validation/Filters',
type: 'object',
nullable: true,
properties: {
text: {
minLength: 1,
Expand Down Expand Up @@ -2210,7 +2215,8 @@ t.test('With directives', t => {
maxProperties: 1,
$id: 'https://mercurius.dev/validation/Query/messages/filters',
type: 'object',
$ref: 'https://mercurius.dev/validation/Filters'
$ref: 'https://mercurius.dev/validation/Filters',
nullable: true
},
data: {
id: '',
Expand Down Expand Up @@ -2302,7 +2308,8 @@ t.test('With directives', t => {
minProperties: 1,
$id: 'https://mercurius.dev/validation/Query/messages/filters',
type: 'object',
$ref: 'https://mercurius.dev/validation/Filters'
$ref: 'https://mercurius.dev/validation/Filters',
nullable: true
},
data: {}
}
Expand Down Expand Up @@ -2386,7 +2393,8 @@ t.test('With directives', t => {
maxItems: 1,
$id: 'https://mercurius.dev/validation/Query/messages/ids',
type: 'array',
items: {}
items: {},
nullable: true
},
data: [
'1',
Expand Down Expand Up @@ -2473,7 +2481,8 @@ t.test('With directives', t => {
minItems: 1,
$id: 'https://mercurius.dev/validation/Query/messages/ids',
type: 'array',
items: {}
items: {},
nullable: true
},
data: []
}
Expand Down Expand Up @@ -2558,7 +2567,8 @@ t.test('With directives', t => {
uniqueItems: true,
$id: 'https://mercurius.dev/validation/Query/messages/ids',
type: 'array',
items: {}
items: {},
nullable: true
},
data: [
'1',
Expand Down Expand Up @@ -2651,7 +2661,8 @@ t.test('With directives', t => {
type: 'integer'
},
$id: 'https://mercurius.dev/validation/Query/messages/ids',
type: 'array'
type: 'array',
nullable: true
},
data: [
'1.1'
Expand Down
49 changes: 43 additions & 6 deletions test/json-schema-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,15 @@ t.test('JSON Schema validators', t => {
id
text
}
messages(filters: { text: "hello"}, nestedFilters: { input: { text: "hello"} }) {
messages(
filters: { text: "hello"},
nestedFilters: { input: { text: "hello"} },
arrayScalarFilters: ["hello"],
arrayObjectFilters: [{
values: ["hello"]
filters: [{ text: "hello" }]
}]
) {
id
text
}
Expand Down Expand Up @@ -457,6 +465,7 @@ t.test('JSON Schema validators', t => {
type: 'string',
minLength: 1
},
nullable: true,
minItems: 2
},
data: ['']
Expand Down Expand Up @@ -556,6 +565,7 @@ t.test('JSON Schema validators', t => {
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
},
nullable: true,
minItems: 2
},
data: [{ filters: [{ text: '' }] }]
Expand Down Expand Up @@ -768,7 +778,8 @@ t.test('JSON Schema validators', t => {
minItems: 2,
items: {
type: 'string'
}
},
nullable: false
},
data: [
''
Expand All @@ -789,6 +800,7 @@ t.test('JSON Schema validators', t => {
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
},
nullable: false,
minItems: 2
},
data: [{ values: [''], filters: [{ text: '' }] }]
Expand Down Expand Up @@ -957,6 +969,7 @@ t.test('JSON Schema validators', t => {
minProperties: 1,
$id: 'https://mercurius.dev/validation/Filters',
type: 'object',
nullable: true,
properties: {
text: {
type: ['string', 'null'],
Expand Down Expand Up @@ -1041,6 +1054,7 @@ t.test('JSON Schema validators', t => {
minProperties: 2,
$id: 'https://mercurius.dev/validation/Filters',
type: 'object',
nullable: true,
properties: {
text: {
minLength: 1,
Expand Down Expand Up @@ -1352,6 +1366,7 @@ t.test('JSON Schema validators', t => {
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
},
nullable: true,
minItems: 2
},
data: [
Expand Down Expand Up @@ -1591,6 +1606,7 @@ t.test('JSON Schema validators', t => {
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
},
nullable: true,
minItems: 2
},
data: [
Expand Down Expand Up @@ -1831,6 +1847,7 @@ t.test('JSON Schema validators', t => {
items: {
$ref: 'https://mercurius.dev/validation/ArrayFilters'
},
nullable: true,
minItems: 2
},
data: [
Expand Down Expand Up @@ -2060,9 +2077,22 @@ t.test('JSON Schema validators', t => {
t.teardown(app.close.bind(app))

app.register(mercurius, {
schema: `type Query {
nullableInput(input: String): String
}`,
schema: `
input TestObject {
value: Float!
}
type Query {
nullableInput(
stringInput: String,
floatInput: Float,
intInput: Int,
objectInput: TestObject,
arrayInput: [String!],
objectArrayInput: [TestObject!]
): String
}
`,
resolvers: {
Query: {
nullableInput: async (_, { input }) => {
Expand All @@ -2074,7 +2104,14 @@ t.test('JSON Schema validators', t => {
app.register(mercuriusValidation)

const query = `query {
nullableInput(input: null)
nullableInput(
stringInput: null,
floatInput: null,
intInput: null,
objectInput: null,
arrayInput: null,
objectArrayInput: null
)
}`

const response = await app.inject({
Expand Down

0 comments on commit 773e505

Please sign in to comment.