diff --git a/packages/gatsby/src/redux/actions.js b/packages/gatsby/src/redux/actions.js index 986c26bdb4c1e..ea083c25eeb90 100644 --- a/packages/gatsby/src/redux/actions.js +++ b/packages/gatsby/src/redux/actions.js @@ -748,8 +748,15 @@ actions.createNodeField = ( node.fields = {} } + /** + * Normalized name of the field that will be used in schema + */ + const schemaFieldName = _.includes(name, `___NODE`) + ? name.split(`___`)[0] + : name + // Check that this field isn't owned by another plugin. - const fieldOwner = node.internal.fieldOwners[name] + const fieldOwner = node.internal.fieldOwners[schemaFieldName] if (fieldOwner && fieldOwner !== plugin.name) { throw new Error( stripIndent` @@ -765,7 +772,7 @@ actions.createNodeField = ( // Update node node.fields[name] = value - node.internal.fieldOwners[name] = plugin.name + node.internal.fieldOwners[schemaFieldName] = plugin.name return { type: `ADD_FIELD_TO_NODE`, diff --git a/packages/gatsby/src/schema/__tests__/__snapshots__/data-tree-utils-test.js.snap b/packages/gatsby/src/schema/__tests__/__snapshots__/data-tree-utils-test.js.snap index 76b3f2f9b1ea0..71992d1241589 100644 --- a/packages/gatsby/src/schema/__tests__/__snapshots__/data-tree-utils-test.js.snap +++ b/packages/gatsby/src/schema/__tests__/__snapshots__/data-tree-utils-test.js.snap @@ -55,7 +55,6 @@ Object { }, }, "date": "2006-07-22T22:39:53.000Z", - "emptyArray": null, "frontmatter": Object { "blue": 100, "circle": "happy", @@ -64,7 +63,6 @@ Object { "title": "The world of dash and adventure", }, "hair": 1, - "iAmNull": null, "key-with..unsupported-values": true, "name": "The Mad Max", "nestedArrays": Array [ diff --git a/packages/gatsby/src/schema/__tests__/data-tree-utils-test.js b/packages/gatsby/src/schema/__tests__/data-tree-utils-test.js index fa1545ec17ad2..4f9ea17bc0c25 100644 --- a/packages/gatsby/src/schema/__tests__/data-tree-utils-test.js +++ b/packages/gatsby/src/schema/__tests__/data-tree-utils-test.js @@ -99,8 +99,8 @@ describe(`Gatsby data tree utils`, () => { expect(getExampleValues(nodes)).toMatchSnapshot() }) - it(`null fields should have a null value`, () => { - expect(getExampleValues(nodes).iAmNull).toBeNull() + it(`skips null fields`, () => { + expect(getExampleValues(nodes).iAmNull).not.toBeDefined() }) it(`should not mutate the nodes`, () => { @@ -111,8 +111,8 @@ describe(`Gatsby data tree utils`, () => { expect(nodes[3].context.nestedObject.someOtherProperty).toEqual(3) }) - it(`turns empty or sparse arrays to null`, () => { - expect(getExampleValues(nodes).emptyArray).toBeNull() + it(`skips empty or sparse arrays`, () => { + expect(getExampleValues(nodes).emptyArray).not.toBeDefined() expect(getExampleValues(nodes).hair).toBeDefined() }) @@ -156,11 +156,11 @@ describe(`Gatsby data tree utils`, () => { it(`skips unsupported types`, () => { // Skips functions let example = getExampleValues([{ foo: () => {} }]) - expect(example.foo).toEqual(null) + expect(example.foo).not.toBeDefined() // Skips array of functions example = getExampleValues([{ foo: [() => {}] }]) - expect(example.foo).toEqual(null) + expect(example.foo).not.toBeDefined() }) }) diff --git a/packages/gatsby/src/schema/data-tree-utils.js b/packages/gatsby/src/schema/data-tree-utils.js index e777db64c836d..b3abeb3a2aec2 100644 --- a/packages/gatsby/src/schema/data-tree-utils.js +++ b/packages/gatsby/src/schema/data-tree-utils.js @@ -153,34 +153,37 @@ const extractFieldExamples = (nodes: object[], selector: string) => { // get list of keys in all nodes const allKeys = _.uniq(_.flatten(nodes.map(_.keys))) - return _.zipObject( - allKeys, - allKeys.map(key => { - const nextSelector = selector && `${selector}.${key}` - - const nodeWithValues = nodes.filter(node => { - if (!node) return false - - const value = node[key] - if (_.isObject(value)) { - return !isEmptyObjectOrArray(value) - } else { - return isDefined(value) - } + return _.pickBy( + _.zipObject( + allKeys, + allKeys.map(key => { + const nextSelector = selector && `${selector}.${key}` + + const nodeWithValues = nodes.filter(node => { + if (!node) return false + + const value = node[key] + if (_.isObject(value)) { + return !isEmptyObjectOrArray(value) + } else { + return isDefined(value) + } + }) + + // we want to keep track of nodes as we need it to get origin of data + const entries = nodeWithValues.map(node => { + const value = node[key] + return { + value, + parent: node, + ...extractTypes(value), + } + }) + + return extractFromEntries(entries, nextSelector, key) }) - - // we want to keep track of nodes as we need it to get origin of data - const entries = nodeWithValues.map(node => { - const value = node[key] - return { - value, - parent: node, - ...extractTypes(value), - } - }) - - return extractFromEntries(entries, nextSelector, key) - }) + ), + isDefined ) }