From 78179c5901ba79f8daefe52b899247277c2a5d46 Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Thu, 12 Nov 2020 18:43:24 -0500 Subject: [PATCH] run AMP server-side optimizer via Netlify build plugin (#263) --- .eslintrc.json | 11 +- netlify.toml | 11 +- package.json | 2 +- .../netlify-plugin-amp-optimizer/.gitignore | 3 + plugins/netlify-plugin-amp-optimizer/LICENSE | 21 ++++ .../netlify-plugin-amp-optimizer/README.md | 3 + plugins/netlify-plugin-amp-optimizer/index.js | 31 +++++ .../netlify-plugin-amp-optimizer/manifest.yml | 1 + .../netlify-plugin-amp-optimizer/package.json | 22 ++++ plugins/netlify-plugin-cache/.gitignore | 3 + plugins/netlify-plugin-cache/LICENSE | 21 ++++ plugins/netlify-plugin-cache/README.md | 48 ++++++++ plugins/netlify-plugin-cache/index.js | 37 ++++++ plugins/netlify-plugin-cache/manifest.yml | 5 + plugins/netlify-plugin-cache/package.json | 45 +++++++ yarn.lock | 110 +++++++++--------- 16 files changed, 315 insertions(+), 59 deletions(-) create mode 100644 plugins/netlify-plugin-amp-optimizer/.gitignore create mode 100644 plugins/netlify-plugin-amp-optimizer/LICENSE create mode 100644 plugins/netlify-plugin-amp-optimizer/README.md create mode 100644 plugins/netlify-plugin-amp-optimizer/index.js create mode 100644 plugins/netlify-plugin-amp-optimizer/manifest.yml create mode 100644 plugins/netlify-plugin-amp-optimizer/package.json create mode 100644 plugins/netlify-plugin-cache/.gitignore create mode 100644 plugins/netlify-plugin-cache/LICENSE create mode 100644 plugins/netlify-plugin-cache/README.md create mode 100644 plugins/netlify-plugin-cache/index.js create mode 100644 plugins/netlify-plugin-cache/manifest.yml create mode 100644 plugins/netlify-plugin-cache/package.json diff --git a/.eslintrc.json b/.eslintrc.json index 9f9a83e2..fc631120 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -11,11 +11,18 @@ "es6": true }, "overrides": [{ - "files": ["functions/**.js"], + "files": ["{functions,plugins}/**/*.js"], "parserOptions": { "ecmaVersion": 8, "sourceType": "module" + }, + "env": { + "browser": false + }, + "rules": { + "compat/compat": "off" } }], - "rules": {} + "rules": {}, + "ignorePatterns": ["public/**"] } diff --git a/netlify.toml b/netlify.toml index 5d526d46..84c7441b 100644 --- a/netlify.toml +++ b/netlify.toml @@ -40,12 +40,21 @@ # don't launch browser automatically autoLaunch = false +# Enable local Netlify build plugins: +[[plugins]] + package = "@netlify/plugin-local-install-core" +# Optimize AMP pages server-side: +# https://github.com/ampproject/amp-toolbox/tree/master/packages/optimizer +# https://github.com/martinbean/netlify-plugin-amp-server-side-rendering +[[plugins]] + package = "./plugins/netlify-plugin-amp-optimizer" # Cache resoures between builds: # https://github.com/jakejarvis/netlify-plugin-cache [[plugins]] - package = "netlify-plugin-cache" + package = "./plugins/netlify-plugin-cache" [plugins.inputs] paths = ["resources", "public", "_vendor"] +# List cached resources for debugging: # [[plugins]] # package = "netlify-plugin-debug-cache" diff --git a/package.json b/package.json index ad56890f..66939737 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "minify:img": "find './public' -type d ! -path './public/vendor*' | xargs -n1 -P8 -I{} imagemin '{}/*' --plugin=jpegoptim --plugin.jpegoptim.progressive --plugin.jpegoptim.stripAll --plugin=pngquant --plugin.pngquant.quality={0.1,0.3} --plugin.pngquant.speed=1 --plugin.pngquant.strip --plugin=gifsicle --plugin=svgo --out-dir='{}' > /dev/null 2>&1 || true", "lint": "run-s lint:**", "lint:scss": "stylelint 'assets/sass/**/*.scss' --syntax scss", - "lint:js": "eslint 'assets/js/**/*.js' 'functions/**/*.js'", + "lint:js": "eslint '**/*.js'", "lint:md": "markdownlint 'content/**/*.md'", "lint:prettier": "prettier --check ." }, diff --git a/plugins/netlify-plugin-amp-optimizer/.gitignore b/plugins/netlify-plugin-amp-optimizer/.gitignore new file mode 100644 index 00000000..db2cc52f --- /dev/null +++ b/plugins/netlify-plugin-amp-optimizer/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +package-lock.json +npm-debug.log* diff --git a/plugins/netlify-plugin-amp-optimizer/LICENSE b/plugins/netlify-plugin-amp-optimizer/LICENSE new file mode 100644 index 00000000..0042aa8a --- /dev/null +++ b/plugins/netlify-plugin-amp-optimizer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Martin Bean + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/netlify-plugin-amp-optimizer/README.md b/plugins/netlify-plugin-amp-optimizer/README.md new file mode 100644 index 00000000..f28675b7 --- /dev/null +++ b/plugins/netlify-plugin-amp-optimizer/README.md @@ -0,0 +1,3 @@ +# Netlify Plugin: AMP Optimizer + +Lightly modified from [martinbean/netlify-plugin-amp-server-side-rendering](https://github.com/martinbean/netlify-plugin-amp-server-side-rendering). diff --git a/plugins/netlify-plugin-amp-optimizer/index.js b/plugins/netlify-plugin-amp-optimizer/index.js new file mode 100644 index 00000000..8f86aee3 --- /dev/null +++ b/plugins/netlify-plugin-amp-optimizer/index.js @@ -0,0 +1,31 @@ +const ampOptimizer = require("@ampproject/toolbox-optimizer").create({ + verbose: true, +}); +const fs = require("fs"); +const glob = require("glob"); + +module.exports = { + onPostBuild: async ({ constants, utils }) => { + // Hugo renders my AMP pages as amp.html right next to each page's index.html + const pattern = constants.PUBLISH_DIR + "/**/amp.html"; + + const files = await new Promise((resolve, reject) => { + glob(pattern, { nodir: true }, (err, files) => { + err ? reject(err) : resolve(files); + }); + }); + + await Promise.all( + files.map(async (file) => { + const html = await fs.promises.readFile(file, "utf-8"); + const optimizedHtml = await ampOptimizer.transformHtml(html); + await fs.promises.writeFile(file, optimizedHtml); + }) + ); + + utils.status.show({ + title: `${files.length} AMP pages optimized`, + summary: "Great success! ⚡", + }); + }, +}; diff --git a/plugins/netlify-plugin-amp-optimizer/manifest.yml b/plugins/netlify-plugin-amp-optimizer/manifest.yml new file mode 100644 index 00000000..f5c24ba8 --- /dev/null +++ b/plugins/netlify-plugin-amp-optimizer/manifest.yml @@ -0,0 +1 @@ +name: netlify-plugin-amp-optimizer diff --git a/plugins/netlify-plugin-amp-optimizer/package.json b/plugins/netlify-plugin-amp-optimizer/package.json new file mode 100644 index 00000000..0e7fc08f --- /dev/null +++ b/plugins/netlify-plugin-amp-optimizer/package.json @@ -0,0 +1,22 @@ +{ + "name": "netlify-plugin-amp-optimizer", + "version": "1.0.0", + "description": "Render your AMP pages, server-side.", + "license": "MIT", + "author": { + "name": "Martin Bean", + "url": "https://martinbean.dev" + }, + "files": [ + "manifest.yml", + "index.js" + ], + "main": "index.js", + "dependencies": { + "@ampproject/toolbox-optimizer": "^2.x", + "glob": "^7.x" + }, + "engines": { + "node": ">=10.0" + } +} diff --git a/plugins/netlify-plugin-cache/.gitignore b/plugins/netlify-plugin-cache/.gitignore new file mode 100644 index 00000000..db2cc52f --- /dev/null +++ b/plugins/netlify-plugin-cache/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +package-lock.json +npm-debug.log* diff --git a/plugins/netlify-plugin-cache/LICENSE b/plugins/netlify-plugin-cache/LICENSE new file mode 100644 index 00000000..57b6e477 --- /dev/null +++ b/plugins/netlify-plugin-cache/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Jake Jarvis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/netlify-plugin-cache/README.md b/plugins/netlify-plugin-cache/README.md new file mode 100644 index 00000000..e9c3bade --- /dev/null +++ b/plugins/netlify-plugin-cache/README.md @@ -0,0 +1,48 @@ +# ⚡ Netlify Plugin: Custom Cache [![npm](https://img.shields.io/npm/v/netlify-plugin-cache?logo=npm&color=red)](https://www.npmjs.com/package/netlify-plugin-cache) ![CI](https://github.com/jakejarvis/netlify-plugin-cache/workflows/CI/badge.svg) + +A generic cache plugin for saving and restoring files and/or folders between Netlify builds for impressive speed improvements. Worry less about running out of build minutes! ⏰ + +Essentially, this plugin is a pretty wrapper around [Netlify's native cache utility](https://github.com/netlify/build/blob/master/packages/cache-utils/README.md) — it isn't tied to any specific static site generator (on purpose). + +## 💿 Install + +Add the following lines to your `netlify.toml`: + +```toml +[[plugins]] +package = "netlify-plugin-cache" + [plugins.inputs] + # Optional (but highly recommended). Defaults to [".cache"]. + paths = ["resources", "_vendor", "folder/file.md"] +``` + +This plugin only takes one input named `paths`: an array of files and/or directories relative to your project's root. These files/directories are restored before a build and saved in cache after a build **if it is successful**. + +**🚨 Important:** `paths` defaults to `[".cache"]`, but it's **highly recommended** you set this yourself based on the tool(s) you're using to generate your site. See examples below. + +Read more about plugin configuration at [the official Netlify Plugin docs](https://docs.netlify.com/configure-builds/build-plugins/#install-a-plugin). + +## 👩‍💻 Usage + +- **Hugo:** Caching the `resources` directory can speed up your build greatly if you [process](https://gohugo.io/content-management/image-processing/) a lot of images, or compile SASS/SCSS via Hugo pipes. You can also cache the `public` directory to avoid completely rebuilding the entire site on each deploy. [More info here.](https://gohugo.io/getting-started/directory-structure/#directory-structure-explained) +- **Gatsby:** By default, the `.cache` directory holds persistent data between builds. You can also cache the `dist` directory to avoid completely rebuilding the entire site on each deploy. [More info here.](https://www.gatsbyjs.org/docs/build-caching/) +- **Jekyll:** A caching API was added as of v4. The notoriously slow SSG can become (relatively) faster by caching the `.jekyll-cache` directory. [More info here.](https://jekyllrb.com/tutorials/cache-api/) +- **Next.js:** The `.next` directory holds the build output. [More info here.](https://nextjs.org/docs/api-reference/next.config.js/setting-a-custom-build-directory) +- **Anything else:** This is the reason I kept this plugin as generic as possible! Research the caching behavior of your static site generator (and how to customize it if necessary). Feel free to open a PR and list it here as well! + +## 🐛 Debugging + +This plugin doesn't provide a way to output a list of files that were cached or restored, because Netlify already provides an official plugin named [`netlify-plugin-debug-cache`](https://github.com/netlify-labs/netlify-plugin-debug-cache) to do exactly that. No need to re-invent the wheel! + +You can add the debug plugin **after** this plugin in your `netlify.toml`. (And yes, you need a `[[plugins]]` line for _each_ plugin you add.) + +```toml +[[plugins]] +package = "netlify-plugin-debug-cache" +``` + +The debug plugin will generate a file named `cache-output.json` at the root of your project's publish directory. [See an example file](https://infallible-wing-581e78.netlify.app/cache-output.json) or [learn more about this plugin](https://github.com/netlify-labs/netlify-plugin-debug-cache). + +## 📜 License + +This project is distributed under the [MIT license](LICENSE). diff --git a/plugins/netlify-plugin-cache/index.js b/plugins/netlify-plugin-cache/index.js new file mode 100644 index 00000000..c0cd0a0e --- /dev/null +++ b/plugins/netlify-plugin-cache/index.js @@ -0,0 +1,37 @@ +// Netlify Plugin: netlify-plugin-cache +// https://github.com/jakejarvis/netlify-plugin-cache +// +// This plugin is essentially a wrapper around Netlify's native `cache-utils`: +// https://github.com/netlify/build/blob/master/packages/cache-utils/README.md + +module.exports = { + // Try to restore cache before build begins, if it exists + onPreBuild: async ({ utils: { cache }, inputs }) => { + if (await cache.restore(inputs.paths)) { + const files = await cache.list(inputs.paths); + console.log(`Successfully restored: ${inputs.paths.join(", ")} ... ${files.length} files in total.`); + } else { + console.log(`A cache of '${inputs.paths.join(", ")}' doesn't exist (yet).`); + } + }, + + // Only save/update cache if build was successful + onSuccess: async ({ utils: { cache, status }, inputs }) => { + if (await cache.save(inputs.paths)) { + const files = await cache.list(inputs.paths); + console.log(`Successfully cached: ${inputs.paths.join(", ")} ... ${files.length} files in total.`); + + // Show success & more detail in deploy summary + status.show({ + title: `${files.length} files cached`, + summary: "These will be restored on the next build! ⚡", + text: `${inputs.paths.join(", ")}`, + }); + } else { + // This probably happened because the default `paths` is set, so provide instructions to fix + console.log(`Attempted to cache: ${inputs.paths.join(", ")} ... but failed. :(`); + console.log("Try setting the 'paths' input appropriately in your netlify.toml configuration."); + console.log("More details: https://jrvs.io/netlify-cache-usage"); + } + }, +}; diff --git a/plugins/netlify-plugin-cache/manifest.yml b/plugins/netlify-plugin-cache/manifest.yml new file mode 100644 index 00000000..334189ef --- /dev/null +++ b/plugins/netlify-plugin-cache/manifest.yml @@ -0,0 +1,5 @@ +name: netlify-plugin-cache +inputs: + - name: paths + description: Array of files and/or directories to cache between builds. + default: [".cache"] diff --git a/plugins/netlify-plugin-cache/package.json b/plugins/netlify-plugin-cache/package.json new file mode 100644 index 00000000..bd712a8f --- /dev/null +++ b/plugins/netlify-plugin-cache/package.json @@ -0,0 +1,45 @@ +{ + "name": "netlify-plugin-cache", + "version": "1.0.3", + "description": "Generic cache plugin for saving and restoring files and/or folders between Netlify builds", + "license": "MIT", + "author": { + "name": "Jake Jarvis", + "email": "jake@jarv.is", + "url": "http://jarv.is/" + }, + "homepage": "https://github.com/jakejarvis/netlify-plugin-cache#readme", + "bugs": "https://github.com/jakejarvis/netlify-plugin-cache/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/jakejarvis/netlify-plugin-cache.git" + }, + "main": "index.js", + "scripts": { + "build": "netlify build", + "test": "xo" + }, + "dependencies": {}, + "devDependencies": { + "netlify-cli": "*", + "xo": "~0.32.0" + }, + "engines": { + "node": ">=10.18" + }, + "keywords": [ + "netlify", + "netlify-plugin", + "cache", + "ci", + "build", + "plugin" + ], + "xo": { + "semicolon": false, + "space": 2, + "rules": { + "object-curly-spacing": 0 + } + } +} diff --git a/yarn.lock b/yarn.lock index 8c2fa8c4..977d0e25 100644 --- a/yarn.lock +++ b/yarn.lock @@ -907,14 +907,14 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/minimist@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" - integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" + integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== "@types/node@*": - version "14.14.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" - integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== + version "14.14.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.7.tgz#8ea1e8f8eae2430cf440564b98c6dfce1ec5945d" + integrity sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1372,13 +1372,13 @@ axios@^0.21.0: follow-redirects "^1.10.0" babel-loader@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" - integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + version "8.2.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.1.tgz#e53313254677e86f27536f5071d807e01d24ec00" + integrity sha512-dMF8sb2KQ8kJl21GUjkW1HWmcsL39GOV5vnzjqrCzEPNY0S0UfMLnumidiwIajDSBmKhYf5iRW+HXaM4cvCKBw== dependencies: find-cache-dir "^2.1.0" loader-utils "^1.4.0" - mkdirp "^0.5.3" + make-dir "^2.1.0" pify "^4.0.1" schema-utils "^2.6.5" @@ -1400,9 +1400,9 @@ balanced-match@^1.0.0: integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2, base64-js@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: version "0.11.2" @@ -1505,7 +1505,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== -bn.js@^5.1.1: +bn.js@^5.0.0, bn.js@^5.1.1: version "5.1.3" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== @@ -1599,11 +1599,11 @@ browserify-des@^1.0.0: safe-buffer "^5.1.2" browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: @@ -1797,11 +1797,11 @@ camelcase@^5.0.0, camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-db@^1.0.30001090: - version "1.0.30001156" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001156.tgz#279f2188d3f7a29313ec0e7e9efb600ca9c61418" - integrity sha512-L9vmkUDqH5QWgnB3RUukW1B5P6Vvkf44pjvaoPOUbIkchkUsq+vwXjzjQl9Hw3Ri8xS3XJmfm3H0UGyTx+s+Rg== + version "1.0.30001157" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001157.tgz#dbb52e098d98cd134b636ac771b8e825315a9850" + integrity sha512-ZzxFzQo5QCMNLhFdwfzKGlW6NyZWPiy1CC6TX4135SkejFq7wjge7ueV6IQifoLN6FcX4lLGpEif5h2JQqXNvg== -caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001154, caniuse-lite@^1.0.30001157: +caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157: version "1.0.30001157" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001157.tgz#2d11aaeb239b340bc1aa730eca18a37fdb07a9ab" integrity sha512-gOerH9Wz2IRZ2ZPdMfBvyOi3cjaz4O4dgNwPGzx8EhqAs4+2IL/O+fJsbt+znSigujoZG8bVcIAUM/I/E5K3MA== @@ -1979,9 +1979,9 @@ cli-truncate@^2.1.0: string-width "^4.2.0" cliui@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.3.tgz#ef180f26c8d9bff3927ee52428bfec2090427981" - integrity sha512-Gj3QHTkVMPKqwP3f7B4KPkBZRMR9r4rfi5bXFpg1a+Svvj8l7q5CnkBkVQzfxT5DFSsGk2+PascOgL0JYkL2kw== + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" strip-ansi "^6.0.0" @@ -2333,9 +2333,9 @@ css-tree@1.0.0-alpha.37: source-map "^0.6.1" css-tree@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0.tgz#21993fa270d742642a90409a2c0cb3ac0298adf6" - integrity sha512-CdVYz/Yuqw0VdKhXPBIgi8DO3NicJVYZNWeX9XcIuSp9ZoFT5IcleVRW07O5rMjdcx1mb+MEJPknTTEW7DdsYw== + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.1.tgz#7726678dfe2a57993a018d9dce519bf1760e3b6d" + integrity sha512-WroX+2MvsYcRGP8QA0p+rxzOniT/zpAoQ/DTKDSJzh5T3IQKUkFHeIIfgIapm2uaP178GWY3Mime1qbk8GO/tA== dependencies: mdn-data "2.0.12" source-map "^0.6.1" @@ -2586,18 +2586,18 @@ doctrine@^3.0.0: esutils "^2.0.2" doiuse@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/doiuse/-/doiuse-4.3.1.tgz#216006797c6725c745775dd1a0fc81fe3242fc73" - integrity sha512-aeAYA6UnodmjeooblVvkJSTeM3fHPNInuAACpHJEywZNyrXvPEXZWKDotRiWthEpqa0ZYtD+e0ZmW8Zeli7Z2g== + version "4.4.0" + resolved "https://registry.yarnpkg.com/doiuse/-/doiuse-4.4.0.tgz#d02541820a05b60ae69facbe2c1abd00513db7c2" + integrity sha512-+RbL+7ECpBzbX+GMnX3PXzc/t+ufvZV/q/ysES5U8i0VexgGKLezQPCVehKwzLH2pIFC0pISfPaSm69CxuEw6w== dependencies: - browserslist "^4.14.5" - caniuse-lite "^1.0.30001154" + browserslist "^4.14.7" + caniuse-lite "^1.0.30001157" css-rule-stream "^1.1.0" duplexer2 "0.0.2" jsonfilter "^1.1.2" ldjson-stream "^1.2.1" multimatch "^5.0.0" - postcss "^8.1.4" + postcss "^8.1.6" source-map "^0.7.3" through2 "^4.0.2" yargs "^16.1.0" @@ -2716,9 +2716,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.591: - version "1.3.592" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.592.tgz#4621521b223bf6e5469373528321e185d3c24670" - integrity sha512-kGNowksvqQiPb1pUSQKpd8JFoGPLxYOwduNRCqCxGh/2Q1qE2JdmwouCW41lUzDxOb/2RIV4lR0tVIfboWlO9A== + version "1.3.593" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.593.tgz#947ccf6dc8e013e2b053d2463ecd1043c164fcef" + integrity sha512-GvO7G1ZxvffnMvPCr4A7+iQPVuvpyqMrx2VWSERAjG+pHK6tmO9XqYdBfMIq9corRyi4bNImSDEiDvIoDb8HrA== elliptic@^6.5.3: version "6.5.3" @@ -4265,7 +4265,7 @@ is-callable@^1.1.4, is-callable@^1.2.2: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== -is-core-module@^2.0.0: +is-core-module@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.1.0.tgz#a4cc031d9b1aca63eecbd18a650e13cb4eeab946" integrity sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA== @@ -5037,7 +5037,7 @@ make-dir@^1.0.0, make-dir@^1.2.0: dependencies: pify "^3.0.0" -make-dir@^2.0.0: +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -6331,7 +6331,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss@^6.x, postcss@^8.1.4, postcss@^8.x: +postcss@^6.x, postcss@^8.1.4, postcss@^8.1.6, postcss@^8.x: version "8.1.7" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.1.7.tgz#ff6a82691bd861f3354fd9b17b2332f88171233f" integrity sha512-llCQW1Pz4MOPwbZLmOddGM9eIJ8Bh7SZ2Oj5sxZva77uVaotYDsYTch1WBTNu7fUY0fpWp0fdt7uW40D4sRiiQ== @@ -6847,11 +6847,11 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2: - version "1.18.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" - integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== dependencies: - is-core-module "^2.0.0" + is-core-module "^2.1.0" path-parse "^1.0.6" responselike@1.0.2: @@ -8321,23 +8321,23 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -watchpack-chokidar2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" - integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== dependencies: chokidar "^2.1.8" watchpack@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.4.tgz#6e9da53b3c80bb2d6508188f5b200410866cd30b" - integrity sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg== + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: graceful-fs "^4.1.2" neo-async "^2.5.0" optionalDependencies: chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.0" + watchpack-chokidar2 "^2.0.1" wcwidth@^1.0.1: version "1.0.1" @@ -8500,9 +8500,9 @@ yargs-parser@^18.1.3: decamelize "^1.2.0" yargs-parser@^20.2.2: - version "20.2.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.3.tgz#92419ba867b858c868acf8bae9bf74af0dd0ce26" - integrity sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww== + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== yargs@^16.0.0, yargs@^16.1.0: version "16.1.0"