diff --git a/gridsome/lib/graphql/__tests__/createFieldTypes.spec.js b/gridsome/lib/graphql/__tests__/createFieldTypes.spec.js index bbeb450b1..fbf930a34 100644 --- a/gridsome/lib/graphql/__tests__/createFieldTypes.spec.js +++ b/gridsome/lib/graphql/__tests__/createFieldTypes.spec.js @@ -32,8 +32,10 @@ const nodes = [ refList: [ { typeName: 'Post1', id: '1' }, { typeName: 'Post2', id: '1' }, - { typeName: 'Post3', id: '1' } + { typeName: 'Post3', id: '1' }, + { typeName: undefined, id: '1' } ], + invalidRef: { typeName: undefined, id: '1' }, simpleObj: { foo: 'bar' }, @@ -94,6 +96,7 @@ test('merge node fields', () => { expect(fields.simpleObj).toMatchObject({ foo: 'bar' }) expect(fields.extendObj).toMatchObject({ bar: 'foo' }) expect(fields.obj).toMatchObject({ foo: 'bar', bar: 'foo', test: { foo: 'bar' }}) + expect(fields.invalidRef).toBeUndefined() }) test('create graphql types from node fields', () => { diff --git a/gridsome/lib/graphql/__tests__/nodes.spec.js b/gridsome/lib/graphql/__tests__/nodes.spec.js index 4d255ac01..6267ceb34 100644 --- a/gridsome/lib/graphql/__tests__/nodes.spec.js +++ b/gridsome/lib/graphql/__tests__/nodes.spec.js @@ -238,7 +238,7 @@ test('create node reference', async () => { } }) - authors.addNode({ + const author = authors.addNode({ id: '2' }) @@ -252,7 +252,7 @@ test('create node reference', async () => { posts.addNode({ id: '2', - customRef: api.store.createReference('TestAuthor', '2') + customRef: api.store.createReference(author) }) const query = `{ @@ -281,9 +281,7 @@ test('create node reference', async () => { }) test('create node reference to same typeName', async () => { - const { addNode } = api.store.addContentType({ - typeName: 'TestPost' - }) + const { addNode } = api.store.addContentType('TestPost') const post = addNode({ id: '1' }) diff --git a/gridsome/lib/graphql/createFieldDefinitions.js b/gridsome/lib/graphql/createFieldDefinitions.js index 395bf4010..c01822662 100644 --- a/gridsome/lib/graphql/createFieldDefinitions.js +++ b/gridsome/lib/graphql/createFieldDefinitions.js @@ -1,5 +1,6 @@ const { omit, isPlainObject, isNumber, isInteger } = require('lodash') const { isRefField, isRefFieldDefinition } = require('./utils') +const { warn } = require('../utils/log') module.exports = function createFieldDefinitions (nodes) { let fields = {} @@ -11,7 +12,7 @@ module.exports = function createFieldDefinitions (nodes) { return fields } -function fieldValues (obj, currentObj = {}) { +function fieldValues (obj, currentObj = {}, path = []) { const res = { ...currentObj } for (const key in obj) { @@ -22,13 +23,13 @@ function fieldValues (obj, currentObj = {}) { if (value === undefined) continue if (value === null) continue - res[key] = fieldValue(value, currentObj[key]) + res[key] = fieldValue(value, currentObj[key], path.concat(key)) } return res } -function fieldValue (value, currentValue) { +function fieldValue (value, currentValue, path = []) { if (Array.isArray(value)) { const arr = Array.isArray(currentValue) ? currentValue : [] const length = value.length @@ -39,7 +40,9 @@ function fieldValue (value, currentValue) { } for (let i = 0; i < length; i++) { - if (!currentValue.typeName.includes(value[i].typeName)) { + if (!value[i].typeName) { + warn(`Missing typeName for reference at: ${path.join('.')}.${i}`) + } else if (!currentValue.typeName.includes(value[i].typeName)) { currentValue.typeName.push(value[i].typeName) } } @@ -52,19 +55,24 @@ function fieldValue (value, currentValue) { } for (let i = 0; i < length; i++) { - arr[0] = fieldValue(value[i], arr[0]) + arr[0] = fieldValue(value[i], arr[0], path.concat(i)) } return arr } else if (isPlainObject(value)) { if (isRefField(value)) { + if (!value.typeName) { + warn(`Missing typeName for reference in field: ${path.join('.')}`) + return currentValue + } + const ref = currentValue || { typeName: value.typeName } ref.isList = ref.isList || Array.isArray(value.id) return ref } - return fieldValues(value, currentValue) + return fieldValues(value, currentValue, path) } else if (isNumber(value)) { return isNumber(currentValue) && isInteger(value) ? currentValue diff --git a/gridsome/lib/graphql/resolvers.js b/gridsome/lib/graphql/resolvers.js index 5aa5c9ada..eb926761b 100644 --- a/gridsome/lib/graphql/resolvers.js +++ b/gridsome/lib/graphql/resolvers.js @@ -15,6 +15,10 @@ function createRefResolver ({ typeName, isList = false }) { const query = {} let chain + if (fieldValue.hasOwnProperty('typeName') && !fieldValue.typeName) { + return isList ? [] : null + } + if (id) { query.id = Array.isArray(id) ? { $in: id } : id query['internal.typeName'] = Array.isArray(typeName) ? { $in: typeName } : typeName diff --git a/gridsome/lib/store/PluginStore.js b/gridsome/lib/store/PluginStore.js index 0e2ceb608..bfe565c5b 100644 --- a/gridsome/lib/store/PluginStore.js +++ b/gridsome/lib/store/PluginStore.js @@ -184,7 +184,11 @@ class PluginStore { createReference (typeName, id) { if (isPlainObject(typeName)) { - return { typeName: typeName.typeName, id: typeName.id } + if (!typeName.$loki) { + throw new Error(`store.createReference() expected a node.`) + } + + return { typeName: typeName.internal.typeName, id: typeName.id } } return { typeName, id }