From c64a932e52e55c8a89766ec526c187bc8e9af07f Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Mon, 26 Jun 2017 19:31:14 -0700 Subject: [PATCH] [1.0] Contentful fixes (#1263) * Some fixes for source-contentful * Update yarn.lock --- .../using-contentful/src/pages/image-api.js | 29 +-- .../src/__tests__/extend-node-type.js | 18 +- .../src/gatsby-node.js | 188 ++++++++++-------- .../src/process-api-data.js | 25 ++- .../src/proxy-handlers.js | 3 - .../src/cache-dir/develop-static-entry.js | 1 - packages/gatsby/src/redux/index.js | 5 +- packages/gatsby/src/utils/develop.js | 4 +- yarn.lock | 67 ++++--- 9 files changed, 197 insertions(+), 143 deletions(-) diff --git a/examples/using-contentful/src/pages/image-api.js b/examples/using-contentful/src/pages/image-api.js index 52c09bc419957..9db263d784e81 100644 --- a/examples/using-contentful/src/pages/image-api.js +++ b/examples/using-contentful/src/pages/image-api.js @@ -121,7 +121,8 @@ export default props => { You can also set the{` `} resizing behavior - {` `} + + {` `} and{` `} resizing focus area @@ -180,19 +181,19 @@ export default props => { a maxWidth, the max width the container of the images reaches.

- {assets.map(({ node: { title, responsiveSizes } }) => ( - {title} - ))} + {assets.map(({ node: { title, responsiveSizes } }) => + {title} + )}

GraphQL query

          {
   const image = {
     defaultLocale: `en-US`,
     file: {
-        url: `//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg`,
-        fileName: `ryugj83mqwa1asojwtwb.jpg`,
-        contentType: `image/jpeg`,
-        details: {
-          size: 28435,
-          image: {
-            width: `4500`,
-            height: `6000`,
-          },
+      url: `//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg`,
+      fileName: `ryugj83mqwa1asojwtwb.jpg`,
+      contentType: `image/jpeg`,
+      details: {
+        size: 28435,
+        image: {
+          width: `4500`,
+          height: `6000`,
         },
       },
+    },
   }
   describe(`resolveResponsiveResolution`, () => {
     it(`generates responsive resolution data for images`, async () => {
diff --git a/packages/gatsby-source-contentful/src/gatsby-node.js b/packages/gatsby-source-contentful/src/gatsby-node.js
index be08443b5afbf..c8dbd13d2aa39 100644
--- a/packages/gatsby-source-contentful/src/gatsby-node.js
+++ b/packages/gatsby-source-contentful/src/gatsby-node.js
@@ -12,11 +12,16 @@ const _ = require(`lodash`)
 exports.setFieldsOnGraphQLNodeType = require(`./extend-node-type`).extendNodeType
 
 exports.sourceNodes = async (
-  { boundActionCreators, getNode, hasNodeChanged, store },
+  { boundActionCreators, getNodes, hasNodeChanged, store },
   { spaceId, accessToken }
 ) => {
-  const { createNode, setPluginStatus } = boundActionCreators
-  
+  const {
+    createNode,
+    deleteNodes,
+    touchNode,
+    setPluginStatus,
+  } = boundActionCreators
+
   // Fetch articles.
   console.time(`Fetch Contentful data`)
   console.log(`Starting to fetch data from Contentful`)
@@ -25,50 +30,48 @@ exports.sourceNodes = async (
     space: spaceId,
     accessToken,
   })
-  // the structure of the sync payload is a bit different
-  // all field will be in this format { fieldName: {'locale': value} } so we need to get the space and its default local
-  // this can be extended later to support multiple locals
+  // The sync API puts the locale in all fields in this format { fieldName:
+  // {'locale': value} } so we need to get the space and its default local.
+  //
+  // We'll extend this soon to support multiple locales.
   let space
   let defaultLocale = `en-US`
   try {
     console.log(`Fetching default locale`)
     space = await client.getSpace()
-    defaultLocale = _.find(space.locales, { 'default': true }).code
+    defaultLocale = _.find(space.locales, { default: true }).code
     console.log(`default local is : ${defaultLocale}`)
   } catch (e) {
-    console.log(`can't get space`)
-    // TODO maybe return here
+    console.log(
+      `Accessing your Contentful space failed. Perhaps you're offline or the spaceId/accessToken is incorrect.`
+    )
+    // TODO perhaps continue if there's cached data? That would let
+    // someone develop a contentful site even if not connected to the internet.
+    // For prod builds though always fail if we can't get the latest data.
+    process.exit(1)
   }
 
-  // Get sync token if it exists
+  // Get sync token if it exists.
   let syncToken
-  let lastSyncedData = { entries: [], assets: [], deletedEntries: [], deletedAssets: [], nextSyncToken: null }
   if (
     store.getState().status.plugins &&
     store.getState().status.plugins[`gatsby-source-contentful`]
   ) {
-    lastSyncedData = store.getState().status.plugins[`gatsby-source-contentful`].status
-      .lastSyncedData
-    syncToken = lastSyncedData.nextSyncToken
+    syncToken = store.getState().status.plugins[`gatsby-source-contentful`]
+      .status.syncToken
   }
 
-  // The SDK will map the entities to the following object
-  // {
-  //  entries,
-  //  assets,
-  //  deletedEntries,
-  //  deletedAssets
-  // }
   let currentSyncData
   try {
     let query = syncToken ? { nextSyncToken: syncToken } : { initial: true }
-    currentSyncData = await client.sync(query) 
+    currentSyncData = await client.sync(query)
   } catch (e) {
-    currentSyncData = { entries: [], assets: [], deletedEntries: [], deletedAssets:[] }
     console.log(`error fetching contentful data`, e)
+    process.exit(1)
   }
 
-  // We fetch content types normaly since we don't receive it in the sync data
+  // We need to fetch content types with the non-sync API as the sync API
+  // doesn't support this.
   let contentTypes
   try {
     contentTypes = await pagedGet(client, `getContentTypes`)
@@ -78,47 +81,39 @@ exports.sourceNodes = async (
   console.log(`contentTypes fetched`, contentTypes.items.length)
 
   const contentTypeItems = contentTypes.items
-  // remove outdated entries 
-  lastSyncedData.entries.filter(entry => {
-    return _.find(
-      currentSyncData.entries, (newEntry) => newEntry.sys.id === entry.sys.id
-      ||
-        _.find(
-          currentSyncData.deletedEntries, (deletedEntry) => deletedEntry.sys.id === entry.sys.id
-        )
-    )
-  })
 
-  // merge entries
-  lastSyncedData.entries = lastSyncedData.entries.concat(currentSyncData.entries)
-  let entryList = contentTypeItems.map(contentType => {
-    return lastSyncedData.entries.filter(entry => entry.sys.contentType.sys.id === contentType.sys.id )
-  })
+  // Remove deleted entries & assets.
+  // TODO figure out if entries referencing now deleted entries/assets
+  // are "updated" so will get updated here.
+  deleteNodes(currentSyncData.deletedEntries.map(e => e.sys.id))
+  deleteNodes(currentSyncData.deletedAssets.map(e => e.sys.id))
 
-  lastSyncedData.assets.filter(asset => {
-    return _.find(
-        currentSyncData.assets, (newAsset) => newAsset.sys.id === asset.sys.id
-      )
-      ||
-        _.find(
-          currentSyncData.deletedAssets, (deletedAsset) => deletedAsset.sys.id === asset.sys.id
-        )
-  })
+  const existingNodes = getNodes().filter(
+    n => n.internal.owner === `gatsby-source-contentful`
+  )
+  existingNodes.forEach(n => touchNode(n.id))
+
+  let entryList = contentTypeItems.map(contentType =>
+    currentSyncData.entries.filter(
+      entry => entry.sys.contentType.sys.id === contentType.sys.id
+    )
+  )
+
+  const assets = currentSyncData.assets
 
-  lastSyncedData.assets = lastSyncedData.assets.concat(currentSyncData.assets)
-  let assets = lastSyncedData.assets
-  
-  console.log(`Total assets `, assets.length)
+  console.log(`Updated entries `, currentSyncData.entries.length)
+  console.log(`Deleted entries `, currentSyncData.deletedEntries.length)
   console.log(`Updated assets `, currentSyncData.assets.length)
   console.log(`Deleted assets `, currentSyncData.deletedAssets.length)
   console.timeEnd(`fetch Contentful data`)
- 
-  // update syncToken
-  lastSyncedData.nextSyncToken = currentSyncData.nextSyncToken
-  // cache the data
+
+  // Update syncToken
+  const nextSyncToken = currentSyncData.nextSyncToken
+
+  // Store our sync state for the next sync.
   setPluginStatus({
     status: {
-      lastSyncedData: lastSyncedData,
+      syncToken: nextSyncToken,
     },
   })
 
@@ -135,17 +130,40 @@ exports.sourceNodes = async (
     }
   })
 
- // entryList = entryList.map(entries => entries.map(entryItem => {
-   // entryItem.defaultLocale = defaultLocale
-   // return new Proxy(entryItem, localeProxyHandler)
- // }))
-// Build foreign reference map before starting to insert any nodes
+  // Build foreign reference map before starting to insert any nodes
   const foreignReferenceMap = processAPIData.buildForeignReferenceMap({
     contentTypeItems,
     entryList,
     notResolvable,
     defaultLocale,
   })
+
+  // Update existing entry nodes that weren't updated but that need reverse
+  // links added.
+  const newOrUpdatedEntries = []
+  entryList.forEach(entries =>
+    entries.forEach(entry => newOrUpdatedEntries.push(entry.sys.id))
+  )
+  Object.keys(foreignReferenceMap)
+  existingNodes
+    .filter(n => _.includes(newOrUpdatedEntries, n.id))
+    .forEach(n => {
+      if (foreignReferenceMap[n.id]) {
+        foreignReferenceMap[n.id].forEach(foreignReference => {
+          // Add reverse links
+          if (n[foreignReference.name]) {
+            n[foreignReference.name].push(foreignReference.id)
+            // It might already be there so we'll uniquify after pushing.
+            n[foreignReference.name] = _.uniq(n[foreignReference.name])
+          } else {
+            // If is one foreign reference, there can always be many.
+            // Best to be safe and put it in an array to start with.
+            n[foreignReference.name] = [foreignReference.id]
+          }
+        })
+      }
+    })
+
   contentTypeItems.forEach((contentTypeItem, i) => {
     processAPIData.createContentTypeNodes({
       contentTypeItem,
@@ -170,22 +188,32 @@ exports.sourceNodes = async (
  * The first call will have no aggregated response. Subsequent calls will
  * concatenate the new responses to the original one.
  */
-function pagedGet (client, method, query = {}, skip = 0, pageLimit = 1000, aggregatedResponse = null) {
-  return client[method]({
-    ...query,
-    skip: skip,
-    limit: pageLimit,
-    order: `sys.createdAt`,
-  })
-  .then((response) => {
-    if (!aggregatedResponse) {
-      aggregatedResponse = response
-    } else {
-      aggregatedResponse.items = aggregatedResponse.items.concat(response.items)
-    }
-    if (skip + pageLimit <= response.total) {
-      return pagedGet(client, method, skip + pageLimit, aggregatedResponse)
-    }
-    return aggregatedResponse
-  })
+function pagedGet(
+  client,
+  method,
+  query = {},
+  skip = 0,
+  pageLimit = 1000,
+  aggregatedResponse = null
+) {
+  return client
+    [method]({
+      ...query,
+      skip: skip,
+      limit: pageLimit,
+      order: `sys.createdAt`,
+    })
+    .then(response => {
+      if (!aggregatedResponse) {
+        aggregatedResponse = response
+      } else {
+        aggregatedResponse.items = aggregatedResponse.items.concat(
+          response.items
+        )
+      }
+      if (skip + pageLimit <= response.total) {
+        return pagedGet(client, method, skip + pageLimit, aggregatedResponse)
+      }
+      return aggregatedResponse
+    })
 }
diff --git a/packages/gatsby-source-contentful/src/process-api-data.js b/packages/gatsby-source-contentful/src/process-api-data.js
index 6332f9461d76f..3e26c9dccd461 100644
--- a/packages/gatsby-source-contentful/src/process-api-data.js
+++ b/packages/gatsby-source-contentful/src/process-api-data.js
@@ -18,8 +18,8 @@ exports.buildForeignReferenceMap = ({
     entryList[i].forEach(entryItem => {
       const entryItemFields = entryItem.fields
       Object.keys(entryItemFields).forEach(entryItemFieldKey => {
-        let entryItemFieldValue = entryItemFields[entryItemFieldKey][defaultLocale]
-        console.log(`${entryItemFieldKey} => ${String(entryItemFieldValue)}`)
+        let entryItemFieldValue =
+          entryItemFields[entryItemFieldKey][defaultLocale]
         if (Array.isArray(entryItemFieldValue)) {
           if (
             entryItemFieldValue[0].sys &&
@@ -120,7 +120,8 @@ exports.createContentTypeNodes = ({
 
     // Add linkages to other nodes based on foreign references
     Object.keys(entryItemFields).forEach(entryItemFieldKey => {
-      const entryItemFieldValue = entryItemFields[entryItemFieldKey]
+      const entryItemFieldValue =
+        entryItemFields[entryItemFieldKey][defaultLocale]
       if (Array.isArray(entryItemFieldValue)) {
         if (
           entryItemFieldValue[0].sys &&
@@ -168,10 +169,22 @@ exports.createContentTypeNodes = ({
       children: [],
       internal: {
         type: `${makeTypeName(contentTypeItemId)}`,
-        mediaType: `application/json`,
+        mediaType: `application/x-contentful`,
       },
     }
 
+    // Use default locale field.
+    Object.keys(entryItemFields).forEach(entryItemFieldKey => {
+      // Ignore fields with "___node" as they're already handled
+      // and won't be a text field.
+      if (entryItemFieldKey.split(`___`).length > 1) {
+        return
+      }
+
+      entryItemFields[entryItemFieldKey] =
+        entryItemFields[entryItemFieldKey][defaultLocale]
+    })
+
     // Replace text fields with text nodes so we can process their markdown
     // into HTML.
     Object.keys(entryItemFields).forEach(entryItemFieldKey => {
@@ -188,11 +201,10 @@ exports.createContentTypeNodes = ({
             : f.id) === entryItemFieldKey
       ).type
       if (fieldType === `Text`) {
-        console.log(entryItemFields[entryItemFieldKey])
         entryItemFields[`${entryItemFieldKey}___NODE`] = createTextNode(
           entryNode,
           entryItemFieldKey,
-          entryItemFields[entryItemFieldKey][defaultLocale],
+          entryItemFields[entryItemFieldKey],
           createNode
         )
 
@@ -242,7 +254,6 @@ exports.createAssetNodes = ({ assetItem, createNode, defaultLocale }) => {
     title: assetItem.fields.title[defaultLocale],
     description: assetItem.fields.description[defaultLocale],
   }
-  console.log(assetItem)
   const assetNode = {
     id: assetItem.sys.id,
     parent: `__SOURCE__`,
diff --git a/packages/gatsby-source-contentful/src/proxy-handlers.js b/packages/gatsby-source-contentful/src/proxy-handlers.js
index ec476dea351c5..5f89a03b3b1aa 100644
--- a/packages/gatsby-source-contentful/src/proxy-handlers.js
+++ b/packages/gatsby-source-contentful/src/proxy-handlers.js
@@ -7,7 +7,4 @@ const localeProxyHandler = {
   },
 }
 
-
 exports.localeProxyHandler = localeProxyHandler
-
-
diff --git a/packages/gatsby/src/cache-dir/develop-static-entry.js b/packages/gatsby/src/cache-dir/develop-static-entry.js
index 9f8819ea6d5dc..05e8409ec308e 100644
--- a/packages/gatsby/src/cache-dir/develop-static-entry.js
+++ b/packages/gatsby/src/cache-dir/develop-static-entry.js
@@ -13,7 +13,6 @@ try {
 }
 
 module.exports = (locals, callback) => {
-
   // const apiRunner = require(`${directory}/.cache/api-runner-ssr`)
   let headComponents = []
   let preBodyComponents = []
diff --git a/packages/gatsby/src/redux/index.js b/packages/gatsby/src/redux/index.js
index 398269eae9ea5..50cad0114fc35 100644
--- a/packages/gatsby/src/redux/index.js
+++ b/packages/gatsby/src/redux/index.js
@@ -64,7 +64,10 @@ emitter.onAny(() => {
 
 exports.emitter = emitter
 exports.store = store
-exports.getNodes = () => _.values(store.getState().nodes)
+exports.getNodes = () => {
+  let nodes = _.values(store.getState().nodes)
+  return nodes ? nodes : []
+}
 const getNode = id => store.getState().nodes[id]
 exports.getNode = getNode
 exports.hasNodeChanged = (id, digest) => {
diff --git a/packages/gatsby/src/utils/develop.js b/packages/gatsby/src/utils/develop.js
index e057228270936..d1b4b5de4746a 100644
--- a/packages/gatsby/src/utils/develop.js
+++ b/packages/gatsby/src/utils/develop.js
@@ -35,7 +35,7 @@ async function startServer(program) {
   // Start bootstrap process.
   await bootstrap(program)
   await developHtml(program).catch(err => {
-    console.log(err);
+    console.log(err)
     process.exit(1)
   })
 
@@ -65,7 +65,7 @@ async function startServer(program) {
     })
   )
 
-  app.use(express.static(__dirname + '/public'));
+  app.use(express.static(__dirname + `/public`))
 
   app.use(
     require(`webpack-dev-middleware`)(compiler, {
diff --git a/yarn.lock b/yarn.lock
index 74372a25eb10c..bc72fcba1ba87 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -87,6 +87,10 @@ ansi-regex@^2.0.0, ansi-regex@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
 
+ansi-regex@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
+
 ansi-styles@^2.2.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -231,8 +235,8 @@ async@^1.4.0, async@^1.5.0:
   resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
 
 async@^2.1.4:
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7"
+  version "2.5.0"
+  resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
   dependencies:
     lodash "^4.14.0"
 
@@ -1037,7 +1041,7 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24
     lodash "^4.2.0"
     to-fast-properties "^1.0.1"
 
-babylon@^6.13.0, babylon@^6.17.0, babylon@^6.17.2:
+babylon@^6.17.0, babylon@^6.17.2, babylon@^6.17.4:
   version "6.17.4"
   resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a"
 
@@ -1203,8 +1207,8 @@ camelcase@^4.1.0:
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
 
 caniuse-lite@^1.0.30000684:
-  version "1.0.30000693"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000693.tgz#c9c6298697c71fdf6cb13eefe8aa93926f2f8613"
+  version "1.0.30000694"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000694.tgz#1492dab7c10c608c9d37a723e6e3e7873e0ce94f"
 
 caseless@~0.12.0:
   version "0.12.0"
@@ -2002,8 +2006,8 @@ eslint-plugin-import@^2.3.0:
     read-pkg-up "^2.0.0"
 
 eslint-plugin-jsx-a11y@^5.0.3:
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.0.3.tgz#4a939f76ec125010528823331bf948cc573380b6"
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.1.0.tgz#4a829634344e7a90391a9fb0fbd19810737d79c5"
   dependencies:
     aria-query "^0.5.0"
     array-includes "^3.0.3"
@@ -2076,8 +2080,8 @@ eslint@^3.19.0:
     user-home "^2.0.0"
 
 eslint@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.0.0.tgz#7277c01437fdf41dccd168d5aa0e49b75ca1f260"
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.1.1.tgz#facbdfcfe3e0facd3a8b80dc98c4e6c13ae582df"
   dependencies:
     babel-code-frame "^6.22.0"
     chalk "^1.1.3"
@@ -2101,6 +2105,7 @@ eslint@^4.0.0:
     json-stable-stringify "^1.0.1"
     levn "^0.3.0"
     lodash "^4.17.4"
+    minimatch "^3.0.2"
     mkdirp "^0.5.1"
     natural-compare "^1.4.0"
     optionator "^0.8.2"
@@ -2785,8 +2790,8 @@ homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1:
     parse-passwd "^1.0.0"
 
 hosted-git-info@^2.1.4:
-  version "2.4.2"
-  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
+  version "2.5.0"
+  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
 
 html-encoding-sniffer@^1.0.1:
   version "1.0.1"
@@ -3209,14 +3214,14 @@ isstream@~0.1.2:
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
 
 istanbul-api@^1.1.1:
-  version "1.1.9"
-  resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.9.tgz#2827920d380d4286d857d57a2968a841db8a7ec8"
+  version "1.1.10"
+  resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.10.tgz#f27e5e7125c8de13f6a80661af78f512e5439b2b"
   dependencies:
     async "^2.1.4"
     fileset "^2.0.2"
     istanbul-lib-coverage "^1.1.1"
     istanbul-lib-hook "^1.0.7"
-    istanbul-lib-instrument "^1.7.2"
+    istanbul-lib-instrument "^1.7.3"
     istanbul-lib-report "^1.1.1"
     istanbul-lib-source-maps "^1.2.1"
     istanbul-reports "^1.1.1"
@@ -3234,15 +3239,15 @@ istanbul-lib-hook@^1.0.7:
   dependencies:
     append-transform "^0.4.0"
 
-istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.2:
-  version "1.7.2"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.2.tgz#6014b03d3470fb77638d5802508c255c06312e56"
+istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.2, istanbul-lib-instrument@^1.7.3:
+  version "1.7.3"
+  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.3.tgz#925b239163eabdd68cc4048f52c2fa4f899ecfa7"
   dependencies:
     babel-generator "^6.18.0"
     babel-template "^6.16.0"
     babel-traverse "^6.18.0"
     babel-types "^6.18.0"
-    babylon "^6.13.0"
+    babylon "^6.17.4"
     istanbul-lib-coverage "^1.1.1"
     semver "^5.3.0"
 
@@ -4090,8 +4095,8 @@ nopt@~3.0.6:
     abbrev "1"
 
 normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5:
-  version "2.3.8"
-  resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb"
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
   dependencies:
     hosted-git-info "^2.1.4"
     is-builtin-module "^1.0.0"
@@ -4111,8 +4116,8 @@ npm-run-path@^2.0.0:
     path-key "^2.0.0"
 
 npmlog@^4.0.2, npmlog@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.0.tgz#dc59bee85f64f00ed424efb2af0783df25d1c0b5"
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
   dependencies:
     are-we-there-yet "~1.1.2"
     console-control-strings "~1.1.0"
@@ -5186,11 +5191,11 @@ string-width@^1.0.1, string-width@^1.0.2:
     strip-ansi "^3.0.0"
 
 string-width@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e"
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0"
   dependencies:
     is-fullwidth-code-point "^2.0.0"
-    strip-ansi "^3.0.0"
+    strip-ansi "^4.0.0"
 
 string_decoder@~1.0.0:
   version "1.0.3"
@@ -5208,6 +5213,12 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1:
   dependencies:
     ansi-regex "^2.0.0"
 
+strip-ansi@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
+  dependencies:
+    ansi-regex "^3.0.0"
+
 strip-ansi@~0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
@@ -5524,7 +5535,7 @@ utils-merge@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
 
-uuid@3.0.1, uuid@^3.0.0, uuid@^3.0.1:
+uuid@3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
 
@@ -5532,6 +5543,10 @@ uuid@^2.0.1:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
 
+uuid@^3.0.0, uuid@^3.0.1:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
+
 uws@8.14.0:
   version "8.14.0"
   resolved "https://registry.yarnpkg.com/uws/-/uws-8.14.0.tgz#acc1488d13ecb23fe2f942a7eafb06681fa91431"