├── .gitignore ├── .nowignore ├── LICENSE ├── README.md ├── now.json ├── package.json ├── src ├── card.ts ├── chromium.ts ├── file.ts ├── parser.ts ├── template.ts └── types.d.ts ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /.nowignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | LICENSE -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 ZEIT, Inc. 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OG Image 2 | 3 | To run locally: 4 | 5 | - `now dev` 6 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-og-image", 3 | "version": 2, 4 | "public": false, 5 | "builds": [ 6 | { 7 | "src": "src/card.ts", 8 | "use": "@now/node", 9 | "config": { "maxLambdaSize": "36mb" } 10 | } 11 | ], 12 | "routes": [{ "src": "/og.jpg", "dest": "/src/card.ts" }] 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generating-og-image", 3 | "version": "1.0.0", 4 | "description": "Generate an OG Image", 5 | "main": "dist/card.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "now-build": "tsc", 9 | "watch": "tsc --watch" 10 | }, 11 | "license": "MIT", 12 | "dependencies": { 13 | "chrome-aws-lambda": "2.0.2", 14 | "puppeteer-core": "2.0.0" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^13.5.1", 18 | "typescript": "3.7.5" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/card.ts: -------------------------------------------------------------------------------- 1 | import { IncomingMessage, ServerResponse } from "http"; 2 | import { parseReqs } from "./parser"; 3 | import { getHtml } from "./template"; 4 | import { writeTempFile } from "./file"; 5 | import { getScreenshot } from "./chromium"; 6 | 7 | const isDev = process.env.NOW_REGION === "dev1"; 8 | 9 | export default async function handler( 10 | req: IncomingMessage, 11 | res: ServerResponse 12 | ) { 13 | try { 14 | const parsedReqs = parseReqs(req); 15 | const html = getHtml(parsedReqs); 16 | 17 | const { title, author } = parsedReqs; 18 | const fileName = [title, author].join("-"); 19 | const filePath = await writeTempFile(fileName, html); 20 | const fileUrl = `file://${filePath}`; 21 | 22 | const file = await getScreenshot(fileUrl, isDev); 23 | 24 | res.statusCode = 200; 25 | res.setHeader("Content-Type", "image/jpeg"); 26 | res.setHeader( 27 | "Cache-Control", 28 | "public,immutable,no-transform,s-max-age=21600,max-age=21600" 29 | ); 30 | res.end(file); 31 | } catch (e) { 32 | res.statusCode = 500; 33 | res.setHeader("Content-Type", "text/html"); 34 | res.end("

Internal Error

Sorry, an error occurred.

"); 35 | console.error(e); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/chromium.ts: -------------------------------------------------------------------------------- 1 | import chrome from "chrome-aws-lambda"; 2 | import { launch } from "puppeteer-core"; 3 | 4 | const exePath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; 5 | 6 | interface Options { 7 | args: string[]; 8 | executablePath: string; 9 | headless: boolean; 10 | } 11 | 12 | async function getOptions(isDev: boolean) { 13 | let options: Options; 14 | if (isDev) { 15 | options = { 16 | args: [], 17 | executablePath: exePath, 18 | headless: true 19 | }; 20 | } else { 21 | options = { 22 | args: chrome.args, 23 | executablePath: await chrome.executablePath, 24 | headless: chrome.headless 25 | }; 26 | } 27 | return options; 28 | } 29 | 30 | export async function getScreenshot(url: string, isDev: boolean) { 31 | const options = await getOptions(isDev); 32 | const browser = await launch(options); 33 | const page = await browser.newPage(); 34 | await page.setViewport({ width: 1200, height: 630 }); 35 | await page.goto(url); 36 | return page.screenshot({ type: "jpeg", quality: 100 }); 37 | } 38 | -------------------------------------------------------------------------------- /src/file.ts: -------------------------------------------------------------------------------- 1 | import { createHash } from "crypto"; 2 | import { join } from "path"; 3 | import { tmpdir } from "os"; 4 | import { writeFile } from "fs"; 5 | import { promisify } from "util"; 6 | 7 | const promiseWriteFile = promisify(writeFile); 8 | 9 | export async function writeTempFile(fileName: string, html: string) { 10 | const hashedFileName = 11 | createHash("md5") 12 | .update(fileName) 13 | .digest("hex") + ".html"; 14 | 15 | const filePath = join(tmpdir(), hashedFileName); 16 | 17 | await promiseWriteFile(filePath, html); 18 | 19 | return filePath; 20 | } 21 | -------------------------------------------------------------------------------- /src/parser.ts: -------------------------------------------------------------------------------- 1 | import { IncomingMessage } from "http"; 2 | import { parse } from "url"; 3 | 4 | export function parseReqs(req: IncomingMessage) { 5 | const { query = {} } = parse(req.url || "", true); 6 | const { author, title, website, image } = query; 7 | 8 | if (Array.isArray(author)) { 9 | throw new Error("Author must be string"); 10 | } 11 | if (Array.isArray(title)) { 12 | throw new Error("Title must be string"); 13 | } 14 | if (Array.isArray(website)) { 15 | throw new Error("Website must be string"); 16 | } 17 | if (Array.isArray(image)) { 18 | throw new Error("Image must be string"); 19 | } 20 | 21 | const parsedReqs: ParsedReqs = { 22 | author, 23 | title, 24 | website, 25 | image 26 | }; 27 | 28 | console.log(JSON.stringify(parsedReqs)); 29 | 30 | return parsedReqs; 31 | } 32 | -------------------------------------------------------------------------------- /src/template.ts: -------------------------------------------------------------------------------- 1 | function getCss() { 2 | return ` 3 | /* http://meyerweb.com/eric/tools/css/reset/ 4 | v2.0 | 20110126 5 | License: none (public domain) 6 | */ 7 | html, body, div, span, applet, object, iframe, 8 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 9 | a, abbr, acronym, address, big, cite, code, 10 | del, dfn, em, img, ins, kbd, q, s, samp, 11 | small, strike, strong, sub, sup, tt, var, 12 | b, u, i, center, 13 | dl, dt, dd, ol, ul, li, 14 | fieldset, form, label, legend, 15 | table, caption, tbody, tfoot, thead, tr, th, td, 16 | article, aside, canvas, details, embed, 17 | figure, figcaption, footer, header, hgroup, 18 | menu, nav, output, ruby, section, summary, 19 | time, mark, audio, video { 20 | margin: 0; 21 | padding: 0; 22 | border: 0; 23 | font-size: 100%; 24 | font: inherit; 25 | vertical-align: baseline; 26 | } 27 | /* HTML5 display-role reset for older browsers */ 28 | article, aside, details, figcaption, figure, 29 | footer, header, hgroup, menu, nav, section { 30 | display: block; 31 | } 32 | body { 33 | line-height: 1; 34 | } 35 | ol, ul { 36 | list-style: none; 37 | } 38 | blockquote, q { 39 | quotes: none; 40 | } 41 | blockquote:before, blockquote:after, 42 | q:before, q:after { 43 | content: ''; 44 | content: none; 45 | } 46 | table { 47 | border-collapse: collapse; 48 | border-spacing: 0; 49 | } 50 | * { 51 | box-sizing: border-box; 52 | } 53 | body { 54 | background: #95adbe; 55 | height: 100vh; 56 | font-family: 'Barlow Condensed', sans-serif; 57 | font-size: 18px; 58 | padding: 20px; 59 | } 60 | .container { 61 | position: relative; 62 | height: calc(100vh - 40px); 63 | padding: 20px; 64 | background: #f8f8f8; 65 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); 66 | } 67 | .title { 68 | font-size: 8em; 69 | line-height: 1.05em; 70 | height: 3.15em; 71 | overflow: hidden; 72 | color: #313131; 73 | } 74 | .author { 75 | position: absolute; 76 | bottom: 0px; 77 | left: 0px; 78 | padding: 20px; 79 | font-size: 3em; 80 | color: #525252; 81 | } 82 | .author-image { 83 | width: 1.5em; 84 | border-radius: 50%; 85 | margin-bottom: -9px; 86 | } 87 | .website { 88 | position: absolute; 89 | bottom: 0px; 90 | right: 0px; 91 | padding: 20px; 92 | font-size: 2em; 93 | color: #525252; 94 | } 95 | `; 96 | } 97 | 98 | export function getHtml(parsedReqs: ParsedReqs) { 99 | const { author, title, website, image } = parsedReqs; 100 | 101 | return ` 102 | 103 | 104 | 105 | Generated Image 106 | 107 | 108 | 111 | 112 |
113 |
${title}
114 |
115 | 116 | ${author} 117 |
118 |
${website}
119 |
120 | 121 | 122 | `; 123 | } 124 | -------------------------------------------------------------------------------- /src/types.d.ts: -------------------------------------------------------------------------------- 1 | interface ParsedReqs { 2 | author: string; 3 | title: string; 4 | website: string; 5 | image: string; 6 | } 7 | 8 | declare module "puppeteer-core"; 9 | declare module "puppeteer"; 10 | 11 | type Browser = any; 12 | type ConnectOptions = any; 13 | type FetcherOptions = any; 14 | type BrowserFetcher = any; 15 | type ChromeArgOptions = any; 16 | type LaunchOptions = any; 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "commonjs", 5 | "target": "esnext", 6 | "moduleResolution": "node", 7 | "jsx": "react", 8 | "sourceMap": true, 9 | "strict": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "noImplicitReturns": true, 12 | "noEmitOnError": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "removeComments": true, 16 | "preserveConstEnums": true, 17 | "esModuleInterop": true 18 | }, 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node@^13.5.1": 6 | version "13.5.1" 7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-13.5.1.tgz#6fae50892d1841f4b38b298e2f78fb68c5960cb9" 8 | integrity sha512-Jj2W7VWQ2uM83f8Ls5ON9adxN98MvyJsMSASYFuSvrov8RMRY64Ayay7KV35ph1TSGIJ2gG9ZVDdEq3c3zaydA== 9 | 10 | agent-base@^4.3.0: 11 | version "4.3.0" 12 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" 13 | integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== 14 | dependencies: 15 | es6-promisify "^5.0.0" 16 | 17 | async-limiter@~1.0.0: 18 | version "1.0.0" 19 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" 20 | integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== 21 | 22 | balanced-match@^1.0.0: 23 | version "1.0.0" 24 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 25 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 26 | 27 | bl@^3.0.0: 28 | version "3.0.0" 29 | resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88" 30 | integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A== 31 | dependencies: 32 | readable-stream "^3.0.1" 33 | 34 | brace-expansion@^1.1.7: 35 | version "1.1.11" 36 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 37 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 38 | dependencies: 39 | balanced-match "^1.0.0" 40 | concat-map "0.0.1" 41 | 42 | buffer-from@^1.0.0: 43 | version "1.1.1" 44 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 45 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 46 | 47 | chownr@^1.1.1: 48 | version "1.1.3" 49 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" 50 | integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== 51 | 52 | chrome-aws-lambda@2.0.2: 53 | version "2.0.2" 54 | resolved "https://registry.yarnpkg.com/chrome-aws-lambda/-/chrome-aws-lambda-2.0.2.tgz#6f5ff829b0cf4623d09dc074af5ad06f65f2f6c4" 55 | integrity sha512-Aqgq5F93eJARkO+O/wD+2bCCFOVQNfA329sdPNl8ib0gsRjS00bAgTc9f5Mvto7H7yDuBcy0V3xJQZwMvmILUg== 56 | dependencies: 57 | lambdafs "^1.3.0" 58 | 59 | concat-map@0.0.1: 60 | version "0.0.1" 61 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 62 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 63 | 64 | concat-stream@1.6.2: 65 | version "1.6.2" 66 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" 67 | integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== 68 | dependencies: 69 | buffer-from "^1.0.0" 70 | inherits "^2.0.3" 71 | readable-stream "^2.2.2" 72 | typedarray "^0.0.6" 73 | 74 | core-util-is@~1.0.0: 75 | version "1.0.2" 76 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 77 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 78 | 79 | debug@2.6.9: 80 | version "2.6.9" 81 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 82 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 83 | dependencies: 84 | ms "2.0.0" 85 | 86 | debug@^3.1.0: 87 | version "3.2.6" 88 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 89 | integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 90 | dependencies: 91 | ms "^2.1.1" 92 | 93 | debug@^4.1.0: 94 | version "4.1.1" 95 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 96 | integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== 97 | dependencies: 98 | ms "^2.1.1" 99 | 100 | end-of-stream@^1.1.0, end-of-stream@^1.4.1: 101 | version "1.4.4" 102 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 103 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 104 | dependencies: 105 | once "^1.4.0" 106 | 107 | es6-promise@^4.0.3: 108 | version "4.2.8" 109 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 110 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 111 | 112 | es6-promisify@^5.0.0: 113 | version "5.0.0" 114 | resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" 115 | integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= 116 | dependencies: 117 | es6-promise "^4.0.3" 118 | 119 | extract-zip@^1.6.6: 120 | version "1.6.7" 121 | resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" 122 | integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= 123 | dependencies: 124 | concat-stream "1.6.2" 125 | debug "2.6.9" 126 | mkdirp "0.5.1" 127 | yauzl "2.4.1" 128 | 129 | fd-slicer@~1.0.1: 130 | version "1.0.1" 131 | resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" 132 | integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= 133 | dependencies: 134 | pend "~1.2.0" 135 | 136 | fs-constants@^1.0.0: 137 | version "1.0.0" 138 | resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" 139 | integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== 140 | 141 | fs.realpath@^1.0.0: 142 | version "1.0.0" 143 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 144 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 145 | 146 | glob@^7.1.3: 147 | version "7.1.3" 148 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 149 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 150 | dependencies: 151 | fs.realpath "^1.0.0" 152 | inflight "^1.0.4" 153 | inherits "2" 154 | minimatch "^3.0.4" 155 | once "^1.3.0" 156 | path-is-absolute "^1.0.0" 157 | 158 | https-proxy-agent@^3.0.0: 159 | version "3.0.1" 160 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81" 161 | integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg== 162 | dependencies: 163 | agent-base "^4.3.0" 164 | debug "^3.1.0" 165 | 166 | inflight@^1.0.4: 167 | version "1.0.6" 168 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 169 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 170 | dependencies: 171 | once "^1.3.0" 172 | wrappy "1" 173 | 174 | inherits@2, inherits@^2.0.3, inherits@~2.0.3: 175 | version "2.0.3" 176 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 177 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 178 | 179 | isarray@~1.0.0: 180 | version "1.0.0" 181 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 182 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 183 | 184 | lambdafs@^1.3.0: 185 | version "1.3.0" 186 | resolved "https://registry.yarnpkg.com/lambdafs/-/lambdafs-1.3.0.tgz#7e369cedc9a09623bb365fa99a1113c2ab2fc7ae" 187 | integrity sha512-HqRPmEgtkTW4sCYDUjTEuTGkjCHuLvtZU8iM8GkhD7SpjW4AJJbBk86YU4K43sWGuW5Vmzp1lVCx4ab/kJsuBw== 188 | dependencies: 189 | tar-fs "^2.0.0" 190 | 191 | mime@^2.0.3: 192 | version "2.4.0" 193 | resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" 194 | integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== 195 | 196 | minimatch@^3.0.4: 197 | version "3.0.4" 198 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 199 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 200 | dependencies: 201 | brace-expansion "^1.1.7" 202 | 203 | minimist@0.0.8: 204 | version "0.0.8" 205 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 206 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 207 | 208 | mkdirp@0.5.1, mkdirp@^0.5.1: 209 | version "0.5.1" 210 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 211 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 212 | dependencies: 213 | minimist "0.0.8" 214 | 215 | ms@2.0.0: 216 | version "2.0.0" 217 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 218 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 219 | 220 | ms@^2.1.1: 221 | version "2.1.1" 222 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 223 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 224 | 225 | once@^1.3.0, once@^1.3.1, once@^1.4.0: 226 | version "1.4.0" 227 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 228 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 229 | dependencies: 230 | wrappy "1" 231 | 232 | path-is-absolute@^1.0.0: 233 | version "1.0.1" 234 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 235 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 236 | 237 | pend@~1.2.0: 238 | version "1.2.0" 239 | resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" 240 | integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= 241 | 242 | process-nextick-args@~2.0.0: 243 | version "2.0.0" 244 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" 245 | integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== 246 | 247 | progress@^2.0.1: 248 | version "2.0.3" 249 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 250 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 251 | 252 | proxy-from-env@^1.0.0: 253 | version "1.0.0" 254 | resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" 255 | integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= 256 | 257 | pump@^3.0.0: 258 | version "3.0.0" 259 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 260 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 261 | dependencies: 262 | end-of-stream "^1.1.0" 263 | once "^1.3.1" 264 | 265 | puppeteer-core@2.0.0: 266 | version "2.0.0" 267 | resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-2.0.0.tgz#2c3b122dec539ff01e6dfc29ee3e6f3a6280330d" 268 | integrity sha512-xgg8hLm7VIiwoYRZtgXNy0gf9IKCA/WyT5Rm5RqkDc7mm4bJMeESmzP+YWyl+X/c1CSOuCy4WWnnC+9T+DKgCQ== 269 | dependencies: 270 | debug "^4.1.0" 271 | extract-zip "^1.6.6" 272 | https-proxy-agent "^3.0.0" 273 | mime "^2.0.3" 274 | progress "^2.0.1" 275 | proxy-from-env "^1.0.0" 276 | rimraf "^2.6.1" 277 | ws "^6.1.0" 278 | 279 | readable-stream@^2.2.2: 280 | version "2.3.6" 281 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" 282 | integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== 283 | dependencies: 284 | core-util-is "~1.0.0" 285 | inherits "~2.0.3" 286 | isarray "~1.0.0" 287 | process-nextick-args "~2.0.0" 288 | safe-buffer "~5.1.1" 289 | string_decoder "~1.1.1" 290 | util-deprecate "~1.0.1" 291 | 292 | readable-stream@^3.0.1, readable-stream@^3.1.1: 293 | version "3.5.0" 294 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.5.0.tgz#465d70e6d1087f6162d079cd0b5db7fbebfd1606" 295 | integrity sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA== 296 | dependencies: 297 | inherits "^2.0.3" 298 | string_decoder "^1.1.1" 299 | util-deprecate "^1.0.1" 300 | 301 | rimraf@^2.6.1: 302 | version "2.6.3" 303 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" 304 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== 305 | dependencies: 306 | glob "^7.1.3" 307 | 308 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 309 | version "5.1.2" 310 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 311 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 312 | 313 | safe-buffer@~5.2.0: 314 | version "5.2.0" 315 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" 316 | integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== 317 | 318 | string_decoder@^1.1.1: 319 | version "1.3.0" 320 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 321 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 322 | dependencies: 323 | safe-buffer "~5.2.0" 324 | 325 | string_decoder@~1.1.1: 326 | version "1.1.1" 327 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 328 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 329 | dependencies: 330 | safe-buffer "~5.1.0" 331 | 332 | tar-fs@^2.0.0: 333 | version "2.0.0" 334 | resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad" 335 | integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== 336 | dependencies: 337 | chownr "^1.1.1" 338 | mkdirp "^0.5.1" 339 | pump "^3.0.0" 340 | tar-stream "^2.0.0" 341 | 342 | tar-stream@^2.0.0: 343 | version "2.1.0" 344 | resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3" 345 | integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw== 346 | dependencies: 347 | bl "^3.0.0" 348 | end-of-stream "^1.4.1" 349 | fs-constants "^1.0.0" 350 | inherits "^2.0.3" 351 | readable-stream "^3.1.1" 352 | 353 | typedarray@^0.0.6: 354 | version "0.0.6" 355 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 356 | integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= 357 | 358 | typescript@3.7.5: 359 | version "3.7.5" 360 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" 361 | integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== 362 | 363 | util-deprecate@^1.0.1, util-deprecate@~1.0.1: 364 | version "1.0.2" 365 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 366 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 367 | 368 | wrappy@1: 369 | version "1.0.2" 370 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 371 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 372 | 373 | ws@^6.1.0: 374 | version "6.1.4" 375 | resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" 376 | integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== 377 | dependencies: 378 | async-limiter "~1.0.0" 379 | 380 | yauzl@2.4.1: 381 | version "2.4.1" 382 | resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" 383 | integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU= 384 | dependencies: 385 | fd-slicer "~1.0.1" 386 | --------------------------------------------------------------------------------