├── .gitignore ├── README.md ├── app.js ├── package.json ├── public ├── guide-screenshots │ ├── account1.png │ └── cors1.png └── images │ └── default.png ├── views └── account.html └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.sw* 3 | *.env 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NodeDirectUploader 2 | 3 | 4 | ## Licensing 5 | 6 | The files in this repository are, unless stated otherwise, released under the Apache License. You are free to redistribute this code with or without modification. The full license text is available [here](http://www.apache.org/licenses/LICENSE-2.0). 7 | 8 | 9 | ## Direct-to-S3 uploads in a Node.js application running on Heroku 10 | 11 | Simple example demonstrating how to accomplish a direct upload to Amazon's S3 in a Node.js web application. 12 | 13 | This example uses the [express](http://expressjs.com/) web framework to facilitate request-handling. However, the process of signing the S3 PUT request would be identical in most Node apps. 14 | 15 | This code is mostly ready to be run as cloned, but a function will need to be properly defined to handle the storing of the POSTed information. The current example simply demonstrates the upload to S3. 16 | 17 | 18 | ## Dependencies and Installation 19 | 20 | Ensure Node is installed. This can be done through your package manager or from their [website](http://nodejs.org/). 21 | 22 | Clone this repository: 23 | ```term 24 | $ git clone https://github.com/willwebberley/NodeDirectUploader.git 25 | ``` 26 | 27 | Change directory into the application and install the application's dependencies: 28 | ```term 29 | $ cd NodeDirectUploader 30 | $ yarn 31 | ``` 32 | 33 | If you prefer `npm` to `yarn`, then run `npm install` instead. 34 | 35 | ## Running the application 36 | * Set environment variables for your AWS access key, secret, and bucket name (see [companion article](https://devcenter.heroku.com/articles/s3-upload-node)) 37 | * Run `yarn start` (or `npm start`) 38 | * Visit [localhost:3000/account](http://localhost:3000/account) to try it out 39 | 40 | 41 | ## Deploying the application 42 | 43 | See the article [Deploying with Git](https://devcenter.heroku.com/articles/git) for more detailed information on deploying to Heroku. 44 | 45 | * Download and install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) 46 | * Commit your application to a local Git repository (e.g. `git init`, `git add .`, `git commit -m "version 1 commit"`, etc.) 47 | * Create the application on Heroku by adding a Git remote (`$ heroku create`) 48 | * Push your code to the new Heroku repo (`$ git push heroku master`) 49 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 3 | 4 | http://www.apache.org/licenses/LICENSE-2.0 5 | 6 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | 10 | /* 11 | * Import required packages. 12 | * Packages should be installed with "npm install". 13 | */ 14 | const express = require('express'); 15 | const aws = require('aws-sdk'); 16 | 17 | /* 18 | * Set-up and run the Express app. 19 | */ 20 | const app = express(); 21 | app.set('views', './views'); 22 | app.use(express.static('./public')); 23 | app.engine('html', require('ejs').renderFile); 24 | app.listen(process.env.PORT || 3000); 25 | 26 | /* 27 | * Configure the AWS region of the target bucket. 28 | * Remember to change this to the relevant region. 29 | */ 30 | aws.config.region = 'eu-west-1'; 31 | 32 | /* 33 | * Load the S3 information from the environment variables. 34 | */ 35 | const S3_BUCKET = process.env.S3_BUCKET; 36 | 37 | /* 38 | * Respond to GET requests to /account. 39 | * Upon request, render the 'account.html' web page in views/ directory. 40 | */ 41 | app.get('/account', (req, res) => res.render('account.html')); 42 | 43 | /* 44 | * Respond to GET requests to /sign-s3. 45 | * Upon request, return JSON containing the temporarily-signed S3 request and 46 | * the anticipated URL of the image. 47 | */ 48 | app.get('/sign-s3', (req, res) => { 49 | const s3 = new aws.S3(); 50 | const fileName = req.query['file-name']; 51 | const fileType = req.query['file-type']; 52 | const s3Params = { 53 | Bucket: S3_BUCKET, 54 | Key: fileName, 55 | Expires: 60, 56 | ContentType: fileType, 57 | ACL: 'public-read' 58 | }; 59 | 60 | s3.getSignedUrl('putObject', s3Params, (err, data) => { 61 | if(err){ 62 | console.log(err); 63 | return res.end(); 64 | } 65 | const returnData = { 66 | signedRequest: data, 67 | url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}` 68 | }; 69 | res.write(JSON.stringify(returnData)); 70 | res.end(); 71 | }); 72 | }); 73 | 74 | /* 75 | * Respond to POST requests to /submit_form. 76 | * This function needs to be completed to handle the information in 77 | * a way that suits your application. 78 | */ 79 | app.post('/save-details', (req, res) => { 80 | // TODO: Read POSTed form data and do something useful 81 | }); 82 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NodeDirectUploader", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node app.js" 7 | }, 8 | "dependencies": { 9 | "aws-sdk": "2.x", 10 | "ejs": "2.x", 11 | "express": "4.x" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /public/guide-screenshots/account1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/willwebberley/NodeDirectUploader/e8daf8509e9ace17c0c3f42573bd5082a3c5de93/public/guide-screenshots/account1.png -------------------------------------------------------------------------------- /public/guide-screenshots/cors1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/willwebberley/NodeDirectUploader/e8daf8509e9ace17c0c3f42573bd5082a3c5de93/public/guide-screenshots/cors1.png -------------------------------------------------------------------------------- /public/images/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/willwebberley/NodeDirectUploader/e8daf8509e9ace17c0c3f42573bd5082a3c5de93/public/images/default.png -------------------------------------------------------------------------------- /views/account.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Edit your account

