/**
 * Webpack dev-server block.
 *
 * @see https://github.com/webpack/webpack-dev-server
 */

module.exports = devServer

devServer.proxy = proxy
devServer.reactHot = reactHot

/**
 * @param {object} [options]    See https://webpack.github.io/docs/configuration.html#devserver
 * @param {bool}   [options.historyApiFallback]
 * @param {bool}   [options.hot]
 * @param {bool}   [options.inline]
 * @param {string|string[]} [entry]   Defaults to 'webpack/hot/only-dev-server'
 * @return {Function}
 */
function devServer (options, entry) {
  options = options || {}
  if (options && (typeof options === 'string' || Array.isArray(options))) {
    entry = options
    options = {}
  }

  if (!Array.isArray(entry)) {
    entry = entry ? [ entry ] : []
  }

  return Object.assign((context) => {
    context.devServer = context.devServer || { entry: [], options: {} }
    context.devServer.entry = context.devServer.entry.concat(entry)
    context.devServer.options = Object.assign({}, context.devServer.options, options)

    return {}
  }, { post: postConfig })
}

function postConfig (context, config) {
  const entryPointsToAdd = context.devServer.entry.length > 0
    ? context.devServer.entry
    : [ 'webpack/hot/only-dev-server' ]

  return {
    devServer: Object.assign({
      hot: true,
      historyApiFallback: true,
      inline: true
    }, context.devServer.options),
    entry: addDevEntryToAll(config.entry || {}, entryPointsToAdd),
    plugins: [
      new context.webpack.HotModuleReplacementPlugin()
    ]
  }
}

function addDevEntryToAll (presentEntryPoints, devServerEntry) {
  const newEntryPoints = {}

  Object.keys(presentEntryPoints).forEach((chunkName) => {
    // It's fine to just set the `devServerEntry`, instead of concat()-ing the present ones.
    // Will be concat()-ed by webpack-merge (see `createConfig()`)
    newEntryPoints[ chunkName ] = devServerEntry
  })

  return newEntryPoints
}

/**
 * @param {object} proxyRoutes    { <path>: <target URL> }
 * @return {Function}
 * @see http://webpack.github.io/docs/webpack-dev-server.html#proxy
 */
function proxy (proxyRoutes) {
  return () => ({
    devServer: {
      proxy: proxyRoutes
    }
  })
}

/**
 * For adding the react-hot-loader to the JS loaders. Only when using
 * react-hot-loader before version 3.
 * @param {object} [options]
 * @param {RegExp, Function, string}  [options.exclude]   Directories to exclude.
 * @return {Function}
 */
function reactHot (options) {
  options = options || {}
  const exclude = options.exclude || /\/node_modules\//

  return (context) => ({
    module: {
      loaders: [{
        test: context.fileType('application/javascript'),
        exclude: Array.isArray(exclude) ? exclude : [ exclude ],
        loaders: [ 'react-hot' ]
      }]
    }
  })
}

@@ -753,38 +753,44 @@
 %0A%0A  
-return Object.assign((context)
+const setter = context =%3E prevConfig
  =%3E 
@@ -1029,22 +1029,61 @@
  return 
-%7B
+prevConfig%0A  
 %7D%0A
+%0A
   
-%7D
+return Object.assign(setter
 , %7B post
@@ -1131,22 +1131,23 @@
 ontext, 
-config
+helpers
 ) %7B%0A  co
@@ -1284,18 +1284,61 @@
  return 
-%7B%0A
+prevConfig =%3E %7B%0A    return helpers.merge(%7B%0A  
     devS
@@ -1360,16 +1360,18 @@
 ssign(%7B%0A
+  
       ho
@@ -1385,16 +1385,18 @@
 ,%0A      
+  
 historyA
@@ -1419,16 +1419,18 @@
 ,%0A      
+ 
+ 
 inline: 
@@ -1434,16 +1434,18 @@
 e: true%0A
+  
     %7D, c
@@ -1471,16 +1471,18 @@
 tions),%0A
+  
     entr
@@ -1501,17 +1501,21 @@
 ryToAll(
-c
+prevC
 onfig.en
@@ -1548,16 +1548,18 @@
 d),%0A    
+  
 plugins:
@@ -1561,16 +1561,18 @@
 gins: %5B%0A
+  
       ne
@@ -1622,17 +1622,38 @@
 n()%0A    
-%5D
+  %5D%0A    %7D)(prevConfig)
 %0A  %7D%0A%7D%0A%0A
@@ -2245,21 +2245,50 @@
 return (
-) =%3E 
+context, helpers) =%3E helpers.merge
 (%7B%0A    d
@@ -2721,52 +2721,42 @@
 text
-) =%3E (%7B%0A    module: %7B%0A      l
+, helpers) =%3E helpers.addL
 oader
-s: %5B
+(
 %7B%0A
-    
     
@@ -2805,20 +2805,16 @@
 ript'),%0A
-    
     excl
@@ -2870,20 +2870,16 @@
  %5D,%0A    
- 
-   
 loaders:
@@ -2899,23 +2899,8 @@
 ' %5D%0A
-      %7D%5D%0A    %7D%0A
   %7D)

Update dev-server block to use new API