diff --git a/client/main.js b/client/main.js
deleted file mode 100644
index ef7121d..0000000
--- a/client/main.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import "./main.css";
-
-import React from "react";
-import ReactDOM from "react-dom";
-
-import App from "./main/App";
-
-ReactDOM.render(, document.getElementById("root"));
diff --git a/client/main/About.js b/client/main/About.js
deleted file mode 100644
index bee1b31..0000000
--- a/client/main/About.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import "./About.css";
-
-import React from "react";
-
-import html from "./About.md";
-
-function About() {
- return
;
-}
-
-export default About;
diff --git a/client/main/App.js b/client/main/App.js
deleted file mode 100644
index 19fd6b5..0000000
--- a/client/main/App.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from "react";
-import { HashRouter } from "react-router-dom";
-import Layout from "./Layout";
-
-const App = () => (
-
-
-
-);
-
-export default App;
diff --git a/client/main/Home.js b/client/main/Home.js
deleted file mode 100644
index e16d897..0000000
--- a/client/main/Home.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import "./Home.css";
-
-import React from "react";
-
-import html from "./Home.md";
-
-function Home() {
- return ;
-}
-
-export default Home;
diff --git a/client/utils/formatNumber.js b/client/utils/formatNumber.js
deleted file mode 100644
index 94b33f9..0000000
--- a/client/utils/formatNumber.js
+++ /dev/null
@@ -1,10 +0,0 @@
-const formatNumber = n => {
- const digits = String(n).split("");
- const groups = [];
-
- while (digits.length) groups.unshift(digits.splice(-3).join(""));
-
- return groups.join(",");
-};
-
-export default formatNumber;
diff --git a/client/utils/formatPercent.js b/client/utils/formatPercent.js
deleted file mode 100644
index 9f68ac9..0000000
--- a/client/utils/formatPercent.js
+++ /dev/null
@@ -1,4 +0,0 @@
-const formatPercent = (n, fixed = 1) =>
- String((n.toPrecision(2) * 100).toFixed(fixed));
-
-export default formatPercent;
diff --git a/client/utils/parseNumber.js b/client/utils/parseNumber.js
deleted file mode 100644
index 9ab1a6d..0000000
--- a/client/utils/parseNumber.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const parseNumber = s => parseInt(s.replace(/,/g, ""), 10) || 0;
-
-export default parseNumber;
diff --git a/docker-compose.yml b/docker-compose.yml
index fd36f81..8a78cc4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,7 +12,7 @@ services:
server:
build: .
- command: node_modules/.bin/nodemon --ignore client server.js
+ command: node_modules/.bin/nodemon --ignore server/client server.js
env_file: .env
environment:
- CACHE_URL=redis://data:6379
@@ -30,7 +30,7 @@ services:
worker:
build: .
- command: node_modules/.bin/nodemon --ignore client server/ingestLogs.js
+ command: node_modules/.bin/nodemon --ignore server/client server/ingestLogs.js
env_file: .env
environment:
- DATA_URL=redis://data:6379
diff --git a/package.json b/package.json
index 2c403b5..313c725 100644
--- a/package.json
+++ b/package.json
@@ -7,12 +7,16 @@
"test": "jest"
},
"dependencies": {
- "babel-core": "^6.26.0",
+ "babel-core": "^6.26.3",
"babel-plugin-syntax-export-extensions": "^6.13.0",
+ "babel-plugin-transform-react-remove-prop-types": "^0.4.14",
+ "babel-preset-env": "^1.7.0",
+ "babel-preset-react": "^6.24.1",
+ "babel-preset-stage-2": "^6.24.1",
+ "babel-register": "^6.26.0",
"body-parser": "^1.18.2",
"cors": "^2.8.1",
"countries-list": "^1.3.2",
- "csso": "^3.1.1",
"date-fns": "^1.28.1",
"etag": "^1.8.0",
"express": "^4.15.2",
@@ -44,15 +48,12 @@
"devDependencies": {
"babel-eslint": "^8.0.3",
"babel-loader": "^7.1.2",
- "babel-plugin-transform-react-remove-prop-types": "^0.4.13",
- "babel-preset-env": "^1.6.1",
- "babel-preset-react": "^6.24.1",
- "babel-preset-stage-2": "^6.24.1",
"css-loader": "0.26.1",
"errorhandler": "^1.5.0",
"eslint": "^4.13.1",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-react": "^7.5.1",
+ "extract-text-webpack-plugin": "^3.0.2",
"file-loader": "0.10.0",
"html-loader": "^0.5.1",
"jest": "^22.4.4",
diff --git a/server.js b/server.js
index a22c19a..ab7ea5f 100644
--- a/server.js
+++ b/server.js
@@ -6,6 +6,8 @@ const createServer = require("./server/createServer");
const createDevServer = require("./server/createDevServer");
const config = require("./server/config");
+require("./server/clientRuntime");
+
if (process.env.SENTRY_DSN) {
raven
.config(process.env.SENTRY_DSN, {
diff --git a/server/actions/serveAutoIndexPage.js b/server/actions/serveAutoIndexPage.js
new file mode 100644
index 0000000..8bd49e3
--- /dev/null
+++ b/server/actions/serveAutoIndexPage.js
@@ -0,0 +1,57 @@
+const React = require("react");
+const ReactDOMServer = require("react-dom/server");
+const semver = require("semver");
+
+const MainPage = require("../client/MainPage");
+const AutoIndexApp = require("../client/autoIndex/App");
+const renderPage = require("../utils/renderPage");
+
+const globalScripts =
+ process.env.NODE_ENV === "production"
+ ? [
+ "/react@16.4.1/umd/react.production.min.js",
+ "/react-dom@16.4.1/umd/react-dom.production.min.js",
+ "/react-router-dom@4.3.1/umd/react-router-dom.min.js"
+ ]
+ : [
+ "/react@16.4.1/umd/react.development.js",
+ "/react-dom@16.4.1/umd/react-dom.development.js",
+ "/react-router-dom@4.3.1/umd/react-router-dom.js"
+ ];
+
+function byVersion(a, b) {
+ return semver.lt(a, b) ? -1 : semver.gt(a, b) ? 1 : 0;
+}
+
+function serveAutoIndexPage(req, res) {
+ const scripts = globalScripts.concat(req.assets.getScripts("autoIndex"));
+ const styles = req.assets.getStyles("autoIndex");
+
+ const props = {
+ packageName: req.packageName,
+ packageVersion: req.packageVersion,
+ availableVersions: Object.keys(req.packageInfo.versions).sort(byVersion),
+ filename: req.filename,
+ entry: req.entry,
+ entries: req.entries
+ };
+ const content = ReactDOMServer.renderToString(
+ React.createElement(AutoIndexApp, props)
+ );
+
+ const html = renderPage(MainPage, {
+ scripts: scripts,
+ styles: styles,
+ data: props,
+ content: content
+ });
+
+ res
+ .set({
+ "Cache-Control": "public,max-age=60", // 1 minute
+ "Cache-Tag": "auto-index"
+ })
+ .send(html);
+}
+
+module.exports = serveAutoIndexPage;
diff --git a/server/actions/serveFile.js b/server/actions/serveFile.js
index 240bb14..366ee91 100644
--- a/server/actions/serveFile.js
+++ b/server/actions/serveFile.js
@@ -1,155 +1,7 @@
-const fs = require("fs");
-const path = require("path");
-const etag = require("etag");
-const babel = require("babel-core");
-
-const IndexPage = require("../components/IndexPage");
-const unpkgRewrite = require("../plugins/unpkgRewrite");
-const addLeadingSlash = require("../utils/addLeadingSlash");
-const renderPage = require("../utils/renderPage");
-
-function getMatchingEntries(entry, entries) {
- const dirname = entry.name || ".";
-
- return Object.keys(entries)
- .filter(name => entry.name !== name && path.dirname(name) === dirname)
- .map(name => entries[name]);
-}
-
-function getMetadata(entry, entries) {
- const metadata = {
- path: addLeadingSlash(entry.name),
- type: entry.type
- };
-
- if (entry.type === "file") {
- metadata.contentType = entry.contentType;
- metadata.integrity = entry.integrity;
- metadata.lastModified = entry.lastModified;
- metadata.size = entry.size;
- } else if (entry.type === "directory") {
- metadata.files = getMatchingEntries(entry, entries).map(e =>
- getMetadata(e, entries)
- );
- }
-
- return metadata;
-}
-
-function serveMetadata(req, res) {
- const metadata = getMetadata(req.entry, req.entries);
-
- res
- .set({
- "Cache-Control": "public,max-age=31536000", // 1 year
- "Cache-Tag": "meta"
- })
- .send(metadata);
-}
-
-function rewriteBareModuleIdentifiers(code, packageConfig) {
- const dependencies = Object.assign(
- {},
- packageConfig.peerDependencies,
- packageConfig.dependencies
- );
-
- const options = {
- // Ignore .babelrc and package.json babel config
- // because we haven't installed dependencies so
- // we can't load plugins; see #84
- babelrc: false,
- plugins: [unpkgRewrite(dependencies)]
- };
-
- return babel.transform(code, options).code;
-}
-
-function getContentTypeHeader(type) {
- return type === "application/javascript" ? type + "; charset=utf-8" : type;
-}
-
-function serveJavaScriptModule(req, res) {
- if (req.entry.contentType !== "application/javascript") {
- return res
- .status(403)
- .type("text")
- .send("?module mode is available only for JavaScript files");
- }
-
- try {
- const code = rewriteBareModuleIdentifiers(
- req.entry.content.toString("utf8"),
- req.packageConfig
- );
-
- res
- .set({
- "Content-Length": Buffer.byteLength(code),
- "Content-Type": getContentTypeHeader(req.entry.contentType),
- "Cache-Control": "public,max-age=31536000", // 1 year
- ETag: etag(code),
- "Cache-Tag": "file,js-file,js-module"
- })
- .send(code);
- } catch (error) {
- console.error(error);
-
- const errorName = error.constructor.name;
- const errorMessage = error.message.replace(
- /^.*?\/unpkg-.+?\//,
- `/${req.packageSpec}/`
- );
- const codeFrame = error.codeFrame;
- const debugInfo = `${errorName}: ${errorMessage}\n\n${codeFrame}`;
-
- res
- .status(500)
- .type("text")
- .send(
- `Cannot generate module for ${req.packageSpec}${
- req.filename
- }\n\n${debugInfo}`
- );
- }
-}
-
-function serveStaticFile(req, res) {
- const tags = ["file"];
-
- const ext = path.extname(req.entry.name).substr(1);
- if (ext) {
- tags.push(`${ext}-file`);
- }
-
- res
- .set({
- "Content-Length": req.entry.size,
- "Content-Type": getContentTypeHeader(req.entry.contentType),
- "Cache-Control": "public,max-age=31536000", // 1 year
- "Last-Modified": req.entry.lastModified,
- ETag: etag(req.entry.content),
- "Cache-Tag": tags.join(",")
- })
- .send(req.entry.content);
-}
-
-function serveIndex(req, res) {
- const html = renderPage(IndexPage, {
- packageInfo: req.packageInfo,
- version: req.packageVersion,
- filename: req.filename,
- entries: req.entries,
- entry: req.entry
- });
-
- res
- .set({
- "Cache-Control": "public,max-age=60", // 1 minute
- "Cache-Tag": "index"
- })
- .send(html);
-}
+const serveAutoIndexPage = require("./serveAutoIndexPage");
+const serveJavaScriptModule = require("./serveJavaScriptModule");
+const serveStaticFile = require("./serveStaticFile");
+const serveMetadata = require("./serveMetadata");
/**
* Send the file, JSON metadata, or HTML directory listing.
@@ -160,7 +12,7 @@ function serveFile(req, res) {
}
if (req.entry.type === "directory") {
- return serveIndex(req, res);
+ return serveAutoIndexPage(req, res);
}
if (req.query.module != null) {
diff --git a/server/actions/serveJavaScriptModule.js b/server/actions/serveJavaScriptModule.js
new file mode 100644
index 0000000..6afc9a5
--- /dev/null
+++ b/server/actions/serveJavaScriptModule.js
@@ -0,0 +1,70 @@
+const etag = require("etag");
+const babel = require("babel-core");
+
+const getContentTypeHeader = require("../utils/getContentTypeHeader");
+const unpkgRewrite = require("../plugins/unpkgRewrite");
+
+function rewriteBareModuleIdentifiers(code, packageConfig) {
+ const dependencies = Object.assign(
+ {},
+ packageConfig.peerDependencies,
+ packageConfig.dependencies
+ );
+
+ const options = {
+ // Ignore .babelrc and package.json babel config
+ // because we haven't installed dependencies so
+ // we can't load plugins; see #84
+ babelrc: false,
+ plugins: [unpkgRewrite(dependencies)]
+ };
+
+ return babel.transform(code, options).code;
+}
+
+function serveJavaScriptModule(req, res) {
+ if (req.entry.contentType !== "application/javascript") {
+ return res
+ .status(403)
+ .type("text")
+ .send("?module mode is available only for JavaScript files");
+ }
+
+ try {
+ const code = rewriteBareModuleIdentifiers(
+ req.entry.content.toString("utf8"),
+ req.packageConfig
+ );
+
+ res
+ .set({
+ "Content-Length": Buffer.byteLength(code),
+ "Content-Type": getContentTypeHeader(req.entry.contentType),
+ "Cache-Control": "public,max-age=31536000", // 1 year
+ ETag: etag(code),
+ "Cache-Tag": "file,js-file,js-module"
+ })
+ .send(code);
+ } catch (error) {
+ console.error(error);
+
+ const errorName = error.constructor.name;
+ const errorMessage = error.message.replace(
+ /^.*?\/unpkg-.+?\//,
+ `/${req.packageSpec}/`
+ );
+ const codeFrame = error.codeFrame;
+ const debugInfo = `${errorName}: ${errorMessage}\n\n${codeFrame}`;
+
+ res
+ .status(500)
+ .type("text")
+ .send(
+ `Cannot generate module for ${req.packageSpec}${
+ req.filename
+ }\n\n${debugInfo}`
+ );
+ }
+}
+
+module.exports = serveJavaScriptModule;
diff --git a/server/actions/serveMainPage.js b/server/actions/serveMainPage.js
index 9bb3f09..028f0a6 100644
--- a/server/actions/serveMainPage.js
+++ b/server/actions/serveMainPage.js
@@ -1,13 +1,29 @@
-const MainPage = require("../components/MainPage");
+const MainPage = require("../client/MainPage");
const renderPage = require("../utils/renderPage");
+const globalScripts =
+ process.env.NODE_ENV === "production"
+ ? [
+ "/react@16.4.1/umd/react.production.min.js",
+ "/react-dom@16.4.1/umd/react-dom.production.min.js",
+ "/react-router-dom@4.3.1/umd/react-router-dom.min.js"
+ ]
+ : [
+ "/react@16.4.1/umd/react.development.js",
+ "/react-dom@16.4.1/umd/react-dom.development.js",
+ "/react-router-dom@4.3.1/umd/react-router-dom.js"
+ ];
+
function serveMainPage(req, res) {
- res.send(
- renderPage(MainPage, {
- scripts: req.assets.getScripts("main"),
- styles: req.assets.getStyles("main")
- })
- );
+ const scripts = globalScripts.concat(req.assets.getScripts("main"));
+ const styles = req.assets.getStyles("main");
+
+ const html = renderPage(MainPage, {
+ scripts: scripts,
+ styles: styles
+ });
+
+ res.send(html);
}
module.exports = serveMainPage;
diff --git a/server/actions/serveMetadata.js b/server/actions/serveMetadata.js
new file mode 100644
index 0000000..e9449a2
--- /dev/null
+++ b/server/actions/serveMetadata.js
@@ -0,0 +1,44 @@
+const path = require("path");
+
+const addLeadingSlash = require("../utils/addLeadingSlash");
+
+function getMatchingEntries(entry, entries) {
+ const dirname = entry.name || ".";
+
+ return Object.keys(entries)
+ .filter(name => entry.name !== name && path.dirname(name) === dirname)
+ .map(name => entries[name]);
+}
+
+function getMetadata(entry, entries) {
+ const metadata = {
+ path: addLeadingSlash(entry.name),
+ type: entry.type
+ };
+
+ if (entry.type === "file") {
+ metadata.contentType = entry.contentType;
+ metadata.integrity = entry.integrity;
+ metadata.lastModified = entry.lastModified;
+ metadata.size = entry.size;
+ } else if (entry.type === "directory") {
+ metadata.files = getMatchingEntries(entry, entries).map(e =>
+ getMetadata(e, entries)
+ );
+ }
+
+ return metadata;
+}
+
+function serveMetadata(req, res) {
+ const metadata = getMetadata(req.entry, req.entries);
+
+ res
+ .set({
+ "Cache-Control": "public,max-age=31536000", // 1 year
+ "Cache-Tag": "meta"
+ })
+ .send(metadata);
+}
+
+module.exports = serveMetadata;
diff --git a/server/actions/serveStaticFile.js b/server/actions/serveStaticFile.js
new file mode 100644
index 0000000..3a382ad
--- /dev/null
+++ b/server/actions/serveStaticFile.js
@@ -0,0 +1,26 @@
+const path = require("path");
+const etag = require("etag");
+
+const getContentTypeHeader = require("../utils/getContentTypeHeader");
+
+function serveStaticFile(req, res) {
+ const tags = ["file"];
+
+ const ext = path.extname(req.entry.name).substr(1);
+ if (ext) {
+ tags.push(`${ext}-file`);
+ }
+
+ res
+ .set({
+ "Content-Length": req.entry.size,
+ "Content-Type": getContentTypeHeader(req.entry.contentType),
+ "Cache-Control": "public,max-age=31536000", // 1 year
+ "Last-Modified": req.entry.lastModified,
+ ETag: etag(req.entry.content),
+ "Cache-Tag": tags.join(",")
+ })
+ .send(req.entry.content);
+}
+
+module.exports = serveStaticFile;
diff --git a/client/.babelrc b/server/client/.babelrc
similarity index 100%
rename from client/.babelrc
rename to server/client/.babelrc
diff --git a/client/.eslintrc b/server/client/.eslintrc
similarity index 100%
rename from client/.eslintrc
rename to server/client/.eslintrc
diff --git a/server/client/MainPage.js b/server/client/MainPage.js
new file mode 100644
index 0000000..bfb1532
--- /dev/null
+++ b/server/client/MainPage.js
@@ -0,0 +1,56 @@
+const React = require("react");
+const PropTypes = require("prop-types");
+
+const h = require("./utils/createHTML");
+const x = require("./utils/execScript");
+
+function MainPage({ title, description, scripts, styles, data, content }) {
+ return (
+
+
+
+
+
+
+
+
+ {styles.map(s => )}
+ {x(
+ "window.Promise || document.write('\\x3Cscript src=\"/_polyfills/es6-promise.min.js\">\\x3C/script>\\x3Cscript>ES6Promise.polyfill()\\x3C/script>')"
+ )}
+ {x(
+ "window.fetch || document.write('\\x3Cscript src=\"/_polyfills/fetch.min.js\">\\x3C/script>')"
+ )}
+ {x(`window.__DATA__ = ${JSON.stringify(data)}`)}
+ {title}
+
+
+
+ {scripts.map(s => )}
+
+
+ );
+}
+
+MainPage.propTypes = {
+ title: PropTypes.string,
+ description: PropTypes.string,
+ scripts: PropTypes.arrayOf(PropTypes.string),
+ styles: PropTypes.arrayOf(PropTypes.string),
+ data: PropTypes.any,
+ content: PropTypes.string
+};
+
+MainPage.defaultProps = {
+ title: "UNPKG",
+ description: "The CDN for everything on npm",
+ scripts: [],
+ styles: [],
+ data: {},
+ content: ""
+};
+
+module.exports = MainPage;
diff --git a/server/client/autoIndex.css b/server/client/autoIndex.css
new file mode 100644
index 0000000..d88876d
--- /dev/null
+++ b/server/client/autoIndex.css
@@ -0,0 +1,8 @@
+body {
+ font-size: 14px;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
+ Arial, sans-serif;
+ line-height: 1.7;
+ padding: 0px 10px 5px;
+ color: #000000;
+}
diff --git a/server/client/autoIndex.js b/server/client/autoIndex.js
new file mode 100644
index 0000000..20bd322
--- /dev/null
+++ b/server/client/autoIndex.js
@@ -0,0 +1,10 @@
+require("./autoIndex.css");
+
+const React = require("react");
+const ReactDOM = require("react-dom");
+
+const App = require("./autoIndex/App");
+
+const props = window.__DATA__ || {};
+
+ReactDOM.hydrate(, document.getElementById("root"));
diff --git a/server/client/autoIndex/App.css b/server/client/autoIndex/App.css
new file mode 100644
index 0000000..deee47e
--- /dev/null
+++ b/server/client/autoIndex/App.css
@@ -0,0 +1,23 @@
+.app {
+ max-width: 900px;
+ margin: 0 auto;
+}
+
+.app-header {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.app-version-selector {
+ line-height: 2.25em;
+ float: right;
+}
+.app-version-selector select {
+ font-size: 1em;
+}
+
+.app-address {
+ text-align: right;
+}
diff --git a/server/client/autoIndex/App.js b/server/client/autoIndex/App.js
new file mode 100644
index 0000000..f8393d8
--- /dev/null
+++ b/server/client/autoIndex/App.js
@@ -0,0 +1,77 @@
+require("./App.css");
+
+const React = require("react");
+
+const DirectoryListing = require("./DirectoryListing");
+
+class App extends React.Component {
+ static defaultProps = {
+ availableVersions: []
+ };
+
+ handleChange = event => {
+ window.location.href = window.location.href.replace(
+ "@" + this.props.packageVersion,
+ "@" + event.target.value
+ );
+ };
+
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ {this.props.packageName}@{this.props.packageVersion}
+
+
+ );
+ }
+}
+
+if (process.env.NODE_ENV === "development") {
+ const PropTypes = require("prop-types");
+
+ const entryType = PropTypes.object;
+
+ App.propTypes = {
+ packageName: PropTypes.string.isRequired,
+ packageVersion: PropTypes.string.isRequired,
+ availableVersions: PropTypes.arrayOf(PropTypes.string),
+ filename: PropTypes.string.isRequired,
+ entry: entryType.isRequired,
+ entries: PropTypes.objectOf(entryType).isRequired
+ };
+}
+
+module.exports = App;
diff --git a/server/client/autoIndex/DirectoryListing.css b/server/client/autoIndex/DirectoryListing.css
new file mode 100644
index 0000000..0a3f7ee
--- /dev/null
+++ b/server/client/autoIndex/DirectoryListing.css
@@ -0,0 +1,17 @@
+.directory-listing table {
+ width: 100%;
+ border-collapse: collapse;
+ font: 0.85em Monaco, monospace;
+}
+
+.directory-listing tr.even {
+ background-color: #eee;
+}
+
+.directory-listing th {
+ text-align: left;
+}
+.directory-listing th,
+.directory-listing td {
+ padding: 0.5em 1em;
+}
diff --git a/server/client/autoIndex/DirectoryListing.js b/server/client/autoIndex/DirectoryListing.js
new file mode 100644
index 0000000..23e7b32
--- /dev/null
+++ b/server/client/autoIndex/DirectoryListing.js
@@ -0,0 +1,126 @@
+require("./DirectoryListing.css");
+
+const React = require("react");
+const formatBytes = require("pretty-bytes");
+const sortBy = require("sort-by");
+
+function getDirname(name) {
+ return (
+ name
+ .split("/")
+ .slice(0, -1)
+ .join("/") || "."
+ );
+}
+
+function getMatchingEntries(entry, entries) {
+ const dirname = entry.name || ".";
+
+ return Object.keys(entries)
+ .filter(name => entry.name !== name && getDirname(name) === dirname)
+ .map(name => entries[name]);
+}
+
+function getRelativeName(base, name) {
+ return base.length ? name.substr(base.length + 1) : name;
+}
+
+function DirectoryListing({ filename, entry, entries }) {
+ const rows = [];
+
+ if (filename !== "/") {
+ rows.push(
+
+
+
+ ..
+
+ |
+ - |
+ - |
+ - |
+
+ );
+ }
+
+ const matchingEntries = getMatchingEntries(entry, entries);
+
+ matchingEntries
+ .filter(({ type }) => type === "directory")
+ .sort(sortBy("name"))
+ .forEach(({ name }) => {
+ const relName = getRelativeName(entry.name, name);
+ const href = relName + "/";
+
+ rows.push(
+
+
+
+ {href}
+
+ |
+ - |
+ - |
+ - |
+
+ );
+ });
+
+ matchingEntries
+ .filter(({ type }) => type === "file")
+ .sort(sortBy("name"))
+ .forEach(({ name, size, contentType, lastModified }) => {
+ const relName = getRelativeName(entry.name, name);
+
+ rows.push(
+
+
+
+ {relName}
+
+ |
+ {contentType} |
+ {formatBytes(size)} |
+ {lastModified} |
+
+ );
+ });
+
+ return (
+
+
+
+
+ Name |
+ Type |
+ Size |
+ Last Modified |
+
+
+
+ {rows.map((row, index) =>
+ React.cloneElement(row, {
+ className: index % 2 ? "odd" : "even"
+ })
+ )}
+
+
+
+ );
+}
+
+if (process.env.NODE_ENV === "development") {
+ const PropTypes = require("prop-types");
+
+ const entryType = PropTypes.shape({
+ name: PropTypes.string.isRequired
+ });
+
+ DirectoryListing.propTypes = {
+ filename: PropTypes.string.isRequired,
+ entry: entryType.isRequired,
+ entries: PropTypes.objectOf(entryType).isRequired
+ };
+}
+
+module.exports = DirectoryListing;
diff --git a/client/main.css b/server/client/main.css
similarity index 100%
rename from client/main.css
rename to server/client/main.css
diff --git a/server/client/main.js b/server/client/main.js
new file mode 100644
index 0000000..2d55aa6
--- /dev/null
+++ b/server/client/main.js
@@ -0,0 +1,8 @@
+require("./main.css");
+
+const React = require("react");
+const ReactDOM = require("react-dom");
+
+const App = require("./main/App");
+
+ReactDOM.render(, document.getElementById("root"));
diff --git a/client/main/About.css b/server/client/main/About.css
similarity index 100%
rename from client/main/About.css
rename to server/client/main/About.css
diff --git a/server/client/main/About.js b/server/client/main/About.js
new file mode 100644
index 0000000..1f4bdb7
--- /dev/null
+++ b/server/client/main/About.js
@@ -0,0 +1,12 @@
+require("./About.css");
+
+const React = require("react");
+
+const h = require("../utils/createHTML");
+const markup = require("./About.md");
+
+function About() {
+ return ;
+}
+
+module.exports = About;
diff --git a/client/main/About.md b/server/client/main/About.md
similarity index 100%
rename from client/main/About.md
rename to server/client/main/About.md
diff --git a/server/client/main/App.js b/server/client/main/App.js
new file mode 100644
index 0000000..f0b8263
--- /dev/null
+++ b/server/client/main/App.js
@@ -0,0 +1,14 @@
+const React = require("react");
+const { HashRouter } = require("react-router-dom");
+
+const Layout = require("./Layout");
+
+function App() {
+ return (
+
+
+
+ );
+}
+
+module.exports = App;
diff --git a/client/main/CloudflareLogo.png b/server/client/main/CloudflareLogo.png
similarity index 100%
rename from client/main/CloudflareLogo.png
rename to server/client/main/CloudflareLogo.png
diff --git a/client/main/HerokuLogo.png b/server/client/main/HerokuLogo.png
similarity index 100%
rename from client/main/HerokuLogo.png
rename to server/client/main/HerokuLogo.png
diff --git a/client/main/Home.css b/server/client/main/Home.css
similarity index 100%
rename from client/main/Home.css
rename to server/client/main/Home.css
diff --git a/server/client/main/Home.js b/server/client/main/Home.js
new file mode 100644
index 0000000..d3c12ba
--- /dev/null
+++ b/server/client/main/Home.js
@@ -0,0 +1,12 @@
+require("./Home.css");
+
+const React = require("react");
+
+const h = require("../utils/createHTML");
+const markup = require("./Home.md");
+
+function Home() {
+ return ;
+}
+
+module.exports = Home;
diff --git a/client/main/Home.md b/server/client/main/Home.md
similarity index 100%
rename from client/main/Home.md
rename to server/client/main/Home.md
diff --git a/client/main/Layout.css b/server/client/main/Layout.css
similarity index 100%
rename from client/main/Layout.css
rename to server/client/main/Layout.css
diff --git a/client/main/Layout.js b/server/client/main/Layout.js
similarity index 88%
rename from client/main/Layout.js
rename to server/client/main/Layout.js
index eed1b18..16382b1 100644
--- a/client/main/Layout.js
+++ b/server/client/main/Layout.js
@@ -1,14 +1,14 @@
-import "./Layout.css";
+require("./Layout.css");
-import React from "react";
-import PropTypes from "prop-types";
-import { Motion, spring } from "react-motion";
-import { Switch, Route, Link, withRouter } from "react-router-dom";
+const React = require("react");
+const PropTypes = require("prop-types");
+const { Switch, Route, Link, withRouter } = require("react-router-dom");
+const { Motion, spring } = require("react-motion");
-import WindowSize from "./WindowSize";
-import About from "./About";
-import Stats from "./Stats";
-import Home from "./Home";
+const WindowSize = require("./WindowSize");
+const About = require("./About");
+const Stats = require("./Stats");
+const Home = require("./Home");
class Layout extends React.Component {
static propTypes = {
@@ -132,4 +132,4 @@ class Layout extends React.Component {
}
}
-export default withRouter(Layout);
+module.exports = withRouter(Layout);
diff --git a/client/main/Stats.css b/server/client/main/Stats.css
similarity index 100%
rename from client/main/Stats.css
rename to server/client/main/Stats.css
diff --git a/client/main/Stats.js b/server/client/main/Stats.js
similarity index 95%
rename from client/main/Stats.js
rename to server/client/main/Stats.js
index 85b75f6..f072e31 100644
--- a/client/main/Stats.js
+++ b/server/client/main/Stats.js
@@ -1,14 +1,14 @@
-import "./Stats.css";
+require("./Stats.css");
-import React from "react";
-import PropTypes from "prop-types";
-import formatBytes from "pretty-bytes";
-import formatDate from "date-fns/format";
-import parseDate from "date-fns/parse";
-import { continents, countries } from "countries-list";
+const React = require("react");
+const PropTypes = require("prop-types");
+const formatBytes = require("pretty-bytes");
+const formatDate = require("date-fns/format");
+const parseDate = require("date-fns/parse");
+const { continents, countries } = require("countries-list");
-import formatNumber from "../utils/formatNumber";
-import formatPercent from "../utils/formatPercent";
+const formatNumber = require("../utils/formatNumber");
+const formatPercent = require("../utils/formatPercent");
function getCountriesByContinent(continent) {
return Object.keys(countries).filter(
@@ -320,4 +320,4 @@ class Stats extends React.Component {
}
}
-export default Stats;
+module.exports = Stats;
diff --git a/client/main/WindowSize.js b/server/client/main/WindowSize.js
similarity index 72%
rename from client/main/WindowSize.js
rename to server/client/main/WindowSize.js
index 06faeb0..6e9e529 100644
--- a/client/main/WindowSize.js
+++ b/server/client/main/WindowSize.js
@@ -1,8 +1,8 @@
-import React from "react";
-import PropTypes from "prop-types";
+const React = require("react");
+const PropTypes = require("prop-types");
-import addEvent from "../utils/addEvent";
-import removeEvent from "../utils/removeEvent";
+const addEvent = require("../utils/addEvent");
+const removeEvent = require("../utils/removeEvent");
const resizeEvent = "resize";
@@ -32,4 +32,4 @@ class WindowSize extends React.Component {
}
}
-export default WindowSize;
+module.exports = WindowSize;
diff --git a/client/utils/addEvent.js b/server/client/utils/addEvent.js
similarity index 88%
rename from client/utils/addEvent.js
rename to server/client/utils/addEvent.js
index d476647..c49fa5f 100644
--- a/client/utils/addEvent.js
+++ b/server/client/utils/addEvent.js
@@ -6,4 +6,4 @@ function addEvent(node, type, handler) {
}
}
-export default addEvent;
+module.exports = addEvent;
diff --git a/server/client/utils/createHTML.js b/server/client/utils/createHTML.js
new file mode 100644
index 0000000..41ad70b
--- /dev/null
+++ b/server/client/utils/createHTML.js
@@ -0,0 +1,5 @@
+function createHTML(code) {
+ return { __html: code };
+}
+
+module.exports = createHTML;
diff --git a/server/client/utils/execScript.js b/server/client/utils/execScript.js
new file mode 100644
index 0000000..b422444
--- /dev/null
+++ b/server/client/utils/execScript.js
@@ -0,0 +1,9 @@
+const React = require("react");
+
+const h = require("./createHTML");
+
+function execScript(code) {
+ return ;
+}
+
+module.exports = execScript;
diff --git a/server/client/utils/formatNumber.js b/server/client/utils/formatNumber.js
new file mode 100644
index 0000000..b85f318
--- /dev/null
+++ b/server/client/utils/formatNumber.js
@@ -0,0 +1,12 @@
+function formatNumber(n) {
+ const digits = String(n).split("");
+ const groups = [];
+
+ while (digits.length) {
+ groups.unshift(digits.splice(-3).join(""));
+ }
+
+ return groups.join(",");
+}
+
+module.exports = formatNumber;
diff --git a/server/client/utils/formatPercent.js b/server/client/utils/formatPercent.js
new file mode 100644
index 0000000..38f7d23
--- /dev/null
+++ b/server/client/utils/formatPercent.js
@@ -0,0 +1,5 @@
+function formatPercent(n, fixed = 1) {
+ return String((n.toPrecision(2) * 100).toFixed(fixed));
+}
+
+module.exports = formatPercent;
diff --git a/server/client/utils/parseNumber.js b/server/client/utils/parseNumber.js
new file mode 100644
index 0000000..70120d7
--- /dev/null
+++ b/server/client/utils/parseNumber.js
@@ -0,0 +1,5 @@
+function parseNumber(s) {
+ return parseInt(s.replace(/,/g, ""), 10) || 0;
+}
+
+module.exports = parseNumber;
diff --git a/client/utils/removeEvent.js b/server/client/utils/removeEvent.js
similarity index 87%
rename from client/utils/removeEvent.js
rename to server/client/utils/removeEvent.js
index d2ee154..354ece9 100644
--- a/client/utils/removeEvent.js
+++ b/server/client/utils/removeEvent.js
@@ -6,4 +6,4 @@ function removeEvent(node, type, handler) {
}
}
-export default removeEvent;
+module.exports = removeEvent;
diff --git a/server/clientRuntime.js b/server/clientRuntime.js
new file mode 100644
index 0000000..e5a4a79
--- /dev/null
+++ b/server/clientRuntime.js
@@ -0,0 +1,9 @@
+// Use babel to compile JSX on the fly.
+require("babel-register")({
+ only: /server\/client/
+});
+
+// Ignore require("*.css") calls.
+require.extensions[".css"] = function() {
+ return {};
+};
diff --git a/server/components/DirectoryListing.js b/server/components/DirectoryListing.js
deleted file mode 100644
index 3705726..0000000
--- a/server/components/DirectoryListing.js
+++ /dev/null
@@ -1,102 +0,0 @@
-const path = require("path");
-const formatBytes = require("pretty-bytes");
-const sortBy = require("sort-by");
-
-const cloneElement = require("./utils/cloneElement");
-const e = require("./utils/createElement");
-
-function getMatchingEntries(entry, entries) {
- const dirname = entry.name || ".";
-
- return Object.keys(entries)
- .filter(name => entry.name !== name && path.dirname(name) === dirname)
- .map(name => entries[name]);
-}
-
-function getRelativeName(base, name) {
- return base.length ? name.substr(base.length + 1) : name;
-}
-
-function DirectoryListing({ filename, entry, entries }) {
- const rows = [];
-
- if (filename !== "/") {
- rows.push(
- e(
- "tr",
- { key: ".." },
- e("td", null, e("a", { title: "Parent directory", href: "../" }, "..")),
- e("td", null, "-"),
- e("td", null, "-"),
- e("td", null, "-")
- )
- );
- }
-
- const matchingEntries = getMatchingEntries(entry, entries);
-
- matchingEntries
- .filter(({ type }) => type === "directory")
- .sort(sortBy("name"))
- .forEach(({ name }) => {
- const relName = getRelativeName(entry.name, name);
- const href = relName + "/";
-
- rows.push(
- e(
- "tr",
- { key: name },
- e("td", null, e("a", { title: relName, href }, href)),
- e("td", null, "-"),
- e("td", null, "-"),
- e("td", null, "-")
- )
- );
- });
-
- matchingEntries
- .filter(({ type }) => type === "file")
- .sort(sortBy("name"))
- .forEach(({ name, size, contentType, lastModified }) => {
- const relName = getRelativeName(entry.name, name);
-
- rows.push(
- e(
- "tr",
- { key: name },
- e("td", null, e("a", { title: relName, href: relName }, relName)),
- e("td", null, contentType),
- e("td", null, formatBytes(size)),
- e("td", null, lastModified)
- )
- );
- });
-
- return e(
- "table",
- null,
- e(
- "thead",
- null,
- e(
- "tr",
- null,
- e("th", null, "Name"),
- e("th", null, "Type"),
- e("th", null, "Size"),
- e("th", null, "Last Modified")
- )
- ),
- e(
- "tbody",
- null,
- rows.map((row, index) =>
- cloneElement(row, {
- className: index % 2 ? "odd" : "even"
- })
- )
- )
- );
-}
-
-module.exports = DirectoryListing;
diff --git a/server/components/IndexPage.css b/server/components/IndexPage.css
deleted file mode 100644
index 1b2219c..0000000
--- a/server/components/IndexPage.css
+++ /dev/null
@@ -1,40 +0,0 @@
-body {
- font-size: 14px;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
- Arial, sans-serif;
- line-height: 1.7;
- padding: 0px 10px 5px;
- color: #000000;
-}
-
-table {
- width: 100%;
- border-collapse: collapse;
- font: 0.85em Monaco, monospace;
-}
-tr.even {
- background-color: #eee;
-}
-th {
- text-align: left;
-}
-th,
-td {
- padding: 0.25em 0.5em;
-}
-
-.content-wrapper {
- max-width: 900px;
- margin: 0 auto;
-}
-.version-wrapper {
- line-height: 2.25em;
- float: right;
-}
-#version {
- font-size: 1em;
-}
-
-address {
- text-align: right;
-}
diff --git a/server/components/IndexPage.js b/server/components/IndexPage.js
deleted file mode 100644
index 4fae1d8..0000000
--- a/server/components/IndexPage.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const semver = require("semver");
-
-const DirectoryListing = require("./DirectoryListing");
-const readCSS = require("./utils/readCSS");
-const e = require("./utils/createElement");
-const s = require("./utils/createStyle");
-const x = require("./utils/createScript");
-
-const IndexPageStyle = readCSS(__dirname, "IndexPage.css");
-const IndexPageScript = `
-var s = document.getElementById('version'), v = s.value;
-s.onchange = function () {
- window.location.href = window.location.href.replace('@' + v, '@' + s.value);
-};
-`;
-
-function byVersion(a, b) {
- return semver.lt(a, b) ? -1 : semver.gt(a, b) ? 1 : 0;
-}
-
-function IndexPage({ packageInfo, version, filename, entry, entries }) {
- const versions = Object.keys(packageInfo.versions).sort(byVersion);
- const options = versions.map(v =>
- e("option", { key: v, value: v }, `${packageInfo.name}@${v}`)
- );
-
- return e(
- "html",
- null,
- e(
- "head",
- null,
- e("meta", { charSet: "utf-8" }),
- e("title", null, `Index of ${filename}`),
- s(IndexPageStyle)
- ),
- e(
- "body",
- null,
- e(
- "div",
- { className: "content-wrapper" },
- e(
- "div",
- { className: "version-wrapper" },
- e("select", { id: "version", defaultValue: version }, options)
- ),
- e("h1", null, `Index of ${filename}`),
- x(IndexPageScript),
- e("hr"),
- e(DirectoryListing, { filename, entry, entries }),
- e("hr"),
- e("address", null, `${packageInfo.name}@${version}`)
- )
- )
- );
-}
-
-module.exports = IndexPage;
diff --git a/server/components/MainPage.js b/server/components/MainPage.js
deleted file mode 100644
index 2538fe6..0000000
--- a/server/components/MainPage.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const PropTypes = require("prop-types");
-
-const e = require("./utils/createElement");
-const x = require("./utils/createScript");
-
-function MainPage({ title, description, scripts, styles, content }) {
- return e(
- "html",
- { lang: "en" },
- e(
- "head",
- null,
- e("meta", { charSet: "utf-8" }),
- e("title", null, title),
- e("meta", { httpEquiv: "X-UA-Compatible", content: "IE=edge,chrome=1" }),
- e("meta", { name: "description", content: description }),
- e("meta", {
- name: "viewport",
- content: "width=device-width,initial-scale=1,maximum-scale=1"
- }),
- e("meta", { name: "timestamp", content: new Date().toISOString() }),
- e("link", { rel: "shortcut icon", href: "/favicon.ico" }),
- x(
- "window.Promise || document.write('\\x3Cscript src=\"/_polyfills/es6-promise.min.js\">\\x3C/script>\\x3Cscript>ES6Promise.polyfill()\\x3C/script>')"
- ),
- x(
- "window.fetch || document.write('\\x3Cscript src=\"/_polyfills/fetch.min.js\">\\x3C/script>')"
- ),
- e("script", { src: "/react@16.4.1/umd/react.production.min.js" }),
- e("script", { src: "/react-dom@16.4.1/umd/react-dom.production.min.js" }),
- e("script", {
- src: "/react-router-dom@4.3.1/umd/react-router-dom.min.js"
- }),
- styles.map(s => e("link", { key: s, rel: "stylesheet", href: s }))
- ),
- e(
- "body",
- null,
- e("div", { id: "root", dangerouslySetInnerHTML: { __html: content } }),
- scripts.map(s => e("script", { key: s, src: s }))
- )
- );
-}
-
-MainPage.propTypes = {
- title: PropTypes.string,
- description: PropTypes.string,
- scripts: PropTypes.arrayOf(PropTypes.string),
- styles: PropTypes.arrayOf(PropTypes.string),
- content: PropTypes.string
-};
-
-MainPage.defaultProps = {
- title: "UNPKG",
- description: "The CDN for everything on npm",
- scripts: [],
- styles: [],
- content: ""
-};
-
-module.exports = MainPage;
diff --git a/server/components/utils/cloneElement.js b/server/components/utils/cloneElement.js
deleted file mode 100644
index 8ed90e5..0000000
--- a/server/components/utils/cloneElement.js
+++ /dev/null
@@ -1,2 +0,0 @@
-const React = require("react");
-module.exports = React.cloneElement;
diff --git a/server/components/utils/createElement.js b/server/components/utils/createElement.js
deleted file mode 100644
index 7a82c28..0000000
--- a/server/components/utils/createElement.js
+++ /dev/null
@@ -1,2 +0,0 @@
-const React = require("react");
-module.exports = React.createElement;
diff --git a/server/components/utils/createScript.js b/server/components/utils/createScript.js
deleted file mode 100644
index 6a910ce..0000000
--- a/server/components/utils/createScript.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const createElement = require("./createElement");
-
-function createScript(code) {
- return createElement("script", { dangerouslySetInnerHTML: { __html: code } });
-}
-
-module.exports = createScript;
diff --git a/server/components/utils/createStyle.js b/server/components/utils/createStyle.js
deleted file mode 100644
index 64d4fff..0000000
--- a/server/components/utils/createStyle.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const createElement = require("./createElement");
-
-function createStyle(code) {
- return createElement("style", { dangerouslySetInnerHTML: { __html: code } });
-}
-
-module.exports = createStyle;
diff --git a/server/components/utils/readCSS.js b/server/components/utils/readCSS.js
deleted file mode 100644
index 422bf8e..0000000
--- a/server/components/utils/readCSS.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const fs = require("fs");
-const path = require("path");
-const csso = require("csso");
-
-function readCSS(...args) {
- return csso.minify(fs.readFileSync(path.resolve(...args), "utf8")).css;
-}
-
-module.exports = readCSS;
diff --git a/server/utils/getContentTypeHeader.js b/server/utils/getContentTypeHeader.js
new file mode 100644
index 0000000..adf03a4
--- /dev/null
+++ b/server/utils/getContentTypeHeader.js
@@ -0,0 +1,5 @@
+function getContentTypeHeader(type) {
+ return type === "application/javascript" ? type + "; charset=utf-8" : type;
+}
+
+module.exports = getContentTypeHeader;
diff --git a/server/utils/renderPage.js b/server/utils/renderPage.js
index a5ae2df..acfe4a5 100644
--- a/server/utils/renderPage.js
+++ b/server/utils/renderPage.js
@@ -4,11 +4,8 @@ const ReactDOMServer = require("react-dom/server");
const doctype = "";
function renderPage(page, props) {
- const html = ReactDOMServer.renderToStaticMarkup(
- React.createElement(page, props)
- );
-
- return doctype + html;
+ const element = React.createElement(page, props);
+ return doctype + ReactDOMServer.renderToStaticMarkup(element);
}
module.exports = renderPage;
diff --git a/webpack.config.js b/webpack.config.js
index c62dca9..ebdeca9 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,9 +1,11 @@
const path = require("path");
const webpack = require("webpack");
+const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: {
- main: path.resolve(__dirname, "client/main.js")
+ main: path.resolve(__dirname, "./server/client/main.js"),
+ autoIndex: path.resolve(__dirname, "./server/client/autoIndex.js")
},
externals: {
@@ -21,7 +23,13 @@ module.exports = {
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, use: "babel-loader" },
- { test: /\.css$/, use: ["style-loader", "css-loader"] },
+ {
+ test: /\.css$/,
+ use: ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: "css-loader"
+ })
+ },
{ test: /\.md$/, use: ["html-loader", "markdown-loader"] },
{ test: /\.png$/, use: "file-loader" }
]
@@ -32,7 +40,8 @@ module.exports = {
"process.env.NODE_ENV": JSON.stringify(
process.env.NODE_ENV || "development"
)
- })
+ }),
+ new ExtractTextPlugin("[name]-[hash:8].css")
],
devtool:
diff --git a/yarn.lock b/yarn.lock
index 0b0337d..8b10069 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -132,7 +132,7 @@ ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
-ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0:
+ajv@^5.0.0, ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
@@ -363,6 +363,12 @@ async@^2.1.2, async@^2.1.4:
dependencies:
lodash "^4.14.0"
+async@^2.4.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
+ dependencies:
+ lodash "^4.17.10"
+
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -426,6 +432,30 @@ babel-core@^6.0.0, babel-core@^6.26.0:
slash "^1.0.0"
source-map "^0.5.6"
+babel-core@^6.26.3:
+ version "6.26.3"
+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207"
+ dependencies:
+ babel-code-frame "^6.26.0"
+ babel-generator "^6.26.0"
+ babel-helpers "^6.24.1"
+ babel-messages "^6.23.0"
+ babel-register "^6.26.0"
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-traverse "^6.26.0"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+ convert-source-map "^1.5.1"
+ debug "^2.6.9"
+ json5 "^0.5.1"
+ lodash "^4.17.4"
+ minimatch "^3.0.4"
+ path-is-absolute "^1.0.1"
+ private "^0.1.8"
+ slash "^1.0.0"
+ source-map "^0.5.7"
+
babel-eslint@^8.0.3:
version "8.2.1"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.1.tgz#136888f3c109edc65376c23ebf494f36a3e03951"
@@ -780,8 +810,8 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015
babel-template "^6.24.1"
babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a"
+ version "6.26.2"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3"
dependencies:
babel-plugin-transform-strict-mode "^6.24.1"
babel-runtime "^6.26.0"
@@ -913,9 +943,9 @@ babel-plugin-transform-react-jsx@^6.24.1:
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-react-remove-prop-types@^0.4.13:
- version "0.4.13"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.13.tgz#331cfc05099a808238311d78319c27460d481189"
+babel-plugin-transform-react-remove-prop-types@^0.4.14:
+ version "0.4.14"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.14.tgz#d3bf0ab39bd491c6670e71abd8642d4e6caae919"
babel-plugin-transform-regenerator@^6.22.0:
version "6.26.0"
@@ -930,9 +960,9 @@ babel-plugin-transform-strict-mode@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
-babel-preset-env@^1.6.1:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48"
+babel-preset-env@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a"
dependencies:
babel-plugin-check-es2015-constants "^6.22.0"
babel-plugin-syntax-trailing-function-commas "^6.22.0"
@@ -961,7 +991,7 @@ babel-preset-env@^1.6.1:
babel-plugin-transform-es2015-unicode-regex "^6.22.0"
babel-plugin-transform-exponentiation-operator "^6.22.0"
babel-plugin-transform-regenerator "^6.22.0"
- browserslist "^2.1.2"
+ browserslist "^3.2.6"
invariant "^2.2.2"
semver "^5.3.0"
@@ -1317,12 +1347,12 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7"
-browserslist@^2.1.2:
- version "2.11.3"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2"
+browserslist@^3.2.6:
+ version "3.2.8"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6"
dependencies:
- caniuse-lite "^1.0.30000792"
- electron-to-chromium "^1.3.30"
+ caniuse-lite "^1.0.30000844"
+ electron-to-chromium "^1.3.47"
bser@^2.0.0:
version "2.0.0"
@@ -1456,9 +1486,9 @@ caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000808"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000808.tgz#30dfd83009d5704f02dffb37725068ed12a366bb"
-caniuse-lite@^1.0.30000792:
- version "1.0.30000808"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000808.tgz#7d759b5518529ea08b6705a19e70dbf401628ffc"
+caniuse-lite@^1.0.30000844:
+ version "1.0.30000865"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000865.tgz#70026616e8afe6e1442f8bb4e1092987d81a2f25"
capture-exit@^1.2.0:
version "1.2.0"
@@ -1799,7 +1829,7 @@ content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
-convert-source-map@^1.4.0, convert-source-map@^1.5.0:
+convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
@@ -1956,13 +1986,6 @@ css-selector-tokenizer@^0.7.0:
fastparse "^1.1.1"
regexpu-core "^1.0.0"
-css-tree@1.0.0-alpha.27:
- version "1.0.0-alpha.27"
- resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.27.tgz#f211526909c7dc940843d83b9376ed98ddb8de47"
- dependencies:
- mdn-data "^1.0.0"
- source-map "^0.5.3"
-
cssesc@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
@@ -2004,12 +2027,6 @@ cssesc@^0.1.0:
postcss-value-parser "^3.2.3"
postcss-zindex "^2.0.1"
-csso@^3.1.1:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.0.tgz#acdbba5719e2c87bc801eadc032764b2e4b9d4e7"
- dependencies:
- css-tree "1.0.0-alpha.27"
-
csso@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85"
@@ -2297,10 +2314,14 @@ ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30:
+electron-to-chromium@^1.2.7:
version "1.3.33"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.33.tgz#bf00703d62a7c65238136578c352d6c5c042a545"
+electron-to-chromium@^1.3.47:
+ version "1.3.52"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.52.tgz#d2d9f1270ba4a3b967b831c40ef71fb4d9ab5ce0"
+
elliptic@^6.0.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
@@ -2787,6 +2808,15 @@ extglob@^2.0.2, extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
+extract-text-webpack-plugin@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7"
+ dependencies:
+ async "^2.4.1"
+ loader-utils "^1.1.0"
+ schema-utils "^0.3.0"
+ webpack-sources "^1.0.1"
+
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
@@ -4558,7 +4588,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-lodash@^4.13.1:
+lodash@^4.13.1, lodash@^4.17.10:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
@@ -4666,10 +4696,6 @@ md5@^2.2.1:
crypt "~0.0.1"
is-buffer "~1.1.1"
-mdn-data@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.0.tgz#a7056319da95a2d0881267d7263075042eb061e2"
-
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -5780,7 +5806,7 @@ pretty-format@^22.4.0, pretty-format@^22.4.3:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
-private@^0.1.6, private@^0.1.7, private@~0.1.5:
+private@^0.1.6, private@^0.1.7, private@^0.1.8, private@~0.1.5:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@@ -6443,6 +6469,12 @@ sax@^1.2.4, sax@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
+schema-utils@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"
+ dependencies:
+ ajv "^5.0.0"
+
select-hose@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"