diff --git a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/normalize.js.snap b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/normalize.js.snap index fbee8e8fad9df..9639144d0a2bf 100644 --- a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/normalize.js.snap +++ b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/normalize.js.snap @@ -2587,7 +2587,7 @@ Our Lemnos products are made carefully by our craftsmen finely honed skillful te "email": "info@acgears.com", "id": "c4LgMotpNF6W20YKmuemW0a", "internal": Object { - "contentDigest": "179698e2d0fdeafe064c16dc552905e0", + "contentDigest": "56c8049cbea94a91a808515540f1e0b3", "type": "ContentfulBrand", }, "logo___NODE": "c2Y8LhXLnYAYqKCGEWG4EKI", @@ -2599,6 +2599,7 @@ Our Lemnos products are made carefully by our craftsmen finely honed skillful te "product___NODE": Array [ "c4BqrajvA8E6qwgkieoqmqO", ], + "twitter": "", "website": "http://www.lemnos.jp/en/", }, ], @@ -2610,17 +2611,22 @@ Our Lemnos products are made carefully by our craftsmen finely honed skillful te ], "companyDescription___NODE": "JrePkDVYomE8AwcuCUyMicompanyDescriptionTextNode", "companyName___NODE": "JrePkDVYomE8AwcuCUyMicompanyNameTextNode", + "email": "", "id": "JrePkDVYomE8AwcuCUyMi", "internal": Object { - "contentDigest": "60153e88a39483fa024d4bf41ab95b6a", + "contentDigest": "98dc28795de1ada78c781c9979afb19b", "type": "ContentfulBrand", }, "logo___NODE": "c4zj1ZOfHgQ8oqgaSKm4Qo2", "node_locale": "en-US", "parent": "Brand", + "phone": Array [ + "", + ], "product___NODE": Array [ "c5KsDBWseXY6QegucYAoacS", ], + "twitter": "", "website": "http://playsam.com/", }, ], @@ -2781,7 +2787,7 @@ Unsere Lemnos Produkte werden sorgfältig von unseren Handwerkern fein geschliff "email": "info@acgears.com", "id": "c4LgMotpNF6W20YKmuemW0a___de", "internal": Object { - "contentDigest": "6e4e76e159aef9a4c09d87404ffb6009", + "contentDigest": "62689ca2ee05da931171762ee0a60d1d", "type": "ContentfulBrand", }, "logo___NODE": "c2Y8LhXLnYAYqKCGEWG4EKI___de", @@ -2793,6 +2799,7 @@ Unsere Lemnos Produkte werden sorgfältig von unseren Handwerkern fein geschliff "product___NODE": Array [ "c4BqrajvA8E6qwgkieoqmqO___de", ], + "twitter": "", "website": "http://www.lemnos.jp/en/", }, ], @@ -2804,17 +2811,22 @@ Unsere Lemnos Produkte werden sorgfältig von unseren Handwerkern fein geschliff ], "companyDescription___NODE": "JrePkDVYomE8AwcuCUyMi___decompanyDescriptionTextNode", "companyName___NODE": "JrePkDVYomE8AwcuCUyMi___decompanyNameTextNode", + "email": "", "id": "JrePkDVYomE8AwcuCUyMi___de", "internal": Object { - "contentDigest": "51ead6a16ac5a54cc51e571eb8a0923d", + "contentDigest": "6d5995e7a04b1680c48c75a17112c533", "type": "ContentfulBrand", }, "logo___NODE": "c4zj1ZOfHgQ8oqgaSKm4Qo2___de", "node_locale": "de", "parent": "Brand", + "phone": Array [ + "", + ], "product___NODE": Array [ "c5KsDBWseXY6QegucYAoacS___de", ], + "twitter": "", "website": "http://playsam.com/", }, ], diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 5bf857653c89f..c6ae2485e4c06 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -139,7 +139,7 @@ exports.buildForeignReferenceMap = ({ } function createTextNode(node, key, text, createNode) { - const str = _.isString(text) ? text : ` ` + const str = _.isString(text) && text !== `` ? text : ` ` const textNode = { id: `${node.id}${key}TextNode`, parent: node.id, @@ -193,6 +193,47 @@ exports.createContentTypeNodes = ({ // Get localized fields. const entryItemFields = _.mapValues(entryItem.fields, v => getField(v)) + // If entry is not set by user, provide an empty value of the same type + const setBlankValue = contentTypeItemField => { + if (contentTypeItemField.type.match(/Symbol|Text|Date/)) { + return `` + } else if (contentTypeItemField.type.match(/Number/)) { + return NaN + } else if ( + contentTypeItemField.type.match( + /Object|Location|Media|Reference|Link/ + ) + ) { + return {} + } else if (contentTypeItemField.type.match(/Array/)) { + // Setting values recursively is useful for 'never defined entries' + // TODO: Does not work for arrays of references, assets, objects, ... + return [setBlankValue(contentTypeItemField.items)] + } else if (contentTypeItemField.type.match(/Boolean/)) { + return false + } + } + contentTypeItem.fields.forEach(contentTypeItemField => { + const fieldName = contentTypeItemField.id + if (typeof entryItemFields[fieldName] === `undefined`) { + entryItemFields[fieldName] = setBlankValue(contentTypeItemField) + } + // Add a "json" property on Objects with the stringified version of its content + // This allows for querying objects with changing properties + // TODO: how to handle a property "json" entered by user? Should we just + // use a more specific name than "json" for our created property + if (contentTypeItemField.type === `Object`) { + if (typeof entryItemFields[fieldName].json === `undefined`) { + entryItemFields[fieldName].json = JSON.stringify( + entryItemFields[fieldName] + ) + } else { + const { json, ...originalObj } = entryItemFields[fieldName] + entryItemFields[fieldName].json = JSON.stringify(originalObj) + } + } + }) + // Prefix any conflicting fields // https://github.com/gatsbyjs/gatsby/pull/1084#pullrequestreview-41662888 conflictFields.forEach(conflictField => { @@ -207,6 +248,7 @@ exports.createContentTypeNodes = ({ const entryItemFieldValue = entryItemFields[entryItemFieldKey] if (Array.isArray(entryItemFieldValue)) { if ( + entryItemFieldValue[0] && entryItemFieldValue[0].sys && entryItemFieldValue[0].sys.type && entryItemFieldValue[0].sys.id diff --git a/packages/gatsby/src/bootstrap/index.js b/packages/gatsby/src/bootstrap/index.js index 47b2eecfee23b..003d15c107db8 100644 --- a/packages/gatsby/src/bootstrap/index.js +++ b/packages/gatsby/src/bootstrap/index.js @@ -17,7 +17,7 @@ const { initCache } = require(`../utils/cache`) const report = require(`../reporter`) // Show stack trace on unhandled promises. -process.on("unhandledRejection", (reason, p) => { +process.on(`unhandledRejection`, (reason, p) => { report.panic(reason) })