5 | 6 |
7 | 8 |

Your avatar

9 | 10 | 11 |

Please select a file

12 | 13 | 14 |

Your information

15 | 16 |
17 | 18 |
19 |

20 | 21 |
22 |

Save changes

23 | 24 | 25 |
26 | 27 | 28 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@~1.3.5: 6 | version "1.3.5" 7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" 8 | integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= 9 | dependencies: 10 | mime-types "~2.1.18" 11 | negotiator "0.6.1" 12 | 13 | array-flatten@1.1.1: 14 | version "1.1.1" 15 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 16 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 17 | 18 | aws-sdk@2.x: 19 | version "2.384.0" 20 | resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.384.0.tgz#c8fdce7c72f068f6d8b198b53cf33b6f35f3e811" 21 | integrity sha512-E+pIOWFNhQH7GCkOl5GU+Vl42MlaKtAq0Yenaa2fRGult9097u7TnUx45V1pNKMCN9RnEFWQy3ZH1TEPEYJ0fw== 22 | dependencies: 23 | buffer "4.9.1" 24 | events "1.1.1" 25 | ieee754 "1.1.8" 26 | jmespath "0.15.0" 27 | querystring "0.2.0" 28 | sax "1.2.1" 29 | url "0.10.3" 30 | uuid "3.1.0" 31 | xml2js "0.4.19" 32 | 33 | base64-js@^1.0.2: 34 | version "1.3.0" 35 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" 36 | integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== 37 | 38 | body-parser@1.18.3: 39 | version "1.18.3" 40 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" 41 | integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= 42 | dependencies: 43 | bytes "3.0.0" 44 | content-type "~1.0.4" 45 | debug "2.6.9" 46 | depd "~1.1.2" 47 | http-errors "~1.6.3" 48 | iconv-lite "0.4.23" 49 | on-finished "~2.3.0" 50 | qs "6.5.2" 51 | raw-body "2.3.3" 52 | type-is "~1.6.16" 53 | 54 | buffer@4.9.1: 55 | version "4.9.1" 56 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" 57 | integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= 58 | dependencies: 59 | base64-js "^1.0.2" 60 | ieee754 "^1.1.4" 61 | isarray "^1.0.0" 62 | 63 | bytes@3.0.0: 64 | version "3.0.0" 65 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 66 | integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= 67 | 68 | content-disposition@0.5.2: 69 | version "0.5.2" 70 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 71 | integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= 72 | 73 | content-type@~1.0.4: 74 | version "1.0.4" 75 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 76 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 77 | 78 | cookie-signature@1.0.6: 79 | version "1.0.6" 80 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 81 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 82 | 83 | cookie@0.3.1: 84 | version "0.3.1" 85 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 86 | integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= 87 | 88 | debug@2.6.9: 89 | version "2.6.9" 90 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 91 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 92 | dependencies: 93 | ms "2.0.0" 94 | 95 | depd@~1.1.2: 96 | version "1.1.2" 97 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 98 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 99 | 100 | destroy@~1.0.4: 101 | version "1.0.4" 102 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 103 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 104 | 105 | ee-first@1.1.1: 106 | version "1.1.1" 107 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 108 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 109 | 110 | ejs@2.x: 111 | version "2.6.1" 112 | resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" 113 | integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== 114 | 115 | encodeurl@~1.0.2: 116 | version "1.0.2" 117 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 118 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 119 | 120 | escape-html@~1.0.3: 121 | version "1.0.3" 122 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 123 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 124 | 125 | etag@~1.8.1: 126 | version "1.8.1" 127 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 128 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 129 | 130 | events@1.1.1: 131 | version "1.1.1" 132 | resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" 133 | integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= 134 | 135 | express@4.x: 136 | version "4.16.4" 137 | resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" 138 | integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== 139 | dependencies: 140 | accepts "~1.3.5" 141 | array-flatten "1.1.1" 142 | body-parser "1.18.3" 143 | content-disposition "0.5.2" 144 | content-type "~1.0.4" 145 | cookie "0.3.1" 146 | cookie-signature "1.0.6" 147 | debug "2.6.9" 148 | depd "~1.1.2" 149 | encodeurl "~1.0.2" 150 | escape-html "~1.0.3" 151 | etag "~1.8.1" 152 | finalhandler "1.1.1" 153 | fresh "0.5.2" 154 | merge-descriptors "1.0.1" 155 | methods "~1.1.2" 156 | on-finished "~2.3.0" 157 | parseurl "~1.3.2" 158 | path-to-regexp "0.1.7" 159 | proxy-addr "~2.0.4" 160 | qs "6.5.2" 161 | range-parser "~1.2.0" 162 | safe-buffer "5.1.2" 163 | send "0.16.2" 164 | serve-static "1.13.2" 165 | setprototypeof "1.1.0" 166 | statuses "~1.4.0" 167 | type-is "~1.6.16" 168 | utils-merge "1.0.1" 169 | vary "~1.1.2" 170 | 171 | finalhandler@1.1.1: 172 | version "1.1.1" 173 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" 174 | integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== 175 | dependencies: 176 | debug "2.6.9" 177 | encodeurl "~1.0.2" 178 | escape-html "~1.0.3" 179 | on-finished "~2.3.0" 180 | parseurl "~1.3.2" 181 | statuses "~1.4.0" 182 | unpipe "~1.0.0" 183 | 184 | forwarded@~0.1.2: 185 | version "0.1.2" 186 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 187 | integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= 188 | 189 | fresh@0.5.2: 190 | version "0.5.2" 191 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 192 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 193 | 194 | http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: 195 | version "1.6.3" 196 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" 197 | integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= 198 | dependencies: 199 | depd "~1.1.2" 200 | inherits "2.0.3" 201 | setprototypeof "1.1.0" 202 | statuses ">= 1.4.0 < 2" 203 | 204 | iconv-lite@0.4.23: 205 | version "0.4.23" 206 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" 207 | integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== 208 | dependencies: 209 | safer-buffer ">= 2.1.2 < 3" 210 | 211 | ieee754@1.1.8: 212 | version "1.1.8" 213 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" 214 | integrity sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q= 215 | 216 | ieee754@^1.1.4: 217 | version "1.1.12" 218 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" 219 | integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== 220 | 221 | inherits@2.0.3: 222 | version "2.0.3" 223 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 224 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 225 | 226 | ipaddr.js@1.8.0: 227 | version "1.8.0" 228 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" 229 | integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= 230 | 231 | isarray@^1.0.0: 232 | version "1.0.0" 233 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 234 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 235 | 236 | jmespath@0.15.0: 237 | version "0.15.0" 238 | resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" 239 | integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= 240 | 241 | media-typer@0.3.0: 242 | version "0.3.0" 243 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 244 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 245 | 246 | merge-descriptors@1.0.1: 247 | version "1.0.1" 248 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 249 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 250 | 251 | methods@~1.1.2: 252 | version "1.1.2" 253 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 254 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 255 | 256 | mime-db@~1.37.0: 257 | version "1.37.0" 258 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" 259 | integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== 260 | 261 | mime-types@~2.1.18: 262 | version "2.1.21" 263 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" 264 | integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== 265 | dependencies: 266 | mime-db "~1.37.0" 267 | 268 | mime@1.4.1: 269 | version "1.4.1" 270 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" 271 | integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== 272 | 273 | ms@2.0.0: 274 | version "2.0.0" 275 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 276 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 277 | 278 | negotiator@0.6.1: 279 | version "0.6.1" 280 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 281 | integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= 282 | 283 | on-finished@~2.3.0: 284 | version "2.3.0" 285 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 286 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 287 | dependencies: 288 | ee-first "1.1.1" 289 | 290 | parseurl@~1.3.2: 291 | version "1.3.2" 292 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 293 | integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= 294 | 295 | path-to-regexp@0.1.7: 296 | version "0.1.7" 297 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 298 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 299 | 300 | proxy-addr@~2.0.4: 301 | version "2.0.4" 302 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" 303 | integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== 304 | dependencies: 305 | forwarded "~0.1.2" 306 | ipaddr.js "1.8.0" 307 | 308 | punycode@1.3.2: 309 | version "1.3.2" 310 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" 311 | integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= 312 | 313 | qs@6.5.2: 314 | version "6.5.2" 315 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 316 | integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 317 | 318 | querystring@0.2.0: 319 | version "0.2.0" 320 | resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" 321 | integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= 322 | 323 | range-parser@~1.2.0: 324 | version "1.2.0" 325 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 326 | integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= 327 | 328 | raw-body@2.3.3: 329 | version "2.3.3" 330 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" 331 | integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== 332 | dependencies: 333 | bytes "3.0.0" 334 | http-errors "1.6.3" 335 | iconv-lite "0.4.23" 336 | unpipe "1.0.0" 337 | 338 | safe-buffer@5.1.2: 339 | version "5.1.2" 340 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 341 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 342 | 343 | "safer-buffer@>= 2.1.2 < 3": 344 | version "2.1.2" 345 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 346 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 347 | 348 | sax@1.2.1: 349 | version "1.2.1" 350 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" 351 | integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= 352 | 353 | sax@>=0.6.0: 354 | version "1.2.4" 355 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" 356 | integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== 357 | 358 | send@0.16.2: 359 | version "0.16.2" 360 | resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" 361 | integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== 362 | dependencies: 363 | debug "2.6.9" 364 | depd "~1.1.2" 365 | destroy "~1.0.4" 366 | encodeurl "~1.0.2" 367 | escape-html "~1.0.3" 368 | etag "~1.8.1" 369 | fresh "0.5.2" 370 | http-errors "~1.6.2" 371 | mime "1.4.1" 372 | ms "2.0.0" 373 | on-finished "~2.3.0" 374 | range-parser "~1.2.0" 375 | statuses "~1.4.0" 376 | 377 | serve-static@1.13.2: 378 | version "1.13.2" 379 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" 380 | integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== 381 | dependencies: 382 | encodeurl "~1.0.2" 383 | escape-html "~1.0.3" 384 | parseurl "~1.3.2" 385 | send "0.16.2" 386 | 387 | setprototypeof@1.1.0: 388 | version "1.1.0" 389 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 390 | integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== 391 | 392 | "statuses@>= 1.4.0 < 2": 393 | version "1.5.0" 394 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 395 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 396 | 397 | statuses@~1.4.0: 398 | version "1.4.0" 399 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 400 | integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== 401 | 402 | type-is@~1.6.16: 403 | version "1.6.16" 404 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" 405 | integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== 406 | dependencies: 407 | media-typer "0.3.0" 408 | mime-types "~2.1.18" 409 | 410 | unpipe@1.0.0, unpipe@~1.0.0: 411 | version "1.0.0" 412 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 413 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 414 | 415 | url@0.10.3: 416 | version "0.10.3" 417 | resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" 418 | integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= 419 | dependencies: 420 | punycode "1.3.2" 421 | querystring "0.2.0" 422 | 423 | utils-merge@1.0.1: 424 | version "1.0.1" 425 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 426 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 427 | 428 | uuid@3.1.0: 429 | version "3.1.0" 430 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" 431 | integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== 432 | 433 | vary@~1.1.2: 434 | version "1.1.2" 435 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 436 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 437 | 438 | xml2js@0.4.19: 439 | version "0.4.19" 440 | resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" 441 | integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== 442 | dependencies: 443 | sax ">=0.6.0" 444 | xmlbuilder "~9.0.1" 445 | 446 | xmlbuilder@~9.0.1: 447 | version "9.0.7" 448 | resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" 449 | integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= 450 | --------------------------------------------------------------------------------