Verified Commit 1d8c9913 authored by Jelle van der Waa's avatar Jelle van der Waa 🚧
Browse files

Port the whole website to React

Use React to structurize the code better and allowing easier creation of
HTML elements and code reuse.
parent 5d02d804
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
......@@ -21,7 +21,8 @@ sass-watcher:
.PHONY: js-watcher
js-watcher:
$(YARN) run budo src/index.js:bundle.js --dir public --port $(PORT) --live -t babelify
# TODO: yarn run doesn't work..
./node_modules/.bin/budo src/index.js:bundle.js --dir public --port $(PORT) --live -- -t babelify
# Dist
......@@ -30,8 +31,10 @@ js-watcher:
dist:
@mkdir -p "dist/${PACKAGE_NAME}-${VERSION}"
cp -avf public/index.html "dist/${PACKAGE_NAME}-${VERSION}/index.html"
# TODO: cache-invalidation with version string replaced in html file
cp -avf public/favicon.ico "dist/${PACKAGE_NAME}-${VERSION}/favicon.ico"
$(SASS) -t compressed src/style.scss "dist/${PACKAGE_NAME}-${VERSION}/bundle.css"
$(YARN) run browserify src/index.js -o "dist/${PACKAGE_NAME}-${VERSION}/bundle.js"
$(YARN) run -s browserify -t babelify src/index.js | $(YARN) run -s uglifyjs > "dist/${PACKAGE_NAME}-${VERSION}/bundle.js"
cd dist && tar --owner=0 --group=0 -czvf ${PACKAGE_NAME}-${VERSION}.tar.gz "${PACKAGE_NAME}-${VERSION}"
......
......@@ -5,13 +5,19 @@
"author": "Jelle van der Waa",
"license": "MIT",
"private": true,
"dependencies": {
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/plugin-proposal-object-rest-spread": "^7.9.6",
"@babel/plugin-transform-react-jsx": "^7.9.4",
"@babel/preset-env": "^7.9.6",
"@babel/preset-react": "^7.9.4",
"babelify": "^10.0.0",
"budo": "^11.6.3",
"bulma": "^0.8.2"
}
"bulma": "^0.8.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"uglify-js": "^3.9.3"
},
"browserslist": "> 0.25%, not dead"
}
......@@ -9,24 +9,7 @@
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<section class="hero is-primary">
<div class="hero-body">
<div id="status" class="container">
<h1 class="title">Arch Linux Reproducible repository status</h1>
<p>Welcome to the official experimental Arch Linux <a href="https://github.com/kpcyrd/rebuilderd">rebuilderd</a> instance, this page shows the results of verification builds of official Arch Linux packages in the repositories in an effort to be fully reproducible. For more information read the <a href="https://reproducible-builds.org/">Reproducible Builds website</a> or join the <a href="ircs://chat.freenode.net/archlinux-reproducible">#archlinux-reproducible</a> IRC channel on <a href="https://freenode.net/">Freenode</a>.</p>
<br>
</div>
</div>
</section>
<section id="bad" class="section">
<div class="tile box has-background-danger">
<div class="content">
<p class='title is-5 has-text-white'>Unreproducible packages</p>
<ul id="packagesul">
</ul>
</div>
</div>
</section>
<div id="root"></div>
<footer class="footer">
<div class="content has-text-centered">
<p>
......
'use strict';
const React = require('react');
const {Header} = require('./Header');
const {Body} = require('./Body');
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
fetchFailed: false,
suites: []
};
}
render() {
const { fetchFailed, suites } = this.state;
return (
<React.Fragment>
<Header fetchFailed={fetchFailed} suites={suites}/>
<Body fetchFailed={fetchFailed} suites={suites}/>
</React.Fragment>
);
}
componentDidMount() {
const url = '/api/v0/pkgs/list';
fetch(url).then((response) => {
if (!response.ok) {
this.setState({fetchFailed: true});
throw new Error(response.statusText);
}
return response.json();
}).then((data) => {
const suites = {};
for (let pkg of data) {
if (pkg.suite in suites) {
suites[pkg.suite].push(pkg);
} else {
suites[pkg.suite] = [pkg];
}
}
const suiteList = [];
for (let repo of Object.keys(suites).sort()) {
suiteList.push({name: repo, pkgs: suites[repo]});
}
this.setState({suites: suiteList});
}).catch((error) => {
console.log(error);
this.setState({fetchFailed: true});
});
}
}
module.exports = {App};
'use strict';
const React = require('react');
const { Section } = require('./Section');
class Body extends React.Component {
render() {
const { fetchFailed, suites } = this.props;
return (
<React.Fragment>
{ fetchFailed &&
<section className="section">
<div className="tile box has-background-danger">
<div className="content has-text-centered">
<p className='title is-5 has-text-white'>An unexpected error occurred fetching the rebuild status</p>
</div>
</div>
</section>
}
{suites.map(suite =>
<Section key={suite.name} suite={suite}/>
)}
</React.Fragment>
)
}
}
module.exports = {Body};
'use strict';
const React = require('react');
class Header extends React.Component {
calculateSuiteStats(data) {
let good = 0;
let bad = 0;
let unknown = 0;
for (let pkg of data) {
switch (pkg.status) {
case 'GOOD':
good++;
break
case 'BAD':
bad++;
break
case 'UNKWN':
unknown++;
break
}
}
const percentage = (good / data.length * 100).toFixed(1);
return {good, bad, unknown, percentage};
}
render() {
const {fetchFailed, suites } = this.props;
const suitesStats = [];
for (let suite of suites) {
const {good, bad, unknown, percentage} = this.calculateSuiteStats(suite.pkgs);
suitesStats.push({name: suite.name, good, bad, unknown, percentage});
}
return (
<section className="hero is-primary">
<div className="hero-body">
<div id="status" className="container">
<h1 className="title">Arch Linux Reproducible status</h1>
<p>Welcome to the official experimental Arch Linux <a href="https://github.com/kpcyrd/rebuilderd">rebuilderd</a> instance, this page shows the results of verification builds of official Arch Linux packages in the repositories in an effort to be fully reproducible. For more information read the <a href="https://reproducible-builds.org/">Reproducible Builds website</a> or join the <a href="ircs://chat.freenode.net/archlinux-reproducible">#archlinux-reproducible</a> IRC channel on <a href="https://freenode.net/">Freenode</a>.</p>
<br/>
{!fetchFailed && suitesStats.map(function(repo, index) {
return <p key={ index }><a href={"#" + repo.name }>[{ repo.name }]</a> repository is { repo.percentage }% reproducible with { repo.bad } bad and { repo.unknown } unknown packages.</p>;
})}
</div>
</div>
</section>
);
}
}
module.exports = {Header};
'use strict';
const React = require('react');
class Section extends React.Component {
render() {
const { suite } = this.props;
return (
<section key={suite.name} id={suite.name} className="section">
<div className="tile box has-background-danger">
<div className="content">
<p className='title is-5 has-text-white'>{ suite.name }</p>
<ul>
{suite.pkgs.map(function(pkg) {
if (pkg.status == 'BAD') {
return <li key={pkg.name}><p className="subtitle is-6 has-text-white">{pkg.name}-{pkg.version}</p></li>
}
})}
</ul>
</div>
</div>
</section>
)
}
}
module.exports = {Section};
function displayBadPackages(suites) {
const packagesList = document.getElementById("packagesul");
const fragment = document.createDocumentFragment();
'use strict';
for (let suite of Object.values(suites).sort()) {
for (let pkg of suite) {
if (pkg.status == 'GOOD') {
continue
}
const React = require('react');
const ReactDOM = require('react-dom');
const li = document.createElement('li');
const p = document.createElement('p');
p.className = 'subtitle is-6 has-text-white';
p.textContent = `${pkg.suite} - ${pkg.name}-${pkg.version}`;
const { App } = require('./App');
li.appendChild(p);
fragment.appendChild(li);
}
}
packagesList.appendChild(fragment);
}
function calculateSuiteStats(data) {
let good = 0;
let bad = 0;
let unknown = 0;
for (pkg of data) {
switch (pkg.status) {
case 'GOOD':
good++;
break
case 'BAD':
bad++;
break
case 'UNKWN':
unknown++;
break
}
}
reproPercentage = (good / data.length * 100).toFixed(1);
return {good, bad, unknown, reproPercentage};
}
function displayStats(suites) {
const elem = document.getElementById("status");
const fragment = document.createDocumentFragment();
for (let suite of Object.values(suites).sort()) {
const {good, bad, unknown, reproPercentage} = calculateSuiteStats(suite);
const h2 = document.createElement('h2');
const suiteName = suite[0].suite;
h2.textContent = `[${suiteName}] repository is ${reproPercentage}% reproducible with ${bad} bad and ${unknown} unknown packages.`;
fragment.appendChild(h2);
}
elem.appendChild(fragment);
}
fetch(`/api/v0/pkgs/list`).then((response) => {
return response.json();
}).then((data) => {
const suites = {};
for (pkg of data) {
if (pkg.suite in suites) {
suites[pkg.suite].push(pkg);
} else {
suites[pkg.suite] = [pkg];
}
}
displayStats(suites);
displayBadPackages(suites);
}).catch(() => {
const elem = document.getElementById('status');
const div = document.createElement('div');
div.textContent = 'An unexpected erorr occurred fetching the rebuild status';
div.className = 'notification is-danger';
elem.appendChild(div);
const bad = document.getElementById('bad');
bad.innerHTML = '';
});
ReactDOM.render(<App />, document.getElementById('root'));
......@@ -8,8 +8,25 @@ $link: #212952;
@import "../node_modules/bulma/sass/elements/container.sass";
@import "../node_modules/bulma/sass/elements/box.sass";
@import "../node_modules/bulma/sass/elements/title.sass";
@import "../node_modules/bulma/sass/elements/notification.sass";
@import "../node_modules/bulma/sass/layout/footer.sass";
@import "../node_modules/bulma/sass/layout/hero.sass";
@import "../node_modules/bulma/sass/layout/section.sass";
@import "../node_modules/bulma/sass/grid/tiles.sass";
@media (min-width: 500px) {
ul {
columns: 2;
}
}
@media (min-width: 1024px) {
ul {
columns: 4;
}
}
@media (min-width: 2000px) {
ul {
columns: 8;
}
}
"use strict"
const path = require('path');
const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader'
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
// options...
}
}
]
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
// eslint options (if necessary)
},
}],
},
externals: {
'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? {
apiPrefix: ''
} : {
apiPrefix: '/repro'
}),
},
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/style.css'
}),
]
};
......@@ -50,6 +50,13 @@
lodash "^4.17.13"
source-map "^0.5.0"
"@babel/helper-annotate-as-pure@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz#f6d08acc6f70bbd59b436262553fb2e259a1a268"
integrity sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==
dependencies:
"@babel/types" "^7.10.1"
"@babel/helper-annotate-as-pure@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee"
......@@ -65,6 +72,23 @@
"@babel/helper-explode-assignable-expression" "^7.8.3"
"@babel/types" "^7.8.3"
"@babel/helper-builder-react-jsx-experimental@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz#9a7d58ad184d3ac3bafb1a452cec2bad7e4a0bc8"
integrity sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ==
dependencies:
"@babel/helper-annotate-as-pure" "^7.10.1"
"@babel/helper-module-imports" "^7.10.1"
"@babel/types" "^7.10.1"
"@babel/helper-builder-react-jsx@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.1.tgz#a327f0cf983af5554701b1215de54a019f09b532"
integrity sha512-KXzzpyWhXgzjXIlJU1ZjIXzUPdej1suE6vzqgImZ/cpAsR/CC8gUcX4EWRmDfWz/cs6HOCPMBIJ3nKoXt3BFuw==
dependencies:
"@babel/helper-annotate-as-pure" "^7.10.1"
"@babel/types" "^7.10.1"
"@babel/helper-compilation-targets@^7.9.6":
version "7.9.6"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz#1e05b7ccc9d38d2f8b40b458b380a04dcfadd38a"
......@@ -132,6 +156,13 @@
dependencies:
"@babel/types" "^7.8.3"
"@babel/helper-module-imports@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz#dd331bd45bccc566ce77004e9d05fe17add13876"
integrity sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==
dependencies:
"@babel/types" "^7.10.1"
"@babel/helper-module-imports@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498"
......@@ -164,6 +195,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670"
integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==
"@babel/helper-plugin-utils@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz#ec5a5cf0eec925b66c60580328b122c01230a127"
integrity sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==
"@babel/helper-regex@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.8.3.tgz#139772607d51b93f23effe72105b319d2a4c6965"
......@@ -207,6 +243,11 @@
dependencies:
"@babel/types" "^7.8.3"
"@babel/helper-validator-identifier@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5"
integrity sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==
"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5":
version "7.9.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80"
......@@ -340,6 +381,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
"@babel/plugin-syntax-jsx@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz#0ae371134a42b91d5418feb3c8c8d43e1565d2da"
integrity sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==
dependencies:
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9"
......@@ -567,6 +615,56 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.3"
"@babel/plugin-transform-react-display-name@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.1.tgz#e6a33f6d48dfb213dda5e007d0c7ff82b6a3d8ef"
integrity sha512-rBjKcVwjk26H3VX8pavMxGf33LNlbocMHdSeldIEswtQ/hrjyTG8fKKILW1cSkODyRovckN/uZlGb2+sAV9JUQ==
dependencies:
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-transform-react-jsx-development@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz#1ac6300d8b28ef381ee48e6fec430cc38047b7f3"
integrity sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg==
dependencies:
"@babel/helper-builder-react-jsx-experimental" "^7.10.1"
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-jsx" "^7.10.1"
"@babel/plugin-transform-react-jsx-self@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz#22143e14388d72eb88649606bb9e46f421bc3821"
integrity sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA==
dependencies:
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-jsx" "^7.10.1"
"@babel/plugin-transform-react-jsx-source@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz#30db3d4ee3cdebbb26a82a9703673714777a4273"
integrity sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA==
dependencies:
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-jsx" "^7.10.1"
"@babel/plugin-transform-react-jsx@^7.10.1", "@babel/plugin-transform-react-jsx@^7.9.4":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.1.tgz#91f544248ba131486decb5d9806da6a6e19a2896"
integrity sha512-MBVworWiSRBap3Vs39eHt+6pJuLUAaK4oxGc8g+wY+vuSJvLiEQjW1LSTqKb8OUPtDvHCkdPhk7d6sjC19xyFw==
dependencies:
"@babel/helper-builder-react-jsx" "^7.10.1"
"@babel/helper-builder-react-jsx-experimental" "^7.10.1"
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-jsx" "^7.10.1"
"@babel/plugin-transform-react-pure-annotations@^7.10.1":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.1.tgz#f5e7c755d3e7614d4c926e144f501648a5277b70"
integrity sha512-mfhoiai083AkeewsBHUpaS/FM1dmUENHBMpS/tugSJ7VXqXO5dCN1Gkint2YvM1Cdv1uhmAKt1ZOuAjceKmlLA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.10.1"
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-transform-regenerator@^7.8.7":
version "7.8.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8"
......@@ -703,6 +801,19 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
"@babel/preset-react@^7.9.4":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.1.tgz#e2ab8ae9a363ec307b936589f07ed753192de041"
integrity sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q==
dependencies:
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-transform-react-display-name" "^7.10.1"
"@babel/plugin-transform-react-jsx" "^7.10.1"
"@babel/plugin-transform-react-jsx-development" "^7.10.1"
"@babel/plugin-transform-react-jsx-self" "^7.10.1"
"@babel/plugin-transform-react-jsx-source" "^7.10.1"
"@babel/plugin-transform-react-pure-annotations" "^7.10.1"
"@babel/runtime@^7.8.4":
version "7.9.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f"
......@@ -734,6 +845,15 @@
globals "^11.1.0"
lodash "^4.17.13"
"@babel/types@^7.10.1":
version "7.10.2"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.2.tgz#30283be31cad0dbf6fb00bd40641ca0ea675172d"
integrity sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==
dependencies:
"@babel/helper-validator-identifier" "^7.10.1"
lodash "^4.17.13"
to-fast-properties "^2.0.0"
"@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5", "@babel/types@^7.9.6":
version "7.9.6"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.6.tgz#2c5502b427251e9de1bd2dff95add646d95cc9f7"
......@@ -1281,6 +1401,11 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0:
lodash.memoize "~3.0.3"
source-map "~0.5.3"
commander@~2.20.3:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"