diff --git a/addons/links/README.md b/addons/links/README.md index 9c34458a53cb..b2c6d63d53ff 100644 --- a/addons/links/README.md +++ b/addons/links/README.md @@ -43,7 +43,7 @@ linkTo('Toggle') // Links to the first story in the 'Toggle' kind With that, you can link an event in a component to any story in the Storybook. - First parameter is the the story kind name (what you named with `storiesOf`). --   Second (optional) parameter is the story name (what you named with `.add`). If the second parameter is omitted, the link will point to the first story in the given kind. +-   Second (optional) parameter is the story name (what you named with `.add`). If the second parameter is omitted, the link will point to the first story in the given kind. > You can also pass a function instead for any of above parameter. That function accepts arguments emitted by the event and it should return a string.
> Have a look at [PR86](https://github.com/kadirahq/react-storybook/pull/86) for more information. diff --git a/app/react-native/package.json b/app/react-native/package.json index d2d78b903fb1..5716932f1b31 100644 --- a/app/react-native/package.json +++ b/app/react-native/package.json @@ -53,6 +53,7 @@ "file-loader": "^0.11.1", "find-cache-dir": "^1.0.0", "global": "^4.3.2", + "html-webpack-plugin": "^2.30.1", "json-loader": "^0.5.4", "json5": "^0.5.1", "postcss-loader": "^2.0.5", diff --git a/app/react-native/src/preview/index.js b/app/react-native/src/preview/index.js index ece4bd2319c3..2529253e331c 100644 --- a/app/react-native/src/preview/index.js +++ b/app/react-native/src/preview/index.js @@ -91,9 +91,11 @@ export default class Preview { this._sendGetCurrentStory(); // finally return the preview component - return params.onDeviceUI - ? - : ; + return params.onDeviceUI ? ( + + ) : ( + + ); }; } diff --git a/app/react-native/src/server/config/webpack.config.js b/app/react-native/src/server/config/webpack.config.js index ddd38a20d004..0e2f5c2ce09e 100644 --- a/app/react-native/src/server/config/webpack.config.js +++ b/app/react-native/src/server/config/webpack.config.js @@ -1,9 +1,10 @@ import path from 'path'; import webpack from 'webpack'; import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; import { OccurenceOrderPlugin, includePaths, excludePaths } from './utils'; -const config = { +const getConfig = options => ({ devtool: '#cheap-module-eval-source-map', entry: { manager: [require.resolve('../../manager')], @@ -14,6 +15,13 @@ const config = { publicPath: '/', }, plugins: [ + new HtmlWebpackPlugin({ + filename: 'index.html', + data: { + options: JSON.stringify(options), + }, + template: require.resolve('../index.html.ejs'), + }), new OccurenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), new CaseSensitivePathsPlugin(), @@ -29,6 +37,6 @@ const config = { }, ], }, -}; +}); -export default config; +export default getConfig; diff --git a/app/react-native/src/server/config/webpack.config.prod.js b/app/react-native/src/server/config/webpack.config.prod.js index 841459f0c83f..b7c15794ef15 100644 --- a/app/react-native/src/server/config/webpack.config.prod.js +++ b/app/react-native/src/server/config/webpack.config.prod.js @@ -1,57 +1,69 @@ import path from 'path'; import webpack from 'webpack'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; import { OccurenceOrderPlugin, includePaths, excludePaths } from './utils'; -const config = { - bail: true, - devtool: '#cheap-module-source-map', - entry: { - manager: [path.resolve(__dirname, '../../manager')], - }, - output: { - path: path.join(__dirname, 'dist'), - filename: 'static/[name].bundle.js', - // Here we set the publicPath to ''. - // This allows us to deploy storybook into subpaths like GitHub pages. - // This works with css and image loaders too. - // This is working for storybook since, we don't use pushState urls and - // relative URLs works always. - publicPath: '/', - }, - plugins: [ - new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), - new webpack.optimize.DedupePlugin(), - new webpack.optimize.UglifyJsPlugin({ - compress: { - screw_ie8: true, - warnings: false, - }, - mangle: { - screw_ie8: true, - }, - output: { - comments: false, - screw_ie8: true, - }, - }), - ], - module: { - loaders: [ - { - test: /\.jsx?$/, - loader: require.resolve('babel-loader'), - query: require('./babel.prod.js'), // eslint-disable-line - include: includePaths, - exclude: excludePaths, - }, +const getConfig = options => { + const config = { + bail: true, + devtool: '#cheap-module-source-map', + entry: { + manager: [path.resolve(__dirname, '../../manager')], + }, + output: { + path: path.join(__dirname, 'dist'), + filename: 'static/[name].bundle.js', + // Here we set the publicPath to ''. + // This allows us to deploy storybook into subpaths like GitHub pages. + // This works with css and image loaders too. + // This is working for storybook since, we don't use pushState urls and + // relative URLs works always. + publicPath: '/', + }, + plugins: [ + new HtmlWebpackPlugin({ + filename: 'index.html', + data: { + options: JSON.stringify(options), + }, + template: require.resolve('../index.html.ejs'), + }), + new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), + new webpack.optimize.DedupePlugin(), + new webpack.optimize.UglifyJsPlugin({ + compress: { + screw_ie8: true, + warnings: false, + }, + mangle: { + screw_ie8: true, + }, + output: { + comments: false, + screw_ie8: true, + }, + }), ], - }, -}; + module: { + loaders: [ + { + test: /\.jsx?$/, + loader: require.resolve('babel-loader'), + query: require('./babel.prod.js'), // eslint-disable-line + include: includePaths, + exclude: excludePaths, + }, + ], + }, + }; -// Webpack 2 doesn't have a OccurenceOrderPlugin plugin in the production mode. -// But webpack 1 has it. That's why we do this. -if (OccurenceOrderPlugin) { - config.plugins.unshift(new OccurenceOrderPlugin()); -} + // Webpack 2 doesn't have a OccurenceOrderPlugin plugin in the production mode. + // But webpack 1 has it. That's why we do this. + if (OccurenceOrderPlugin) { + config.plugins.unshift(new OccurenceOrderPlugin()); + } + + return config; +}; -export default config; +export default getConfig; diff --git a/app/react-native/src/server/index.html.ejs b/app/react-native/src/server/index.html.ejs new file mode 100644 index 000000000000..84b46693e476 --- /dev/null +++ b/app/react-native/src/server/index.html.ejs @@ -0,0 +1,34 @@ + + + + + + Storybook for React + + + +
+ + + diff --git a/app/react-native/src/server/index.html.js b/app/react-native/src/server/index.html.js deleted file mode 100644 index e3bc622c4e2f..000000000000 --- a/app/react-native/src/server/index.html.js +++ /dev/null @@ -1,41 +0,0 @@ -import url from 'url'; - -export default function(publicPath, options) { - return ` - - - - - - Storybook for React - - - -
- - - - - `; -} diff --git a/app/react-native/src/server/middleware.js b/app/react-native/src/server/middleware.js index 10ec0c03c14a..3aa404d17d24 100644 --- a/app/react-native/src/server/middleware.js +++ b/app/react-native/src/server/middleware.js @@ -7,7 +7,6 @@ import webpackHotMiddleware from 'webpack-hot-middleware'; import baseConfig from './config/webpack.config'; import baseProductionConfig from './config/webpack.config.prod'; import loadConfig from './config'; -import getIndexHtml from './index.html'; function getMiddleware(configDir) { const middlewarePath = path.resolve(configDir, 'middleware.js'); @@ -26,7 +25,7 @@ export default function({ projectDir, configDir, ...options }) { // custom `.babelrc` file and `webpack.config.js` files const environment = options.environment || 'DEVELOPMENT'; const isProd = environment === 'PRODUCTION'; - const currentWebpackConfig = isProd ? baseProductionConfig : baseConfig; + const currentWebpackConfig = isProd ? baseProductionConfig(options) : baseConfig(options); const config = loadConfig(environment, currentWebpackConfig, projectDir, configDir); // remove the leading '/' @@ -53,12 +52,8 @@ export default function({ projectDir, configDir, ...options }) { } router.get('/', (req, res) => { - res.send( - getIndexHtml(publicPath, { - manualId: options.manualId, - secured: options.secured, - }) - ); + res.set('Content-Type', 'text/html'); + res.sendFile(path.join(`${__dirname}/public/index.html`)); }); return router; diff --git a/app/react/package.json b/app/react/package.json index 196b9788192e..af55142edbb0 100644 --- a/app/react/package.json +++ b/app/react/package.json @@ -50,6 +50,7 @@ "glamor": "^2.20.40", "glamorous": "^4.1.2", "global": "^4.3.2", + "html-webpack-plugin": "^2.30.1", "json-loader": "^0.5.4", "json-stringify-safe": "^5.0.1", "json5": "^0.5.1", diff --git a/app/react/src/client/preview/client_api.test.js b/app/react/src/client/preview/client_api.test.js index 8a83cbcba977..5936fe3337ab 100644 --- a/app/react/src/client/preview/client_api.test.js +++ b/app/react/src/client/preview/client_api.test.js @@ -80,7 +80,10 @@ describe('preview.client_api', () => { }, }); - api.storiesOf('none', module).aa().bb(); + api + .storiesOf('none', module) + .aa() + .bb(); expect(data).toEqual(['foo', 'bar']); }); diff --git a/app/react/src/server/build.js b/app/react/src/server/build.js index 884b9a7188a7..99df39a8f57b 100755 --- a/app/react/src/server/build.js +++ b/app/react/src/server/build.js @@ -9,9 +9,7 @@ import shelljs from 'shelljs'; import packageJson from '../../package.json'; import getBaseConfig from './config/webpack.config.prod'; import loadConfig from './config'; -import getIndexHtml from './index.html'; -import getIframeHtml from './iframe.html'; -import { getPreviewHeadHtml, getManagerHeadHtml, parseList, getEnvConfig } from './utils'; +import { parseList, getEnvConfig } from './utils'; process.env.NODE_ENV = process.env.NODE_ENV || 'production'; @@ -86,19 +84,4 @@ webpack(config).run((err, stats) => { stats.hasErrors() && stats.toJson().errors.forEach(e => logger.error(e)); process.exit(1); } - - const data = { - publicPath: config.output.publicPath, - assets: stats.toJson().assetsByChunkName, - }; - - // Write both the storybook UI and IFRAME HTML files to destination path. - fs.writeFileSync( - path.resolve(outputDir, 'index.html'), - getIndexHtml({ ...data, headHtml: getManagerHeadHtml(configDir) }) - ); - fs.writeFileSync( - path.resolve(outputDir, 'iframe.html'), - getIframeHtml({ ...data, headHtml: getPreviewHeadHtml(configDir) }) - ); }); diff --git a/app/react/src/server/config/utils.js b/app/react/src/server/config/utils.js index 8cb15c640d93..0236481efd78 100644 --- a/app/react/src/server/config/utils.js +++ b/app/react/src/server/config/utils.js @@ -23,11 +23,15 @@ export function loadEnv(options = {}) { PUBLIC_URL: JSON.stringify(options.production ? '.' : ''), }; - Object.keys(process.env).filter(name => /^STORYBOOK_/.test(name)).forEach(name => { - env[name] = JSON.stringify(process.env[name]); - }); + Object.keys(process.env) + .filter(name => /^STORYBOOK_/.test(name)) + .forEach(name => { + env[name] = JSON.stringify(process.env[name]); + }); return { 'process.env': env, }; } + +export const getConfigDir = () => process.env.SBCONFIG_CONFIG_DIR || './.storybook'; diff --git a/app/react/src/server/config/webpack.config.js b/app/react/src/server/config/webpack.config.js index 24eacd0bf24b..d90af4f9c919 100644 --- a/app/react/src/server/config/webpack.config.js +++ b/app/react/src/server/config/webpack.config.js @@ -1,9 +1,20 @@ import path from 'path'; import webpack from 'webpack'; import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; import WatchMissingNodeModulesPlugin from './WatchMissingNodeModulesPlugin'; -import { includePaths, excludePaths, nodeModulesPaths, loadEnv, nodePaths } from './utils'; + +import { + getConfigDir, + includePaths, + excludePaths, + nodeModulesPaths, + loadEnv, + nodePaths, +} from './utils'; import babelLoaderConfig from './babel'; +import { getPreviewHeadHtml, getManagerHeadHtml } from '../utils'; +import { version } from '../../../package.json'; export default function() { const config = { @@ -22,6 +33,23 @@ export default function() { publicPath: '/', }, plugins: [ + new HtmlWebpackPlugin({ + filename: 'index.html', + chunks: ['manager'], + data: { + managerHead: getManagerHeadHtml(getConfigDir()), + version, + }, + template: require.resolve('../index.html.ejs'), + }), + new HtmlWebpackPlugin({ + filename: 'iframe.html', + excludeChunks: ['manager'], + data: { + previewHead: getPreviewHeadHtml(getConfigDir()), + }, + template: require.resolve('../iframe.html.ejs'), + }), new webpack.DefinePlugin(loadEnv()), new webpack.HotModuleReplacementPlugin(), new CaseSensitivePathsPlugin(), diff --git a/app/react/src/server/config/webpack.config.prod.js b/app/react/src/server/config/webpack.config.prod.js index 989b1adca7ad..12a2793137f6 100644 --- a/app/react/src/server/config/webpack.config.prod.js +++ b/app/react/src/server/config/webpack.config.prod.js @@ -1,7 +1,10 @@ import path from 'path'; import webpack from 'webpack'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; import babelLoaderConfig from './babel.prod'; -import { includePaths, excludePaths, loadEnv, nodePaths } from './utils'; +import { getConfigDir, includePaths, excludePaths, loadEnv, nodePaths } from './utils'; +import { getPreviewHeadHtml, getManagerHeadHtml } from '../utils'; +import { version } from '../../../package.json'; export default function() { const entries = { @@ -23,6 +26,23 @@ export default function() { publicPath: '', }, plugins: [ + new HtmlWebpackPlugin({ + filename: 'index.html', + chunks: ['manager'], + data: { + managerHead: getManagerHeadHtml(getConfigDir()), + version, + }, + template: require.resolve('../index.html.ejs'), + }), + new HtmlWebpackPlugin({ + filename: 'iframe.html', + excludeChunks: ['manager'], + data: { + previewHead: getPreviewHeadHtml(getConfigDir()), + }, + template: require.resolve('../iframe.html.ejs'), + }), new webpack.DefinePlugin(loadEnv({ production: true })), new webpack.optimize.UglifyJsPlugin({ compress: { diff --git a/app/react/src/server/iframe.html.ejs b/app/react/src/server/iframe.html.ejs new file mode 100644 index 000000000000..55723c849e3d --- /dev/null +++ b/app/react/src/server/iframe.html.ejs @@ -0,0 +1,19 @@ + + + + + + + + Storybook + <%= htmlWebpackPlugin.options.data.previewHead %> + + +
+
+ + diff --git a/app/react/src/server/iframe.html.js b/app/react/src/server/iframe.html.js deleted file mode 100644 index 9b9fdc020f51..000000000000 --- a/app/react/src/server/iframe.html.js +++ /dev/null @@ -1,82 +0,0 @@ -import url from 'url'; - -const getExtensionForFilename = filename => /.+\.(\w+)$/.exec(filename)[1]; - -// assets.preview will be: -// - undefined -// - string e.g. 'static/preview.9adbb5ef965106be1cc3.bundle.js' -// - array of strings e.g. -// [ 'static/preview.9adbb5ef965106be1cc3.bundle.js', -// 'preview.0d2d3d845f78399fd6d5e859daa152a9.css', -// 'static/preview.9adbb5ef965106be1cc3.bundle.js.map', -// 'preview.0d2d3d845f78399fd6d5e859daa152a9.css.map' ] -export const urlsFromAssets = assets => { - if (!assets) { - return { - js: ['static/preview.bundle.js'], - css: [], - }; - } - - const urls = { - js: [], - css: [], - }; - - Object.keys(assets) - // Don't load the manager script in the iframe - .filter(key => key !== 'manager') - .forEach(key => { - let assetList = assets[key]; - if (!Array.isArray(assetList)) { - assetList = [assetList]; - } - assetList - .filter(assetUrl => { - const extension = getExtensionForFilename(assetUrl); - const isMap = extension === 'map'; - const isSupportedExtension = Boolean(urls[extension]); - return isSupportedExtension && !isMap; - }) - .forEach(assetUrl => { - urls[getExtensionForFilename(assetUrl)].push(assetUrl); - }); - }); - - return urls; -}; - -export default function({ assets, publicPath, headHtml }) { - const urls = urlsFromAssets(assets); - - const cssTags = urls.css - .map(u => ``) - .join('\n'); - const scriptTags = urls.js - .map(u => ``) - .join('\n'); - - return ` - - - - - - - - Storybook - ${headHtml} - ${cssTags} - - -
-
- ${scriptTags} - - - `; -} diff --git a/app/react/src/server/iframe.html.test.js b/app/react/src/server/iframe.html.test.js deleted file mode 100644 index b57e2b9bba04..000000000000 --- a/app/react/src/server/iframe.html.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { urlsFromAssets } from './iframe.html'; - -describe('server.urlsFromAssets', () => { - it('should return the default when there are no assets', () => { - expect(urlsFromAssets()).toEqual({ - js: ['static/preview.bundle.js'], - css: [], - }); - }); - - it('should return multiple assets', () => { - const fixture = { - manager: 'static/manager.a.bundle.js', - preview: ['static/preview.x.bundle.js', 'static/preview.y.css', 'static/preview.y.css.map'], - }; - expect(urlsFromAssets(fixture)).toEqual({ - js: ['static/preview.x.bundle.js'], - css: ['static/preview.y.css'], - }); - }); - - it('should not return non-js or non-css assets', () => { - const fixture = { - 'some-thing.svg': 'some-thing.svg', - }; - expect(urlsFromAssets(fixture)).toEqual({ - js: [], - css: [], - }); - }); -}); diff --git a/app/react/src/server/index.html.ejs b/app/react/src/server/index.html.ejs new file mode 100644 index 000000000000..397aaf41d52e --- /dev/null +++ b/app/react/src/server/index.html.ejs @@ -0,0 +1,44 @@ + + + + + + + + Storybook + + <%= htmlWebpackPlugin.options.data.managerHead %> + + + +
+ + diff --git a/app/react/src/server/index.html.js b/app/react/src/server/index.html.js deleted file mode 100644 index 425b53601cfa..000000000000 --- a/app/react/src/server/index.html.js +++ /dev/null @@ -1,70 +0,0 @@ -import url from 'url'; -import { version } from '../../package.json'; - -// assets.manager will be: -// - undefined -// - string e.g. 'static/manager.9adbb5ef965106be1cc3.bundle.js' -// - array of strings e.g. -// assets.manager will be something like: -// [ 'static/manager.c6e6350b6eb01fff8bad.bundle.js', -// 'static/manager.c6e6350b6eb01fff8bad.bundle.js.map' ] -const managerUrlsFromAssets = assets => { - if (!assets || !assets.manager) { - return { - js: 'static/manager.bundle.js', - }; - } - - if (typeof assets.manager === 'string') { - return { - js: assets.manager, - }; - } - - return { - js: assets.manager.find(filename => filename.match(/\.js$/)), - css: assets.manager.find(filename => filename.match(/\.css$/)), - }; -}; - -export default function({ assets, publicPath, headHtml }) { - const managerUrls = managerUrlsFromAssets(assets); - - return ` - - - - - - - - Storybook - - ${headHtml} - - -
- - - - `; -} diff --git a/app/react/src/server/middleware.js b/app/react/src/server/middleware.js index 7ebeb18be477..e5b0ed9b8e4a 100644 --- a/app/react/src/server/middleware.js +++ b/app/react/src/server/middleware.js @@ -1,12 +1,11 @@ +import path from 'path'; import { Router } from 'express'; import webpack from 'webpack'; import webpackDevMiddleware from 'webpack-dev-middleware'; import webpackHotMiddleware from 'webpack-hot-middleware'; import getBaseConfig from './config/webpack.config'; import loadConfig from './config'; -import getIndexHtml from './index.html'; -import getIframeHtml from './iframe.html'; -import { getPreviewHeadHtml, getManagerHeadHtml, getMiddleware } from './utils'; +import { getMiddleware } from './utils'; let webpackResolve = () => {}; let webpackReject = () => {}; @@ -44,19 +43,14 @@ export default function(configDir) { middlewareFn(router); webpackDevMiddlewareInstance.waitUntilValid(stats => { - const data = { - publicPath: config.output.publicPath, - assets: stats.toJson().assetsByChunkName, - }; - router.get('/', (req, res) => { - const headHtml = getManagerHeadHtml(configDir); - res.send(getIndexHtml({ publicPath, headHtml })); + res.set('Content-Type', 'text/html'); + res.sendFile(path.join(`${__dirname}/public/index.html`)); }); router.get('/iframe.html', (req, res) => { - const headHtml = getPreviewHeadHtml(configDir); - res.send(getIframeHtml({ ...data, headHtml, publicPath })); + res.set('Content-Type', 'text/html'); + res.sendFile(path.join(`${__dirname}/public/iframe.html`)); }); if (stats.toJson().errors.length) { diff --git a/app/vue/package.json b/app/vue/package.json index 5c8fa1e3cfb3..006c18c5374d 100644 --- a/app/vue/package.json +++ b/app/vue/package.json @@ -48,6 +48,7 @@ "file-loader": "^0.11.1", "find-cache-dir": "^1.0.0", "global": "^4.3.2", + "html-webpack-plugin": "^2.30.1", "json-loader": "^0.5.4", "json-stringify-safe": "^5.0.1", "json5": "^0.5.1", diff --git a/app/vue/src/client/preview/client_api.test.js b/app/vue/src/client/preview/client_api.test.js index ba7ec39502e8..b12f63f036a4 100644 --- a/app/vue/src/client/preview/client_api.test.js +++ b/app/vue/src/client/preview/client_api.test.js @@ -80,7 +80,10 @@ describe('preview.client_api', () => { }, }); - api.storiesOf('none', module).aa().bb(); + api + .storiesOf('none', module) + .aa() + .bb(); expect(data).toEqual(['foo', 'bar']); }); diff --git a/app/vue/src/server/build.js b/app/vue/src/server/build.js index b2a598b3e806..99df39a8f57b 100755 --- a/app/vue/src/server/build.js +++ b/app/vue/src/server/build.js @@ -9,9 +9,7 @@ import shelljs from 'shelljs'; import packageJson from '../../package.json'; import getBaseConfig from './config/webpack.config.prod'; import loadConfig from './config'; -import getIndexHtml from './index.html'; -import getIframeHtml from './iframe.html'; -import { getPreviewHeadHtml, getManagerHeadHtml, parseList, getEnvConfig } from './utils'; +import { parseList, getEnvConfig } from './utils'; process.env.NODE_ENV = process.env.NODE_ENV || 'production'; @@ -78,24 +76,12 @@ if (program.staticDir) { // compile all resources with webpack and write them to the disk. logger.log('Building storybook ...'); webpack(config).run((err, stats) => { - if (err) { + if (err || stats.hasErrors()) { logger.error('Failed to build the storybook'); - logger.error(err.message); + // eslint-disable-next-line no-unused-expressions + err && logger.error(err.message); + // eslint-disable-next-line no-unused-expressions + stats.hasErrors() && stats.toJson().errors.forEach(e => logger.error(e)); process.exit(1); } - - const data = { - publicPath: config.output.publicPath, - assets: stats.toJson().assetsByChunkName, - }; - - // Write both the storybook UI and IFRAME HTML files to destination path. - fs.writeFileSync( - path.resolve(outputDir, 'index.html'), - getIndexHtml({ ...data, headHtml: getManagerHeadHtml(configDir) }) - ); - fs.writeFileSync( - path.resolve(outputDir, 'iframe.html'), - getIframeHtml({ ...data, headHtml: getPreviewHeadHtml(configDir) }) - ); }); diff --git a/app/vue/src/server/config/utils.js b/app/vue/src/server/config/utils.js index 8cb15c640d93..0236481efd78 100644 --- a/app/vue/src/server/config/utils.js +++ b/app/vue/src/server/config/utils.js @@ -23,11 +23,15 @@ export function loadEnv(options = {}) { PUBLIC_URL: JSON.stringify(options.production ? '.' : ''), }; - Object.keys(process.env).filter(name => /^STORYBOOK_/.test(name)).forEach(name => { - env[name] = JSON.stringify(process.env[name]); - }); + Object.keys(process.env) + .filter(name => /^STORYBOOK_/.test(name)) + .forEach(name => { + env[name] = JSON.stringify(process.env[name]); + }); return { 'process.env': env, }; } + +export const getConfigDir = () => process.env.SBCONFIG_CONFIG_DIR || './.storybook'; diff --git a/app/vue/src/server/config/webpack.config.js b/app/vue/src/server/config/webpack.config.js index 10d1a6c9c1b4..c5fe4cdd6317 100644 --- a/app/vue/src/server/config/webpack.config.js +++ b/app/vue/src/server/config/webpack.config.js @@ -1,9 +1,19 @@ import path from 'path'; import webpack from 'webpack'; import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; import WatchMissingNodeModulesPlugin from './WatchMissingNodeModulesPlugin'; -import { includePaths, excludePaths, nodeModulesPaths, loadEnv, nodePaths } from './utils'; +import { + getConfigDir, + includePaths, + excludePaths, + nodeModulesPaths, + loadEnv, + nodePaths, +} from './utils'; +import { getPreviewHeadHtml, getManagerHeadHtml } from '../utils'; import babelLoaderConfig from './babel'; +import { version } from '../../../package.json'; export default function() { const config = { @@ -22,6 +32,23 @@ export default function() { publicPath: '/', }, plugins: [ + new HtmlWebpackPlugin({ + filename: 'index.html', + chunks: ['manager'], + data: { + managerHead: getManagerHeadHtml(getConfigDir()), + version, + }, + template: require.resolve('../index.html.ejs'), + }), + new HtmlWebpackPlugin({ + filename: 'iframe.html', + excludeChunks: ['manager'], + data: { + previewHead: getPreviewHeadHtml(getConfigDir()), + }, + template: require.resolve('../iframe.html.ejs'), + }), new webpack.DefinePlugin(loadEnv()), new webpack.HotModuleReplacementPlugin(), new CaseSensitivePathsPlugin(), diff --git a/app/vue/src/server/config/webpack.config.prod.js b/app/vue/src/server/config/webpack.config.prod.js index 1260b9de6dc4..f4fca7240d7c 100644 --- a/app/vue/src/server/config/webpack.config.prod.js +++ b/app/vue/src/server/config/webpack.config.prod.js @@ -1,7 +1,10 @@ import path from 'path'; import webpack from 'webpack'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; import babelLoaderConfig from './babel.prod'; -import { includePaths, excludePaths, loadEnv, nodePaths } from './utils'; +import { getConfigDir, includePaths, excludePaths, loadEnv, nodePaths } from './utils'; +import { getPreviewHeadHtml, getManagerHeadHtml } from '../utils'; +import { version } from '../../../package.json'; export default function() { const entries = { @@ -23,6 +26,23 @@ export default function() { publicPath: '', }, plugins: [ + new HtmlWebpackPlugin({ + filename: 'index.html', + chunks: ['manager'], + data: { + managerHead: getManagerHeadHtml(getConfigDir()), + version, + }, + template: require.resolve('../index.html.ejs'), + }), + new HtmlWebpackPlugin({ + filename: 'iframe.html', + excludeChunks: ['manager'], + data: { + previewHead: getPreviewHeadHtml(getConfigDir()), + }, + template: require.resolve('../iframe.html.ejs'), + }), new webpack.DefinePlugin(loadEnv({ production: true })), new webpack.optimize.UglifyJsPlugin({ compress: { diff --git a/app/vue/src/server/iframe.html.ejs b/app/vue/src/server/iframe.html.ejs new file mode 100644 index 000000000000..32318e29e958 --- /dev/null +++ b/app/vue/src/server/iframe.html.ejs @@ -0,0 +1,20 @@ + + + + + + + + Storybook + <%= htmlWebpackPlugin.options.data.previewHead %> + + +
+
+ + diff --git a/app/vue/src/server/iframe.html.js b/app/vue/src/server/iframe.html.js deleted file mode 100644 index bfcc2db58ee3..000000000000 --- a/app/vue/src/server/iframe.html.js +++ /dev/null @@ -1,87 +0,0 @@ -import url from 'url'; - -const getExtensionForFilename = filename => /.+\.(\w+)$/.exec(filename)[1]; - -// assets.preview will be: -// - undefined -// - string e.g. 'static/preview.9adbb5ef965106be1cc3.bundle.js' -// - array of strings e.g. -// [ 'static/preview.9adbb5ef965106be1cc3.bundle.js', -// 'preview.0d2d3d845f78399fd6d5e859daa152a9.css', -// 'static/preview.9adbb5ef965106be1cc3.bundle.js.map', -// 'preview.0d2d3d845f78399fd6d5e859daa152a9.css.map' ] -const urlsFromAssets = assets => { - if (!assets) { - return { - js: ['static/preview.bundle.js'], - css: [], - }; - } - - const urls = { - js: [], - css: [], - }; - - Object.keys(assets) - // Don't load the manager script in the iframe - .filter(key => key !== 'manager') - .forEach(key => { - let asset = assets[key]; - if (typeof asset === 'string') { - urls[getExtensionForFilename(asset)].push(asset); - } else { - if (!Array.isArray(asset)) { - asset = [asset]; - } - asset - .filter(assetUrl => { - const extension = getExtensionForFilename(assetUrl); - const isMap = extension === 'map'; - const isSupportedExtension = Boolean(urls[extension]); - return isSupportedExtension && !isMap; - }) - .forEach(assetUrl => { - urls[getExtensionForFilename(assetUrl)].push(assetUrl); - }); - } - }); - - return urls; -}; - -export default function({ assets, publicPath, headHtml }) { - const urls = urlsFromAssets(assets); - - const cssTags = urls.css - .map(u => ``) - .join('\n'); - const scriptTags = urls.js - .map(u => ``) - .join('\n'); - - return ` - - - - - - - - Storybook - ${headHtml} - ${cssTags} - - -
-
- ${scriptTags} - - - `; -} diff --git a/app/vue/src/server/index.html.ejs b/app/vue/src/server/index.html.ejs new file mode 100644 index 000000000000..397aaf41d52e --- /dev/null +++ b/app/vue/src/server/index.html.ejs @@ -0,0 +1,44 @@ + + + + + + + + Storybook + + <%= htmlWebpackPlugin.options.data.managerHead %> + + + +
+ + diff --git a/app/vue/src/server/index.html.js b/app/vue/src/server/index.html.js deleted file mode 100644 index 425b53601cfa..000000000000 --- a/app/vue/src/server/index.html.js +++ /dev/null @@ -1,70 +0,0 @@ -import url from 'url'; -import { version } from '../../package.json'; - -// assets.manager will be: -// - undefined -// - string e.g. 'static/manager.9adbb5ef965106be1cc3.bundle.js' -// - array of strings e.g. -// assets.manager will be something like: -// [ 'static/manager.c6e6350b6eb01fff8bad.bundle.js', -// 'static/manager.c6e6350b6eb01fff8bad.bundle.js.map' ] -const managerUrlsFromAssets = assets => { - if (!assets || !assets.manager) { - return { - js: 'static/manager.bundle.js', - }; - } - - if (typeof assets.manager === 'string') { - return { - js: assets.manager, - }; - } - - return { - js: assets.manager.find(filename => filename.match(/\.js$/)), - css: assets.manager.find(filename => filename.match(/\.css$/)), - }; -}; - -export default function({ assets, publicPath, headHtml }) { - const managerUrls = managerUrlsFromAssets(assets); - - return ` - - - - - - - - Storybook - - ${headHtml} - - -
- - - - `; -} diff --git a/app/vue/src/server/middleware.js b/app/vue/src/server/middleware.js index 7ebeb18be477..cf03d060a596 100644 --- a/app/vue/src/server/middleware.js +++ b/app/vue/src/server/middleware.js @@ -1,12 +1,11 @@ import { Router } from 'express'; import webpack from 'webpack'; +import path from 'path'; import webpackDevMiddleware from 'webpack-dev-middleware'; import webpackHotMiddleware from 'webpack-hot-middleware'; import getBaseConfig from './config/webpack.config'; import loadConfig from './config'; -import getIndexHtml from './index.html'; -import getIframeHtml from './iframe.html'; -import { getPreviewHeadHtml, getManagerHeadHtml, getMiddleware } from './utils'; +import { getMiddleware } from './utils'; let webpackResolve = () => {}; let webpackReject = () => {}; @@ -44,19 +43,14 @@ export default function(configDir) { middlewareFn(router); webpackDevMiddlewareInstance.waitUntilValid(stats => { - const data = { - publicPath: config.output.publicPath, - assets: stats.toJson().assetsByChunkName, - }; - router.get('/', (req, res) => { - const headHtml = getManagerHeadHtml(configDir); - res.send(getIndexHtml({ publicPath, headHtml })); + res.set('Content-Type', 'text/html'); + res.sendFile(path.join(`${__dirname}/public/index.html`)); }); router.get('/iframe.html', (req, res) => { - const headHtml = getPreviewHeadHtml(configDir); - res.send(getIframeHtml({ ...data, headHtml, publicPath })); + res.set('Content-Type', 'text/html'); + res.sendFile(path.join(`${__dirname}/public/iframe.html`)); }); if (stats.toJson().errors.length) { diff --git a/examples/cra-kitchen-sink/.storybook/webpack.config.js b/examples/cra-kitchen-sink/.storybook/webpack.config.js new file mode 100644 index 000000000000..001da2406dda --- /dev/null +++ b/examples/cra-kitchen-sink/.storybook/webpack.config.js @@ -0,0 +1,28 @@ +const webpack = require('webpack'); + +// load the default config generator. +const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js'); + +// Export a function. Accept the base config as the only param. +module.exports = (storybookBaseConfig, configType) => { + // configType has a value of 'DEVELOPMENT' or 'PRODUCTION' + // You can change the configuration based on that. + // 'PRODUCTION' is used when building the static version of storybook. + + const config = genDefaultConfig(storybookBaseConfig, configType); + + // Make whatever fine-grained changes you need + config.plugins.push( + new webpack.optimize.CommonsChunkPlugin({ + name: "vendor", + chunks: ['preview'], + minChunks: function (module) { + // this assumes your vendor imports exist in the node_modules directory + return module.context && module.context.indexOf("node_modules") !== -1; + }, + }) + ); + + // Return the altered config + return config; +}; diff --git a/examples/cra-kitchen-sink/src/components/ImportedPropsButton.js b/examples/cra-kitchen-sink/src/components/ImportedPropsButton.js index 6ee56cbca6d1..e38013d735f3 100644 --- a/examples/cra-kitchen-sink/src/components/ImportedPropsButton.js +++ b/examples/cra-kitchen-sink/src/components/ImportedPropsButton.js @@ -2,10 +2,11 @@ import React from 'react'; import DocgenButton from './DocgenButton'; /** Button component description */ -const ImportedPropsButton = ({ disabled, label, onClick }) => +const ImportedPropsButton = ({ disabled, label, onClick }) => ( ; + +); ImportedPropsButton.defaultProps = DocgenButton.defaultProps; diff --git a/examples/cra-kitchen-sink/src/stories/__snapshots__/index.storyshot b/examples/cra-kitchen-sink/src/stories/__snapshots__/index.storyshot index a862be90e2b0..76bd3f3d9be9 100644 --- a/examples/cra-kitchen-sink/src/stories/__snapshots__/index.storyshot +++ b/examples/cra-kitchen-sink/src/stories/__snapshots__/index.storyshot @@ -150,7 +150,7 @@ exports[`Storyshots AddonInfo.DocgenButton DocgenButton 1`] = ` } } > - Button with PropTypes and doc comments + Some Description

@@ -618,7 +618,7 @@ exports[`Storyshots AddonInfo.FlowTypeButton FlowTypeButton 1`] = ` } } > - Button with Flow type documentation comments + Some Description

@@ -3118,9 +3118,9 @@ exports[`Storyshots WithEvents Logger 1`] = ` Object { "color": "rgb(51, 51, 51)", "fontFamily": " - -apple-system, \\".SFNSText-Regular\\", \\"San Francisco\\", \\"Roboto\\", - \\"Segoe UI\\", \\"Helvetica Neue\\", \\"Lucida Grande\\", sans-serif - ", + -apple-system, \\".SFNSText-Regular\\", \\"San Francisco\\", \\"Roboto\\", + \\"Segoe UI\\", \\"Helvetica Neue\\", \\"Lucida Grande\\", sans-serif + ", "padding": 20, } } diff --git a/examples/cra-kitchen-sink/src/stories/index.js b/examples/cra-kitchen-sink/src/stories/index.js index dcbe82ff4396..6a6e91d58df2 100644 --- a/examples/cra-kitchen-sink/src/stories/index.js +++ b/examples/cra-kitchen-sink/src/stories/index.js @@ -42,7 +42,7 @@ const emit = emiter.emit.bind(emiter); storiesOf('Welcome', module).add('to Storybook', () => ); -const InfoButton = () => +const InfoButton = () => ( borderRadius: '0px 0px 0px 5px', }} > - {' '}Show Info{' '} - ; + {' '} + Show Info{' '} + +); storiesOf('Button', module) .addDecorator(withKnobs) - .add('with text', () => + .add('with text', () => ( - ) - .add('with some emoji', () => + )) + .add('with some emoji', () => ( - ) - .add('with notes', () => + )) + .add('with notes', () => ( - ) + )) .add('with knobs', () => { setOptions({ selectedAddonPanel: 'storybooks/storybook-addon-knobs' }); const name = text('Name', 'Storyteller'); @@ -121,73 +123,58 @@ storiesOf('Button', module) return (
-

- {intro} -

-

- My birthday is: {new Date(birthday).toLocaleDateString('en-US', dateOptions)} -

-

- I have {children.length} children: -

+

{intro}

+

My birthday is: {new Date(birthday).toLocaleDateString('en-US', dateOptions)}

+

I have {children.length} children:

    - {children.map(child => + {children.map(child => (
  1. {child.name}, {child.age} years old
  2. - )} + ))}
-

- My wallet contains: ${dollars.toFixed(2)} -

+

My wallet contains: ${dollars.toFixed(2)}

In my backpack, I have:

-
    - {items.map(item => -
  • - {item} -
  • - )} -
-

- {salutation} -

+
    {items.map(item =>
  • {item}
  • )}
+

{salutation}

); }) .addWithInfo( 'with some info', 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its painful API.', - context => + context => ( click the label in top right for info about "{context.story}" + ) ) .add( 'with new info', withInfo( 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.' - )(context => + )(context => ( {setOptions({ selectedAddonPanel: 'storybook/info/info-panel' })} click the label in top right for info about "{context.story}" - ) + )) ) .add( 'addons composition', withInfo('see Notes panel for composition info')( - withNotes('Composition: Info(Notes())')(context => + withNotes('Composition: Info(Notes())')(context => (
{setOptions({ selectedAddonPanel: 'storybook/notes/panel' })} click the label in top right for info about "{context.story}"
- ) + )) ) ); -storiesOf('AddonInfo.DocgenButton', module).addWithInfo('DocgenButton', 'Some Description', () => +storiesOf('AddonInfo.DocgenButton', module).addWithInfo('DocgenButton', 'Some Description', () => ( -); +)); storiesOf( 'AddonInfo.ImportedPropsButton', @@ -201,9 +188,9 @@ storiesOf( storiesOf( 'AddonInfo.FlowTypeButton', module -).addWithInfo('FlowTypeButton', 'Some Description', () => +).addWithInfo('FlowTypeButton', 'Some Description', () => ( -); +)); storiesOf('App', module).add('full app', () => ); @@ -212,7 +199,7 @@ storiesOf('Some really long story kind description', module) .add('with text', () => ); storiesOf('WithEvents', module) - .addDecorator(getStory => + .addDecorator(getStory => ( {getStory()} - ) + )) .add('Logger', () => ); storiesOf('withNotes', module) @@ -273,28 +260,20 @@ storiesOf('withNotes', module) .add('with some emoji', withNotes('My notes on emojies')(() =>

🤔😳😯😮

)) .add( 'with a button and some emoji', - withNotes('My notes on a button with emojies')(() => + withNotes('My notes on a button with emojies')(() => ( - ) + )) ) - .add('with old API', () => + .add('with old API', () => ( - ); + )); storiesOf('component.base.Link', module) .addDecorator(withKnobs) - .add('first', () => - - {text('firstLink', 'first link')} - - ) - .add('second', () => - - {text('secondLink', 'second link')} - - ); + .add('first', () => {text('firstLink', 'first link')}) + .add('second', () => {text('secondLink', 'second link')}); storiesOf('component.base.Span', module) .add('first', () => first span) @@ -305,20 +284,20 @@ storiesOf('component.common.Div', module) .add('second', () =>
second div
); storiesOf('component.common.Table', module) - .add('first', () => + .add('first', () => (
first table
- ) - .add('second', () => + )) + .add('second', () => (
first table
- ); + )); storiesOf('component.Button', module) .add('first', () => ) @@ -328,11 +307,7 @@ storiesOf('component.Button', module) storiesOf('Cells/Molecules.Atoms/simple', module) .addDecorator(withKnobs) - .add('with text', () => - - ) + .add('with text', () => ) .add('with some emoji', () => ); storiesOf('Cells/Molecules/Atoms.more', module) diff --git a/examples/crna-kitchen-sink/package.json b/examples/crna-kitchen-sink/package.json index 4126c6c8233c..996107a55711 100644 --- a/examples/crna-kitchen-sink/package.json +++ b/examples/crna-kitchen-sink/package.json @@ -34,6 +34,7 @@ "expo": "19.0.0", "prop-types": "15.5.10", "react": "16.0.0-alpha.12", - "react-native": "0.46.1" + "react-native": "0.46.1", + "webpack": "^2.5.1 || ^3.0.0" } } diff --git a/examples/crna-kitchen-sink/storybook/stories/Knobs/index.js b/examples/crna-kitchen-sink/storybook/stories/Knobs/index.js index 19cec307ac4f..8ca5af5a4440 100644 --- a/examples/crna-kitchen-sink/storybook/stories/Knobs/index.js +++ b/examples/crna-kitchen-sink/storybook/stories/Knobs/index.js @@ -34,26 +34,12 @@ export default () => { return ( - - {intro} - - - My birthday is: {new Date(birthday).toLocaleDateString('en-US', dateOptions)} - - - My wallet contains: ${dollars.toFixed(2)} - + {intro} + My birthday is: {new Date(birthday).toLocaleDateString('en-US', dateOptions)} + My wallet contains: ${dollars.toFixed(2)} In my backpack, I have: - - {items.map(item => - - {item} - - )} - - - {salutation} - + {items.map(item => {item})} + {salutation} ); }; diff --git a/examples/crna-kitchen-sink/storybook/stories/index.js b/examples/crna-kitchen-sink/storybook/stories/index.js index 597005a811de..2eea2d4a4e29 100644 --- a/examples/crna-kitchen-sink/storybook/stories/index.js +++ b/examples/crna-kitchen-sink/storybook/stories/index.js @@ -14,20 +14,18 @@ import Welcome from './Welcome'; storiesOf('Welcome', module).add('to Storybook', () => ); storiesOf('Button', module) - .addDecorator(getStory => - - {getStory()} - - ) - .add('with text', () => + .addDecorator(getStory => {getStory()}) + .add('with text', () => ( - ) - .add('with some emoji', () => + )) + .add('with some emoji', () => ( - ); + )); -storiesOf('Knobs', module).addDecorator(withKnobs).add('with knobs', knobsWrapper); +storiesOf('Knobs', module) + .addDecorator(withKnobs) + .add('with knobs', knobsWrapper); diff --git a/examples/crna-kitchen-sink/storybook/webpack.config.js b/examples/crna-kitchen-sink/storybook/webpack.config.js new file mode 100644 index 000000000000..a2daea72816d --- /dev/null +++ b/examples/crna-kitchen-sink/storybook/webpack.config.js @@ -0,0 +1,27 @@ +const webpack = require('webpack'); + +// load the default config generator. +const genDefaultConfig = require('@storybook/react-native/dist/server/config/defaults/webpack.config.js'); + +// Export a function. Accept the base config as the only param. +module.exports = (storybookBaseConfig, configType) => { + // configType has a value of 'DEVELOPMENT' or 'PRODUCTION' + // You can change the configuration based on that. + // 'PRODUCTION' is used when building the static version of storybook. + + const config = genDefaultConfig(storybookBaseConfig, configType); + + // Make whatever fine-grained changes you need + config.plugins.push( + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks(module) { + // this assumes your vendor imports exist in the node_modules directory + return module.context && module.context.indexOf('node_modules') !== -1; + }, + }) + ); + + // Return the altered config + return config; +}; diff --git a/examples/react-native-vanilla/storybook/stories/Knobs/index.js b/examples/react-native-vanilla/storybook/stories/Knobs/index.js index 19cec307ac4f..8ca5af5a4440 100644 --- a/examples/react-native-vanilla/storybook/stories/Knobs/index.js +++ b/examples/react-native-vanilla/storybook/stories/Knobs/index.js @@ -34,26 +34,12 @@ export default () => { return ( - - {intro} - - - My birthday is: {new Date(birthday).toLocaleDateString('en-US', dateOptions)} - - - My wallet contains: ${dollars.toFixed(2)} - + {intro} + My birthday is: {new Date(birthday).toLocaleDateString('en-US', dateOptions)} + My wallet contains: ${dollars.toFixed(2)} In my backpack, I have: - - {items.map(item => - - {item} - - )} - - - {salutation} - + {items.map(item => {item})} + {salutation} ); }; diff --git a/examples/react-native-vanilla/storybook/stories/index.js b/examples/react-native-vanilla/storybook/stories/index.js index 597005a811de..2eea2d4a4e29 100644 --- a/examples/react-native-vanilla/storybook/stories/index.js +++ b/examples/react-native-vanilla/storybook/stories/index.js @@ -14,20 +14,18 @@ import Welcome from './Welcome'; storiesOf('Welcome', module).add('to Storybook', () => ); storiesOf('Button', module) - .addDecorator(getStory => - - {getStory()} - - ) - .add('with text', () => + .addDecorator(getStory => {getStory()}) + .add('with text', () => ( - ) - .add('with some emoji', () => + )) + .add('with some emoji', () => ( - ); + )); -storiesOf('Knobs', module).addDecorator(withKnobs).add('with knobs', knobsWrapper); +storiesOf('Knobs', module) + .addDecorator(withKnobs) + .add('with knobs', knobsWrapper); diff --git a/examples/vue-kitchen-sink/.storybook/webpack.config.js b/examples/vue-kitchen-sink/.storybook/webpack.config.js new file mode 100644 index 000000000000..416bb092edd9 --- /dev/null +++ b/examples/vue-kitchen-sink/.storybook/webpack.config.js @@ -0,0 +1,28 @@ +const webpack = require('webpack'); + +// load the default config generator. +const genDefaultConfig = require('@storybook/vue/dist/server/config/defaults/webpack.config.js'); + +// Export a function. Accept the base config as the only param. +module.exports = (storybookBaseConfig, configType) => { + // configType has a value of 'DEVELOPMENT' or 'PRODUCTION' + // You can change the configuration based on that. + // 'PRODUCTION' is used when building the static version of storybook. + + const config = genDefaultConfig(storybookBaseConfig, configType); + + // Make whatever fine-grained changes you need + config.plugins.push( + new webpack.optimize.CommonsChunkPlugin({ + name: "vendor", + chunks: ['preview'], + minChunks: function (module) { + // this assumes your vendor imports exist in the node_modules directory + return module.context && module.context.indexOf("node_modules") !== -1; + }, + }) + ); + + // Return the altered config + return config; +}; diff --git a/lib/channels/src/index.js b/lib/channels/src/index.js index defa6aff9c5c..ca33fa3a848a 100644 --- a/lib/channels/src/index.js +++ b/lib/channels/src/index.js @@ -67,7 +67,9 @@ export default class Channel { _randomId() { // generates a random 13 character string - return Math.random().toString(16).slice(2); + return Math.random() + .toString(16) + .slice(2); } _handleEvent(event) { diff --git a/lib/ui/src/modules/ui/components/addon_panel/index.js b/lib/ui/src/modules/ui/components/addon_panel/index.js index 17b1935286a5..a1341fe66b5d 100644 --- a/lib/ui/src/modules/ui/components/addon_panel/index.js +++ b/lib/ui/src/modules/ui/components/addon_panel/index.js @@ -34,18 +34,20 @@ class AddonPanel extends Component { } renderPanels() { - return Object.keys(this.props.panels).sort().map(name => { - const panelStyle = { display: 'none' }; - const panel = this.props.panels[name]; - if (name === this.props.selectedPanel) { - Object.assign(panelStyle, { flex: 1, display: 'flex' }); - } - return ( -
- {panel.render()} -
- ); - }); + return Object.keys(this.props.panels) + .sort() + .map(name => { + const panelStyle = { display: 'none' }; + const panel = this.props.panels[name]; + if (name === this.props.selectedPanel) { + Object.assign(panelStyle, { flex: 1, display: 'flex' }); + } + return ( +
+ {panel.render()} +
+ ); + }); } renderEmpty() { @@ -61,9 +63,7 @@ class AddonPanel extends Component {
{this.renderTabs()}
-
- {this.renderPanels()} -
+
{this.renderPanels()}
); } diff --git a/lib/ui/src/modules/ui/components/layout/index.js b/lib/ui/src/modules/ui/components/layout/index.js index 593fed01ee53..05814ea78c58 100755 --- a/lib/ui/src/modules/ui/components/layout/index.js +++ b/lib/ui/src/modules/ui/components/layout/index.js @@ -222,13 +222,12 @@ class Layout extends React.Component { > {conditionalRender( showStoriesPanel, - () => + () => (
-
- {storiesPanel()} -
+
{storiesPanel()}
-
, + + ), () => )} @@ -264,11 +263,12 @@ class Layout extends React.Component { {conditionalRender( showAddonPanel, - () => + () => (
{addonPanel()} -
, + + ), () => )} diff --git a/lib/ui/src/modules/ui/components/layout/usplit.js b/lib/ui/src/modules/ui/components/layout/usplit.js index 65d950479fd6..a191e63d312d 100644 --- a/lib/ui/src/modules/ui/components/layout/usplit.js +++ b/lib/ui/src/modules/ui/components/layout/usplit.js @@ -40,10 +40,11 @@ const spanStyle = { }), }; -const USplit = ({ shift, split }) => +const USplit = ({ shift, split }) => (
-
; + +); USplit.propTypes = { shift: PropTypes.number, diff --git a/lib/ui/src/modules/ui/components/shortcuts_help.js b/lib/ui/src/modules/ui/components/shortcuts_help.js index fa3407d31d66..752d157002c4 100755 --- a/lib/ui/src/modules/ui/components/shortcuts_help.js +++ b/lib/ui/src/modules/ui/components/shortcuts_help.js @@ -65,29 +65,21 @@ export const Keys = ({ shortcutKeys }) => { if (shortcutKeys.length === 1) { return ( - - {shortcutKeys[0]} - + {shortcutKeys[0]} ); } // if we have multiple key combinations for a shortcut - const keys = shortcutKeys.map((key, index, arr) => + const keys = shortcutKeys.map((key, index, arr) => ( - - {key} - + {key} {/* add / & space if it is not a last key combination */} {arr.length - 1 !== index ? /   : ''} - ); + )); - return ( - - {keys} - - ); + return {keys}; }; Keys.propTypes = { @@ -95,12 +87,12 @@ Keys.propTypes = { }; export const Shortcuts = ({ appShortcuts }) => { - const shortcuts = appShortcuts.map(shortcut => + const shortcuts = appShortcuts.map(shortcut => (
{shortcut.name}
- ); + )); return (
diff --git a/lib/ui/src/modules/ui/components/stories_panel/header.js b/lib/ui/src/modules/ui/components/stories_panel/header.js index 458a3b79ad8f..a898bd03bb06 100755 --- a/lib/ui/src/modules/ui/components/stories_panel/header.js +++ b/lib/ui/src/modules/ui/components/stories_panel/header.js @@ -49,17 +49,16 @@ const linkStyle = { borderRadius: 2, }; -const Header = ({ openShortcutsHelp, name, url }) => +const Header = ({ openShortcutsHelp, name, url }) => ( ; +
+); Header.defaultProps = { openShortcutsHelp: null, diff --git a/lib/ui/src/modules/ui/components/stories_panel/index.js b/lib/ui/src/modules/ui/components/stories_panel/index.js index 57ae6ab563da..e8282889dd5a 100755 --- a/lib/ui/src/modules/ui/components/stories_panel/index.js +++ b/lib/ui/src/modules/ui/components/stories_panel/index.js @@ -50,9 +50,9 @@ class StoriesPanel extends Component { onChange={text => onStoryFilter(text)} />
- {hierarchyContainsStories(storiesHierarchy) - ? - : null} + {hierarchyContainsStories(storiesHierarchy) ? ( + + ) : null}
); diff --git a/lib/ui/src/modules/ui/components/stories_panel/stories_tree/index.test.js b/lib/ui/src/modules/ui/components/stories_panel/stories_tree/index.test.js index 25756977c124..7e6d8d84cdb1 100644 --- a/lib/ui/src/modules/ui/components/stories_panel/stories_tree/index.test.js +++ b/lib/ui/src/modules/ui/components/stories_panel/stories_tree/index.test.js @@ -51,7 +51,11 @@ describe('manager.ui.components.stories_panel.stories', () => { /> ); - const list = wrap.find('div').first().children('div').last(); + const list = wrap + .find('div') + .first() + .children('div') + .last(); expect(list.text()).toBe(''); }); @@ -281,7 +285,10 @@ describe('manager.ui.components.stories_panel.stories', () => { /> ); - const kind = wrap.find('[data-name="a"]').filterWhere(el => el.text() === 'a').last(); + const kind = wrap + .find('[data-name="a"]') + .filterWhere(el => el.text() === 'a') + .last(); kind.simulate('click'); onSelectStory.mockClear(); diff --git a/lib/ui/src/modules/ui/components/stories_panel/stories_tree/tree_decorators_utils.js b/lib/ui/src/modules/ui/components/stories_panel/stories_tree/tree_decorators_utils.js index 82969e23f3ca..ef5edbeee426 100644 --- a/lib/ui/src/modules/ui/components/stories_panel/stories_tree/tree_decorators_utils.js +++ b/lib/ui/src/modules/ui/components/stories_panel/stories_tree/tree_decorators_utils.js @@ -50,10 +50,6 @@ export function highlightNode(node, style) { ); } - return ( - - {part.text} - - ); + return {part.text}; }); } diff --git a/lib/ui/src/modules/ui/components/stories_panel/text_filter.js b/lib/ui/src/modules/ui/components/stories_panel/text_filter.js index ee717206d301..9161adfd3d35 100755 --- a/lib/ui/src/modules/ui/components/stories_panel/text_filter.js +++ b/lib/ui/src/modules/ui/components/stories_panel/text_filter.js @@ -97,10 +97,11 @@ export default class TextFilter extends React.Component { /> {this.state.query && - this.state.query.length && + this.state.query.length && ( } + + )} ); } diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index 03a6e8bf4dff..5a7a28a00a8e 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -9,7 +9,10 @@ const { lstatSync, readdirSync } = require('fs'); const { join } = require('path'); const isTgz = source => lstatSync(source).isFile() && source.match(/.tgz$/); -const getDirectories = source => readdirSync(source).map(name => join(source, name)).filter(isTgz); +const getDirectories = source => + readdirSync(source) + .map(name => join(source, name)) + .filter(isTgz); log.heading = 'storybook'; const prefix = 'bootstrap'; @@ -111,7 +114,11 @@ Object.keys(tasks).forEach(key => { }); let selection; -if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { +if ( + !Object.keys(tasks) + .map(key => tasks[key].value) + .filter(Boolean).length +) { selection = inquirer .prompt([ { @@ -150,7 +157,9 @@ if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { }); } else { selection = Promise.resolve( - Object.keys(tasks).map(key => tasks[key]).filter(item => item.value === true) + Object.keys(tasks) + .map(key => tasks[key]) + .filter(item => item.value === true) ); } diff --git a/scripts/test.js b/scripts/test.js index 8d75b58515c6..5723b9f0ff83 100755 --- a/scripts/test.js +++ b/scripts/test.js @@ -98,7 +98,11 @@ Object.keys(tasks).forEach(key => { }); let selection; -if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { +if ( + !Object.keys(tasks) + .map(key => tasks[key].value) + .filter(Boolean).length +) { selection = inquirer .prompt([ { @@ -114,10 +118,13 @@ if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { })) .concat(new inquirer.Separator()) .concat( - Object.keys(tasks).map(key => tasks[key]).filter(key => key.extraParam).map(key => ({ - name: key.name, - checked: key.defaultValue, - })) + Object.keys(tasks) + .map(key => tasks[key]) + .filter(key => key.extraParam) + .map(key => ({ + name: key.name, + checked: key.defaultValue, + })) ), }, ]) @@ -126,7 +133,9 @@ if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) { ); } else { selection = Promise.resolve( - Object.keys(tasks).map(key => tasks[key]).filter(item => item.value === true) + Object.keys(tasks) + .map(key => tasks[key]) + .filter(item => item.value === true) ); } diff --git a/yarn.lock b/yarn.lock index 38aafc6bb394..5f2700b9ee35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -430,10 +430,6 @@ ast-types@0.8.12: version "0.8.12" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc" -ast-types@0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52" - ast-types@0.9.11: version "0.9.11" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.11.tgz#371177bb59232ff5ceaa1d09ee5cad705b1a5aa9" @@ -507,7 +503,7 @@ axobject-query@^0.1.0: dependencies: ast-types-flow "0.0.7" -babel-cli@^6.24.1: +babel-cli@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" dependencies: @@ -619,7 +615,7 @@ babel-core@^5: trim-right "^1.0.0" try-resolve "^1.0.0" -babel-core@^6.0.0, babel-core@^6.21.0, babel-core@^6.25.0, babel-core@^6.26.0, babel-core@^6.7.2: +babel-core@^6.0.0, babel-core@^6.21.0, babel-core@^6.26.0, babel-core@^6.7.2: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" dependencies: @@ -1497,7 +1493,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-polyfill@^6.20.0, babel-polyfill@^6.23.0, babel-polyfill@^6.26.0: +babel-polyfill@^6.20.0, babel-polyfill@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" dependencies: @@ -2262,12 +2258,12 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000725" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000725.tgz#20f2313d79401e02f61840f39698bc8c558811a6" + version "1.0.30000726" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000726.tgz#9bb742f8d026a62df873bc03c06843d2255b60d7" caniuse-lite@^1.0.30000669, caniuse-lite@^1.0.30000718: - version "1.0.30000725" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000725.tgz#4fa66372323c6ff46c8a1ba03f9dcd73d7a1cb39" + version "1.0.30000726" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000726.tgz#966a753fa107a09d4131cf8b3d616723a06ccf7e" caniuse-lite@^1.0.30000715: version "1.0.30000717" @@ -2379,7 +2375,7 @@ child-process-promise@^2.2.1: node-version "^1.0.0" promise-polyfill "^6.0.1" -chokidar@^1.4.3, chokidar@^1.5.1, chokidar@^1.6.0, chokidar@^1.6.1, chokidar@^1.7.0: +chokidar@^1.5.1, chokidar@^1.6.0, chokidar@^1.6.1, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -2516,7 +2512,7 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -codecov@^2.2.0: +codecov@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/codecov/-/codecov-2.3.0.tgz#ad25a2c6e0442d13740d9d4ddbb9a3e2714330f4" dependencies: @@ -2678,19 +2674,6 @@ config-chain@~1.1.5: ini "^1.3.4" proto-list "~1.2.1" -configstore@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021" - dependencies: - graceful-fs "^4.1.2" - mkdirp "^0.5.0" - object-assign "^4.0.1" - os-tmpdir "^1.0.0" - osenv "^0.1.0" - uuid "^2.0.1" - write-file-atomic "^1.1.2" - xdg-basedir "^2.0.0" - configstore@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" @@ -3278,7 +3261,7 @@ damerau-levenshtein@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" -danger@^1.0.0: +danger@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/danger/-/danger-1.2.0.tgz#45012a191af890c8bb3879a2f3bdf0ef406e0cef" dependencies: @@ -3667,15 +3650,6 @@ duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" -duplexify@^3.2.0: - version "3.5.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -3738,12 +3712,6 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" -end-of-stream@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" - dependencies: - once "^1.4.0" - enhanced-resolve@^3.0.0, enhanced-resolve@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" @@ -3861,7 +3829,7 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" -es6-promise@^3.0.2: +es6-promise@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" @@ -3943,9 +3911,9 @@ eslint-config-airbnb@^15.1.0: dependencies: eslint-config-airbnb-base "^11.3.0" -eslint-config-prettier@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.3.0.tgz#b75b1eabea0c8b97b34403647ee25db349b9d8a0" +eslint-config-prettier@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.4.0.tgz#fb7cf29c0ab2ba61af5164fb1930f9bef3be2872" dependencies: get-stdin "^5.0.1" @@ -4056,7 +4024,7 @@ eslint-plugin-jsx-a11y@^6.0.2: emoji-regex "^6.1.0" jsx-ast-utils "^1.4.0" -eslint-plugin-prettier@^2.1.2: +eslint-plugin-prettier@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.2.0.tgz#f2837ad063903d73c621e7188fb3d41486434088" dependencies: @@ -4071,7 +4039,7 @@ eslint-plugin-react@7.0.1: has "^1.0.1" jsx-ast-utils "^1.3.4" -eslint-plugin-react@^7.1.0: +eslint-plugin-react@^7.3.0: version "7.3.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.3.0.tgz#ca9368da36f733fbdc05718ae4e91f778f38e344" dependencies: @@ -4131,9 +4099,9 @@ eslint@3.19.0, eslint@^3.16.1: text-table "~0.2.0" user-home "^2.0.0" -eslint@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.5.0.tgz#bb75d3b8bde97fb5e13efcd539744677feb019c3" +eslint@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.6.1.tgz#ddc7fc7fd70bf93205b0b3449bb16a1e9e7d4950" dependencies: ajv "^5.2.0" babel-code-frame "^6.22.0" @@ -4641,8 +4609,8 @@ flatten@^1.0.2: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" flow-parser@^0.*: - version "0.54.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.54.0.tgz#82b3eea7a95561cb2f8d24d2068789e3491447a8" + version "0.54.1" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.54.1.tgz#5037778da8d8391192527f2b36853e98945ae390" fn-name@^2.0.1: version "2.0.1" @@ -4733,7 +4701,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^4.0.0, fs-extra@^4.0.1: +fs-extra@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.1.tgz#7fc0c6c8957f983f57f306a24e5b9ddd8d0dd880" dependencies: @@ -4841,6 +4809,10 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" +get-own-enumerable-property-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-1.0.1.tgz#f1d4e3ad1402e039898e56d1e9b9aa924c26e484" + get-pkg-repo@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" @@ -5090,21 +5062,6 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" -got@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/got/-/got-3.3.1.tgz#e5d0ed4af55fc3eef4d56007769d98192bcb2eca" - dependencies: - duplexify "^3.2.0" - infinity-agent "^2.0.0" - is-redirect "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - nested-error-stacks "^1.0.0" - object-assign "^3.0.0" - prepend-http "^1.0.0" - read-all-stream "^3.0.0" - timed-out "^2.0.0" - got@^5.0.0: version "5.7.1" resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" @@ -5409,6 +5366,17 @@ html-webpack-plugin@2.28.0: pretty-error "^2.0.2" toposort "^1.0.0" +html-webpack-plugin@^2.30.1: + version "2.30.1" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz#7f9c421b7ea91ec460f56527d78df484ee7537d5" + dependencies: + bluebird "^3.4.7" + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + toposort "^1.0.0" + htmlparser2@3.8.x: version "3.8.3" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" @@ -5533,7 +5501,7 @@ ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" -ignore-by-default@^1.0.0: +ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -5579,10 +5547,6 @@ indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" -infinity-agent@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/infinity-agent/-/infinity-agent-2.0.3.tgz#45e0e2ff7a9eb030b27d62b74b3744b7a7ac4216" - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -5689,9 +5653,9 @@ inquirer@^0.12.0: strip-ansi "^3.0.0" through "^2.3.6" -inquirer@^3.0.6, inquirer@^3.1.0, inquirer@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.2.tgz#c2aaede1507cc54d826818737742d621bef2e823" +inquirer@^3.0.6, inquirer@^3.2.2, inquirer@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.3.tgz#1c7b1731cf77b934ec47d22c9ac5aa8fe7fbe095" dependencies: ansi-escapes "^2.0.0" chalk "^2.0.0" @@ -5831,7 +5795,7 @@ is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" -is-extglob@^2.1.0: +is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -5867,6 +5831,12 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + is-hexadecimal@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz#6e084bbc92061fbb0971ec58b6ce6d404e24da69" @@ -5906,7 +5876,7 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-obj@^1.0.0: +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -5966,6 +5936,10 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" @@ -6304,7 +6278,7 @@ jest-environment-node@^21.0.0: jest-mock "^21.0.0" jest-util "^21.0.0" -jest-enzyme@^3.8.1: +jest-enzyme@^3.8.2: version "3.8.2" resolved "https://registry.yarnpkg.com/jest-enzyme/-/jest-enzyme-3.8.2.tgz#b0352ca90193b4acc15509206ec68ddc41d98b6d" dependencies: @@ -6823,12 +6797,6 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" -latest-version@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-1.0.1.tgz#72cfc46e3e8d1be651e1ebb54ea9f6ea96f374bb" - dependencies: - package-json "^1.0.0" - latest-version@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" @@ -6859,7 +6827,7 @@ left-pad@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.1.3.tgz#612f61c033f3a9e08e939f1caebeea41b6f3199a" -lerna@2.1.2: +lerna@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/lerna/-/lerna-2.1.2.tgz#b07eb7a4d7dd7d44a105262fef49b2229301c577" dependencies: @@ -6915,19 +6883,23 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lint-staged@^4.0.2: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-4.0.4.tgz#9ca6968b30dfbfe81365b7a763cd4f4992896553" +lint-staged@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-4.1.0.tgz#5d983361566aa5974cd58f0a64afa5acbd9d6118" dependencies: app-root-path "^2.0.0" + chalk "^2.1.0" cosmiconfig "^1.1.0" execa "^0.8.0" + is-glob "^4.0.0" + jest-validate "^20.0.3" listr "^0.12.0" - lodash.chunk "^4.2.0" + lodash "^4.17.4" minimatch "^3.0.0" npm-which "^3.0.1" p-map "^1.1.1" staged-git-files "0.0.4" + stringify-object "^3.2.0" listr-silent-renderer@^1.1.1: version "1.1.1" @@ -7141,10 +7113,6 @@ lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" -lodash.chunk@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc" - lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" @@ -7773,12 +7741,6 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" -nested-error-stacks@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz#19f619591519f096769a5ba9a86e6eeec823c3cf" - dependencies: - inherits "~2.0.1" - netrc@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444" @@ -7888,20 +7850,20 @@ node-version@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.1.0.tgz#f437d7ba407e65e2c4eaef8887b1718ba523d4f0" -nodemon@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.11.0.tgz#226c562bd2a7b13d3d7518b49ad4828a3623d06c" +nodemon@^1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.12.0.tgz#e538548a777340a19f855c4f087b7e528aa3feda" dependencies: - chokidar "^1.4.3" - debug "^2.2.0" - es6-promise "^3.0.2" - ignore-by-default "^1.0.0" + chokidar "^1.7.0" + debug "^2.6.8" + es6-promise "^3.3.1" + ignore-by-default "^1.0.1" lodash.defaults "^3.1.2" - minimatch "^3.0.0" - ps-tree "^1.0.1" - touch "1.0.0" + minimatch "^3.0.4" + ps-tree "^1.1.0" + touch "^3.1.0" undefsafe "0.0.3" - update-notifier "0.5.0" + update-notifier "^2.2.0" nomnom@^1.8.1: version "1.8.1" @@ -8258,13 +8220,6 @@ p-map@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a" -package-json@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-1.2.0.tgz#c8ecac094227cdf76a316874ed05e27cc939a0e0" - dependencies: - got "^3.2.0" - registry-url "^3.0.0" - package-json@^2.0.0: version "2.4.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" @@ -8835,12 +8790,12 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 supports-color "^3.2.3" postcss@^6.0.1, postcss@^6.0.10, postcss@^6.0.2, postcss@^6.x: - version "6.0.10" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.10.tgz#c311b89734483d87a91a56dc9e53f15f4e6e84e4" + version "6.0.11" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.11.tgz#f48db210b1d37a7f7ab6499b7a54982997ab6f72" dependencies: chalk "^2.1.0" source-map "^0.5.7" - supports-color "^4.2.1" + supports-color "^4.4.0" prelude-ls@~1.1.2: version "1.1.2" @@ -8854,9 +8809,9 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@^1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.3.tgz#59dadc683345ec6b88f88b94ed4ae7e1da394bfe" +prettier@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.6.1.tgz#850f411a3116226193e32ea5acfc21c0f9a76d7d" pretty-bytes@^4.0.2: version "4.0.2" @@ -8963,7 +8918,7 @@ prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" -ps-tree@^1.0.1: +ps-tree@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" dependencies: @@ -9626,7 +9581,7 @@ rebound@^0.0.13: version "0.0.13" resolved "https://registry.yarnpkg.com/rebound/-/rebound-0.0.13.tgz#4a225254caf7da756797b19c5817bf7a7941fac1" -recast@0.10.33: +recast@0.10.33, recast@^0.10.10: version "0.10.33" resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697" dependencies: @@ -9635,15 +9590,6 @@ recast@0.10.33: private "~0.1.5" source-map "~0.5.0" -recast@^0.10.10: - version "0.10.43" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f" - dependencies: - ast-types "0.8.15" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - source-map "~0.5.0" - recast@^0.11.17: version "0.11.23" resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" @@ -9788,7 +9734,7 @@ registry-auth-token@^3.0.1: rc "^1.1.6" safe-buffer "^5.0.1" -registry-url@^3.0.0, registry-url@^3.0.3: +registry-url@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" dependencies: @@ -9964,7 +9910,7 @@ remark-lint-ordered-list-marker-style@^1.0.0: unist-util-position "^3.0.0" unist-util-visit "^1.1.1" -remark-lint@^6.0.0: +remark-lint@^6.0.0, remark-lint@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/remark-lint/-/remark-lint-6.0.1.tgz#68b10ec25d5145042f7cfa52649e20ef7bc91482" dependencies: @@ -9999,7 +9945,7 @@ remark-parse@^4.0.0: vfile-location "^2.0.0" xtend "^4.0.1" -remark-preset-lint-recommended@^3.0.0: +remark-preset-lint-recommended@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.1.tgz#75486577873e20f514cf66e399fcc0d872971049" dependencies: @@ -10807,10 +10753,6 @@ stream-http@^2.3.1: to-arraybuffer "^1.0.0" xtend "^4.0.0" -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - stream-to-observable@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" @@ -10819,7 +10761,7 @@ strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" -string-length@^1.0.0, string-length@^1.0.1: +string-length@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac" dependencies: @@ -10875,6 +10817,14 @@ stringify-entities@^1.0.1: is-alphanumerical "^1.0.0" is-hexadecimal "^1.0.0" +stringify-object@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.0.tgz#94370a135e41bc048358813bf99481f1315c6aa6" + dependencies: + get-own-enumerable-property-symbols "^1.0.1" + is-obj "^1.0.1" + is-regexp "^1.0.0" + stringmap@~0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1" @@ -10967,6 +10917,12 @@ supports-color@^4.0.0, supports-color@^4.1.0, supports-color@^4.2.1: dependencies: has-flag "^2.0.0" +supports-color@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + dependencies: + has-flag "^2.0.0" + svg-tag-names@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/svg-tag-names/-/svg-tag-names-1.1.1.tgz#9641b29ef71025ee094c7043f7cdde7d99fbd50a" @@ -11175,10 +11131,6 @@ time-stamp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" -timed-out@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a" - timed-out@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" @@ -11232,9 +11184,9 @@ toposort@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.3.tgz#f02cd8a74bd8be2fc0e98611c3bacb95a171869c" -touch@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-1.0.0.tgz#449cbe2dbae5a8c8038e30d71fa0ff464947c4de" +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" dependencies: nopt "~1.0.10" @@ -11529,18 +11481,6 @@ unzip-response@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" -update-notifier@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.5.0.tgz#07b5dc2066b3627ab3b4f530130f7eddda07a4cc" - dependencies: - chalk "^1.0.0" - configstore "^1.0.0" - is-npm "^1.0.0" - latest-version "^1.0.0" - repeating "^1.1.2" - semver-diff "^2.0.0" - string-length "^1.0.0" - update-notifier@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-1.0.3.tgz#8f92c515482bd6831b7c93013e70f87552c7cf5a" @@ -11554,7 +11494,7 @@ update-notifier@^1.0.3: semver-diff "^2.0.0" xdg-basedir "^2.0.0" -update-notifier@^2.1.0: +update-notifier@^2.1.0, update-notifier@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.2.0.tgz#1b5837cf90c0736d88627732b661c138f86de72f" dependencies: