├── .gitignore ├── .prettierrc ├── deploy.sh ├── package.json ├── .gcloudignore ├── LICENSE ├── README.md ├── index.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | *.log 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set +e 4 | 5 | gcloud functions deploy pdfByURL \ 6 | --runtime=nodejs14 \ 7 | --memory=1024MB \ 8 | --trigger-http \ 9 | --timeout=30s 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shuttlepdf", 3 | "version": "3.0.0", 4 | "main": "index.js", 5 | "repository": "https://github.com/courtsite/shuttlepdf", 6 | "author": "Courtsite ", 7 | "license": "MIT", 8 | "engines": { 9 | "node": ">=12 <=14" 10 | }, 11 | "dependencies": { 12 | "puppeteer": "^10.4.0" 13 | }, 14 | "devDependencies": { 15 | "prettier": "^2.4.1" 16 | }, 17 | "scripts": { 18 | "fmt": "prettier --write *.js" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gcloudignore: -------------------------------------------------------------------------------- 1 | # This file specifies files that are *not* uploaded to Google Cloud Platform 2 | # using gcloud. It follows the same syntax as .gitignore, with the addition of 3 | # "#!include" directives (which insert the entries of the given .gitignore-style 4 | # file at that point). 5 | # 6 | # For more information, run: 7 | # $ gcloud topic gcloudignore 8 | # 9 | .gcloudignore 10 | # If you would like to upload your .git directory, .gitignore file or files 11 | # from your .gitignore file, remove the corresponding line 12 | # below: 13 | .git 14 | .gitignore 15 | 16 | node_modules 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Courtsite Web Solutions 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shuttlepdf 2 | 3 | 📃 Smashingly simple, and scalable _("serverless")_ HTML to PDF conversions using Google Cloud Functions, and Puppeteer. 4 | 5 | 6 | ## Getting Started 7 | 8 | ### Prerequisites 9 | 10 | - Ensure you have `gcloud` installed: 11 | - MacOS: `brew cask install google-cloud-sdk` 12 | - Others: https://cloud.google.com/sdk/gcloud 13 | - Ensure you have authenticated with Google Cloud: `gcloud init` 14 | - (Optional) Set your current working project: `gcloud config set project ` 15 | 16 | ### Deployment 17 | 18 | 1. Clone / download a copy of this repository 19 | 2. Run `./deploy.sh` 20 | 3. Enter yes for "Allow unauthenticated invocations of new function" (unless you want to expose your function privately, and in other ways) 21 | 4. Test it out! e.g. `https://-.cloudfunctions.net/pdfByURL?url=https://www.bbc.co.uk` 22 | 23 | Update `deploy.sh` to suit your needs (e.g. higher timeouts, different region, more memory, etc). 24 | 25 | ### Performance 26 | 27 | It is worth mentioning that the average processing time for a standard web page (using the default `1024MB` set in `deploy.sh`) is between 5-15s. 28 | 29 | This can potentially be improved by increasing the memory (as doing so will increase the CPU alongside it). 30 | 31 | If you are dealing with lots of requests or if you require lower latencies, you may want to consider running a serverful converter, e.g. https://github.com/gotenberg/gotenberg 32 | 33 | We also suggest pairing the serverful converter with a workflow engine like [Temporal](https://temporal.io/) if you have relatively complex processing pipelines or if you require strong guarantees (SLAs) around conversions. 34 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { URL } = require("url"); 2 | const puppeteer = require("puppeteer"); 3 | let page; 4 | 5 | async function getBrowserPage() { 6 | const browser = await puppeteer.launch({ 7 | args: [ 8 | "--allow-running-insecure-content", 9 | "--disable-background-networking", 10 | "--disable-default-apps", 11 | "--disable-dev-shm-usage", 12 | "--disable-extensions", 13 | "--disable-gpu", 14 | "--disable-new-tab-first-run", 15 | "--disable-notifications", 16 | "--disable-sync", 17 | "--disable-translate", 18 | "--font-render-hinting=none", 19 | "--headless", 20 | "--hide-scrollbars", 21 | "--ignore-certificate-errors", 22 | "--metrics-recording-only", 23 | "--mute-audio", 24 | "--no-default-browser-check", 25 | "--no-first-run", 26 | "--no-sandbox", 27 | "--no-startup-window", 28 | "--no-zygote", 29 | "--safebrowsing-disable-auto-update", 30 | ], 31 | }); 32 | return browser.newPage(); 33 | } 34 | 35 | exports.pdfByURL = async (req, res) => { 36 | const acceptedMethods = ["GET", "POST"]; 37 | if (acceptedMethods.indexOf(req.method.toUpperCase()) === -1) { 38 | return res 39 | .status(400) 40 | .send( 41 | `invalid HTTP method: ${req.method} (only GET or POST allowed)` 42 | ); 43 | } 44 | 45 | let parsedUrl = null; 46 | try { 47 | parsedUrl = new URL(req.query.url); 48 | } catch (err) { 49 | return res.status(400).send(`invalid URL: ${req.query.url}`); 50 | } 51 | 52 | if (!page) { 53 | page = await getBrowserPage(); 54 | } 55 | 56 | await page.goto(parsedUrl.toString()); 57 | 58 | const mediaType = req.query.mediaType || "screen"; 59 | await page.emulateMediaType(mediaType); 60 | 61 | const pdfBuffer = await page.pdf({ printBackground: true }); 62 | 63 | res.set("Content-Type", "application/pdf"); 64 | res.status(200).send(pdfBuffer); 65 | }; 66 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node@*": 6 | version "14.14.10" 7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.10.tgz#5958a82e41863cfc71f2307b3748e3491ba03785" 8 | integrity sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ== 9 | 10 | "@types/yauzl@^2.9.1": 11 | version "2.9.1" 12 | resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af" 13 | integrity sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA== 14 | dependencies: 15 | "@types/node" "*" 16 | 17 | agent-base@6: 18 | version "6.0.2" 19 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" 20 | integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== 21 | dependencies: 22 | debug "4" 23 | 24 | balanced-match@^1.0.0: 25 | version "1.0.0" 26 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 27 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 28 | 29 | base64-js@^1.3.1: 30 | version "1.5.1" 31 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 32 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 33 | 34 | bl@^4.0.3: 35 | version "4.0.3" 36 | resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" 37 | integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== 38 | dependencies: 39 | buffer "^5.5.0" 40 | inherits "^2.0.4" 41 | readable-stream "^3.4.0" 42 | 43 | brace-expansion@^1.1.7: 44 | version "1.1.11" 45 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 46 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 47 | dependencies: 48 | balanced-match "^1.0.0" 49 | concat-map "0.0.1" 50 | 51 | buffer-crc32@~0.2.3: 52 | version "0.2.13" 53 | resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" 54 | integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= 55 | 56 | buffer@^5.2.1, buffer@^5.5.0: 57 | version "5.7.1" 58 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" 59 | integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== 60 | dependencies: 61 | base64-js "^1.3.1" 62 | ieee754 "^1.1.13" 63 | 64 | chownr@^1.1.1: 65 | version "1.1.4" 66 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" 67 | integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== 68 | 69 | concat-map@0.0.1: 70 | version "0.0.1" 71 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 72 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 73 | 74 | debug@4, debug@4.3.1, debug@^4.1.1: 75 | version "4.3.1" 76 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" 77 | integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== 78 | dependencies: 79 | ms "2.1.2" 80 | 81 | devtools-protocol@0.0.901419: 82 | version "0.0.901419" 83 | resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.901419.tgz#79b5459c48fe7e1c5563c02bd72f8fec3e0cebcd" 84 | integrity sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ== 85 | 86 | end-of-stream@^1.1.0, end-of-stream@^1.4.1: 87 | version "1.4.4" 88 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 89 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 90 | dependencies: 91 | once "^1.4.0" 92 | 93 | extract-zip@2.0.1: 94 | version "2.0.1" 95 | resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" 96 | integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== 97 | dependencies: 98 | debug "^4.1.1" 99 | get-stream "^5.1.0" 100 | yauzl "^2.10.0" 101 | optionalDependencies: 102 | "@types/yauzl" "^2.9.1" 103 | 104 | fd-slicer@~1.1.0: 105 | version "1.1.0" 106 | resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" 107 | integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= 108 | dependencies: 109 | pend "~1.2.0" 110 | 111 | find-up@^4.0.0: 112 | version "4.1.0" 113 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" 114 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== 115 | dependencies: 116 | locate-path "^5.0.0" 117 | path-exists "^4.0.0" 118 | 119 | fs-constants@^1.0.0: 120 | version "1.0.0" 121 | resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" 122 | integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== 123 | 124 | fs.realpath@^1.0.0: 125 | version "1.0.0" 126 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 127 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 128 | 129 | get-stream@^5.1.0: 130 | version "5.2.0" 131 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" 132 | integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== 133 | dependencies: 134 | pump "^3.0.0" 135 | 136 | glob@^7.1.3: 137 | version "7.1.6" 138 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 139 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 140 | dependencies: 141 | fs.realpath "^1.0.0" 142 | inflight "^1.0.4" 143 | inherits "2" 144 | minimatch "^3.0.4" 145 | once "^1.3.0" 146 | path-is-absolute "^1.0.0" 147 | 148 | https-proxy-agent@5.0.0: 149 | version "5.0.0" 150 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" 151 | integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== 152 | dependencies: 153 | agent-base "6" 154 | debug "4" 155 | 156 | ieee754@^1.1.13: 157 | version "1.2.1" 158 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 159 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 160 | 161 | inflight@^1.0.4: 162 | version "1.0.6" 163 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 164 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 165 | dependencies: 166 | once "^1.3.0" 167 | wrappy "1" 168 | 169 | inherits@2, inherits@^2.0.3, inherits@^2.0.4: 170 | version "2.0.4" 171 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 172 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 173 | 174 | locate-path@^5.0.0: 175 | version "5.0.0" 176 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" 177 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== 178 | dependencies: 179 | p-locate "^4.1.0" 180 | 181 | minimatch@^3.0.4: 182 | version "3.0.4" 183 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 184 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 185 | dependencies: 186 | brace-expansion "^1.1.7" 187 | 188 | minimist@^1.2.5: 189 | version "1.2.5" 190 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 191 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 192 | 193 | mkdirp@^0.5.1: 194 | version "0.5.5" 195 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 196 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 197 | dependencies: 198 | minimist "^1.2.5" 199 | 200 | ms@2.1.2: 201 | version "2.1.2" 202 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 203 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 204 | 205 | node-fetch@2.6.1: 206 | version "2.6.1" 207 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" 208 | integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== 209 | 210 | once@^1.3.0, once@^1.3.1, once@^1.4.0: 211 | version "1.4.0" 212 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 213 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 214 | dependencies: 215 | wrappy "1" 216 | 217 | p-limit@^2.2.0: 218 | version "2.3.0" 219 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" 220 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== 221 | dependencies: 222 | p-try "^2.0.0" 223 | 224 | p-locate@^4.1.0: 225 | version "4.1.0" 226 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" 227 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== 228 | dependencies: 229 | p-limit "^2.2.0" 230 | 231 | p-try@^2.0.0: 232 | version "2.2.0" 233 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 234 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 235 | 236 | path-exists@^4.0.0: 237 | version "4.0.0" 238 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 239 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 240 | 241 | path-is-absolute@^1.0.0: 242 | version "1.0.1" 243 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 244 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 245 | 246 | pend@~1.2.0: 247 | version "1.2.0" 248 | resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" 249 | integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= 250 | 251 | pkg-dir@4.2.0: 252 | version "4.2.0" 253 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" 254 | integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== 255 | dependencies: 256 | find-up "^4.0.0" 257 | 258 | prettier@^2.4.1: 259 | version "2.4.1" 260 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" 261 | integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== 262 | 263 | progress@2.0.1: 264 | version "2.0.1" 265 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" 266 | integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== 267 | 268 | proxy-from-env@1.1.0: 269 | version "1.1.0" 270 | resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" 271 | integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== 272 | 273 | pump@^3.0.0: 274 | version "3.0.0" 275 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 276 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 277 | dependencies: 278 | end-of-stream "^1.1.0" 279 | once "^1.3.1" 280 | 281 | puppeteer@^10.4.0: 282 | version "10.4.0" 283 | resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-10.4.0.tgz#a6465ff97fda0576c4ac29601406f67e6fea3dc7" 284 | integrity sha512-2cP8mBoqnu5gzAVpbZ0fRaobBWZM8GEUF4I1F6WbgHrKV/rz7SX8PG2wMymZgD0wo0UBlg2FBPNxlF/xlqW6+w== 285 | dependencies: 286 | debug "4.3.1" 287 | devtools-protocol "0.0.901419" 288 | extract-zip "2.0.1" 289 | https-proxy-agent "5.0.0" 290 | node-fetch "2.6.1" 291 | pkg-dir "4.2.0" 292 | progress "2.0.1" 293 | proxy-from-env "1.1.0" 294 | rimraf "3.0.2" 295 | tar-fs "2.0.0" 296 | unbzip2-stream "1.3.3" 297 | ws "7.4.6" 298 | 299 | readable-stream@^3.1.1, readable-stream@^3.4.0: 300 | version "3.6.0" 301 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 302 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 303 | dependencies: 304 | inherits "^2.0.3" 305 | string_decoder "^1.1.1" 306 | util-deprecate "^1.0.1" 307 | 308 | rimraf@3.0.2: 309 | version "3.0.2" 310 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 311 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 312 | dependencies: 313 | glob "^7.1.3" 314 | 315 | safe-buffer@~5.2.0: 316 | version "5.2.1" 317 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 318 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 319 | 320 | string_decoder@^1.1.1: 321 | version "1.3.0" 322 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 323 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 324 | dependencies: 325 | safe-buffer "~5.2.0" 326 | 327 | tar-fs@2.0.0: 328 | version "2.0.0" 329 | resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad" 330 | integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== 331 | dependencies: 332 | chownr "^1.1.1" 333 | mkdirp "^0.5.1" 334 | pump "^3.0.0" 335 | tar-stream "^2.0.0" 336 | 337 | tar-stream@^2.0.0: 338 | version "2.2.0" 339 | resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" 340 | integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== 341 | dependencies: 342 | bl "^4.0.3" 343 | end-of-stream "^1.4.1" 344 | fs-constants "^1.0.0" 345 | inherits "^2.0.3" 346 | readable-stream "^3.1.1" 347 | 348 | through@^2.3.8: 349 | version "2.3.8" 350 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 351 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 352 | 353 | unbzip2-stream@1.3.3: 354 | version "1.3.3" 355 | resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a" 356 | integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg== 357 | dependencies: 358 | buffer "^5.2.1" 359 | through "^2.3.8" 360 | 361 | util-deprecate@^1.0.1: 362 | version "1.0.2" 363 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 364 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 365 | 366 | wrappy@1: 367 | version "1.0.2" 368 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 369 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 370 | 371 | ws@7.4.6: 372 | version "7.4.6" 373 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" 374 | integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== 375 | 376 | yauzl@^2.10.0: 377 | version "2.10.0" 378 | resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" 379 | integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= 380 | dependencies: 381 | buffer-crc32 "~0.2.3" 382 | fd-slicer "~1.1.0" 383 | --------------------------------------------------------------------------------