├── .dockerignore ├── .gitignore ├── Dockerfile ├── Procfile ├── README.md ├── app.js ├── bin └── www ├── docker-compose.yml ├── makefile ├── package-lock.json ├── package.json ├── public └── stylesheets │ └── style.css ├── routes ├── index.js └── users.js └── views ├── error.pug ├── index.pug └── layout.pug /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://docs.npmjs.com/cli/shrinkwrap#caveats 27 | node_modules 28 | 29 | # Debug log from npm 30 | npm-debug.log 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:11.2.0-alpine 2 | 3 | RUN apk add --no-cache curl-dev libzip-dev autoconf build-base gmp-dev coreutils python 4 | 5 | RUN mkdir -p /usr/src/app 6 | WORKDIR /usr/src/app 7 | COPY . /usr/src/app 8 | 9 | RUN npm i 10 | 11 | EXPOSE 3000 12 | 13 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: npm start -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gettingMean-2 2 | # Getting MEAN Second Edition application code 3 | 4 | This is the code for the sample 'Loc8r' application that is built through the course of the book Getting MEAN Second Edition. 5 | 6 | Getting MEAN Second Edition is published by Manning, and teaches readers how to develop web applications end-to-end using the MEAN stack with Node 11 and Angular 7. It is currently in early access through the MEAP program, with new chapters being released regularly. 7 | 8 | > Note: if you have the First Edition of the book using Node 4 and Angular 1 you need the [First Edition code](https://github.com/simonholmes/getting-MEAN/) instead. 9 | 10 | ## The application at various stages 11 | 12 | There will be named branches for the various states of the code throughout the book: 13 | 14 | * `master` **Chapter 3 start**: A blank Express 4.16.3 project 15 | * `chapter-03` **Chapter 3 end**: Creating and setting up a MEAN project 16 | * `chapter-04-views` **Chapter 4 mid-point**: The data is hard coded into views 17 | * `chapter-04` **Chapter 4 end**: Building a static site with Node.js and Express 18 | * `chapter-05` **Chapter 5**: Building a data model with MongoDB and Mongoose 19 | * `chapter-06` **Chapter 6**: Writing a REST API: Exposing your MongoDB database to the application 20 | * `chapter-07` **Chapter 7**: Consuming a REST API: Using an API from inside Express 21 | * `chapter-08` **Chapter 8**: Creating an Angular application with TypeScript 22 | * `chapter-09` **Chapter 9**: Building a Single Page Application with Angular 23 | * `chapter-10` **Chapter 10**: Building a Single Page Application with Angular: The next level 24 | * `chapter-11` **Chapter 11**: Authenticating users, managing sessions and securing APIs 25 | * `chapter-12` **Chapter 12**: Using an authentication API in Angular applications 26 | 27 | ## Get the code to run on your machine 28 | 29 | Pre-requisites: 30 | 31 | * Git installed 32 | * A command line interface capable of running Git commands 33 | * Node v11 installed 34 | 35 | To get the code for a specific branch: 36 | 37 | `$ git clone -b branch-name https://github.com/cliveharber/gettingMean-2.git` 38 | 39 | Then change into the folder the git clone command will create: 40 | 41 | `$ cd getting-MEAN-2` 42 | 43 | And finally install the dependencies: 44 | 45 | `npm install` 46 | 47 | ## Getting the code via Docker 48 | 49 | Pre-requisites: 50 | 51 | * Docker 52 | 53 | To get the code for a specific branch: 54 | 55 | `$ git clone -b branch-name https://github.com/cliveharber/gettingMean-2.git` 56 | 57 | Then change into the folder the git clone command will create: 58 | 59 | `$ cd getting-MEAN-2` 60 | 61 | And finally run the docker containers 62 | 63 | `make build` 64 | 65 | To remove the containers when complete 66 | 67 | `make destroy` 68 | 69 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | const favicon = require('serve-favicon'); 4 | const logger = require('morgan'); 5 | const cookieParser = require('cookie-parser'); 6 | const bodyParser = require('body-parser'); 7 | 8 | const indexRouter = require('./routes/index'); 9 | const usersRouter = require('./routes/users'); 10 | 11 | const app = express(); 12 | 13 | // view engine setup 14 | app.set('views', path.join(__dirname, 'views')); 15 | app.set('view engine', 'pug'); 16 | 17 | // uncomment after placing your favicon in /public 18 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 19 | app.use(logger('dev')); 20 | app.use(bodyParser.json()); 21 | app.use(bodyParser.urlencoded({ extended: false })); 22 | app.use(cookieParser()); 23 | app.use(express.static(path.join(__dirname, 'public'))); 24 | 25 | app.use('/', indexRouter); 26 | app.use('/users', usersRouter); 27 | 28 | // catch 404 and forward to error handler 29 | app.use(function(req, res, next) { 30 | const err = new Error('Not Found'); 31 | err.status = 404; 32 | next(err); 33 | }); 34 | 35 | // error handler 36 | app.use(function(err, req, res, next) { 37 | // set locals, only providing error in development 38 | res.locals.message = err.message; 39 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 40 | 41 | // render the error page 42 | res.status(err.status || 500); 43 | res.render('error'); 44 | }); 45 | 46 | module.exports = app; 47 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | const app = require('../app'); 8 | const debug = require('debug')('book-code:server'); 9 | const http = require('http'); 10 | 11 | /** 12 | * Normalize a port into a number, string, or false. 13 | */ 14 | 15 | const normalizePort = (val) => { 16 | const port = parseInt(val, 10); 17 | 18 | if (isNaN(port)) { 19 | // named pipe 20 | return val; 21 | } 22 | 23 | if (port >= 0) { 24 | // port number 25 | return port; 26 | } 27 | 28 | return false; 29 | } 30 | 31 | /** 32 | * Event listener for HTTP server "error" event. 33 | */ 34 | 35 | const onError = (error) => { 36 | if (error.syscall !== 'listen') { 37 | throw error; 38 | } 39 | 40 | const bind = typeof port === 'string' 41 | ? 'Pipe ' + port 42 | : 'Port ' + port; 43 | 44 | // handle specific listen errors with friendly messages 45 | switch (error.code) { 46 | case 'EACCES': 47 | console.error(bind + ' requires elevated privileges'); 48 | process.exit(1); 49 | break; 50 | case 'EADDRINUSE': 51 | console.error(bind + ' is already in use'); 52 | process.exit(1); 53 | break; 54 | default: 55 | throw error; 56 | } 57 | } 58 | 59 | /** 60 | * Event listener for HTTP server "listening" event. 61 | */ 62 | 63 | const onListening = () => { 64 | const addr = server.address(); 65 | const bind = typeof addr === 'string' 66 | ? 'pipe ' + addr 67 | : 'port ' + addr.port; 68 | debug('Listening on ' + bind); 69 | } 70 | 71 | /** 72 | * Get port from environment and store in Express. 73 | */ 74 | 75 | const port = normalizePort(process.env.PORT || '3000'); 76 | app.set('port', port); 77 | 78 | /** 79 | * Create HTTP server. 80 | */ 81 | 82 | const server = http.createServer(app); 83 | 84 | /** 85 | * Listen on provided port, on all network interfaces. 86 | */ 87 | 88 | server.listen(port); 89 | server.on('error', onError); 90 | server.on('listening', onListening); 91 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.0' 2 | services: 3 | express: 4 | build: . 5 | ports: 6 | - 3000:3000 -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | default: build 2 | 3 | build: 4 | docker-compose build 5 | docker-compose up -d 6 | 7 | destroy: 8 | docker-compose rm -f -s -v 9 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Getting-MEAN-2nd-edition", 3 | "version": "0.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/helper-validator-identifier": { 8 | "version": "7.14.9", 9 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", 10 | "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==" 11 | }, 12 | "@babel/parser": { 13 | "version": "7.15.3", 14 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", 15 | "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==" 16 | }, 17 | "@babel/types": { 18 | "version": "7.15.0", 19 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", 20 | "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", 21 | "requires": { 22 | "@babel/helper-validator-identifier": "^7.14.9", 23 | "to-fast-properties": "^2.0.0" 24 | } 25 | }, 26 | "accepts": { 27 | "version": "1.3.7", 28 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 29 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 30 | "requires": { 31 | "mime-types": "~2.1.24", 32 | "negotiator": "0.6.2" 33 | } 34 | }, 35 | "acorn": { 36 | "version": "7.4.1", 37 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", 38 | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" 39 | }, 40 | "array-flatten": { 41 | "version": "1.1.1", 42 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 43 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 44 | }, 45 | "asap": { 46 | "version": "2.0.6", 47 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 48 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" 49 | }, 50 | "assert-never": { 51 | "version": "1.2.1", 52 | "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", 53 | "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" 54 | }, 55 | "babel-walk": { 56 | "version": "3.0.0-canary-5", 57 | "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", 58 | "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", 59 | "requires": { 60 | "@babel/types": "^7.9.6" 61 | } 62 | }, 63 | "basic-auth": { 64 | "version": "2.0.1", 65 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 66 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 67 | "requires": { 68 | "safe-buffer": "5.1.2" 69 | } 70 | }, 71 | "body-parser": { 72 | "version": "1.19.0", 73 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 74 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 75 | "requires": { 76 | "bytes": "3.1.0", 77 | "content-type": "~1.0.4", 78 | "debug": "2.6.9", 79 | "depd": "~1.1.2", 80 | "http-errors": "1.7.2", 81 | "iconv-lite": "0.4.24", 82 | "on-finished": "~2.3.0", 83 | "qs": "6.7.0", 84 | "raw-body": "2.4.0", 85 | "type-is": "~1.6.17" 86 | }, 87 | "dependencies": { 88 | "debug": { 89 | "version": "2.6.9", 90 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 91 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 92 | "requires": { 93 | "ms": "2.0.0" 94 | } 95 | } 96 | } 97 | }, 98 | "bytes": { 99 | "version": "3.1.0", 100 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 101 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 102 | }, 103 | "call-bind": { 104 | "version": "1.0.2", 105 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 106 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 107 | "requires": { 108 | "function-bind": "^1.1.1", 109 | "get-intrinsic": "^1.0.2" 110 | } 111 | }, 112 | "character-parser": { 113 | "version": "2.2.0", 114 | "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", 115 | "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", 116 | "requires": { 117 | "is-regex": "^1.0.3" 118 | } 119 | }, 120 | "constantinople": { 121 | "version": "4.0.1", 122 | "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", 123 | "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", 124 | "requires": { 125 | "@babel/parser": "^7.6.0", 126 | "@babel/types": "^7.6.1" 127 | } 128 | }, 129 | "content-disposition": { 130 | "version": "0.5.3", 131 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 132 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 133 | "requires": { 134 | "safe-buffer": "5.1.2" 135 | } 136 | }, 137 | "content-type": { 138 | "version": "1.0.4", 139 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 140 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 141 | }, 142 | "cookie": { 143 | "version": "0.3.1", 144 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 145 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 146 | }, 147 | "cookie-parser": { 148 | "version": "1.4.4", 149 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz", 150 | "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==", 151 | "requires": { 152 | "cookie": "0.3.1", 153 | "cookie-signature": "1.0.6" 154 | } 155 | }, 156 | "cookie-signature": { 157 | "version": "1.0.6", 158 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 159 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 160 | }, 161 | "debug": { 162 | "version": "4.1.1", 163 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 164 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 165 | "requires": { 166 | "ms": "^2.1.1" 167 | }, 168 | "dependencies": { 169 | "ms": { 170 | "version": "2.1.2", 171 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 172 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 173 | } 174 | } 175 | }, 176 | "depd": { 177 | "version": "1.1.2", 178 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 179 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 180 | }, 181 | "destroy": { 182 | "version": "1.0.4", 183 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 184 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 185 | }, 186 | "doctypes": { 187 | "version": "1.1.0", 188 | "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", 189 | "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" 190 | }, 191 | "ee-first": { 192 | "version": "1.1.1", 193 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 194 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 195 | }, 196 | "encodeurl": { 197 | "version": "1.0.2", 198 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 199 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 200 | }, 201 | "escape-html": { 202 | "version": "1.0.3", 203 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 204 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 205 | }, 206 | "etag": { 207 | "version": "1.8.1", 208 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 209 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 210 | }, 211 | "express": { 212 | "version": "4.17.1", 213 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 214 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 215 | "requires": { 216 | "accepts": "~1.3.7", 217 | "array-flatten": "1.1.1", 218 | "body-parser": "1.19.0", 219 | "content-disposition": "0.5.3", 220 | "content-type": "~1.0.4", 221 | "cookie": "0.4.0", 222 | "cookie-signature": "1.0.6", 223 | "debug": "2.6.9", 224 | "depd": "~1.1.2", 225 | "encodeurl": "~1.0.2", 226 | "escape-html": "~1.0.3", 227 | "etag": "~1.8.1", 228 | "finalhandler": "~1.1.2", 229 | "fresh": "0.5.2", 230 | "merge-descriptors": "1.0.1", 231 | "methods": "~1.1.2", 232 | "on-finished": "~2.3.0", 233 | "parseurl": "~1.3.3", 234 | "path-to-regexp": "0.1.7", 235 | "proxy-addr": "~2.0.5", 236 | "qs": "6.7.0", 237 | "range-parser": "~1.2.1", 238 | "safe-buffer": "5.1.2", 239 | "send": "0.17.1", 240 | "serve-static": "1.14.1", 241 | "setprototypeof": "1.1.1", 242 | "statuses": "~1.5.0", 243 | "type-is": "~1.6.18", 244 | "utils-merge": "1.0.1", 245 | "vary": "~1.1.2" 246 | }, 247 | "dependencies": { 248 | "cookie": { 249 | "version": "0.4.0", 250 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 251 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 252 | }, 253 | "debug": { 254 | "version": "2.6.9", 255 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 256 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 257 | "requires": { 258 | "ms": "2.0.0" 259 | } 260 | }, 261 | "parseurl": { 262 | "version": "1.3.3", 263 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 264 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 265 | } 266 | } 267 | }, 268 | "finalhandler": { 269 | "version": "1.1.2", 270 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 271 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 272 | "requires": { 273 | "debug": "2.6.9", 274 | "encodeurl": "~1.0.2", 275 | "escape-html": "~1.0.3", 276 | "on-finished": "~2.3.0", 277 | "parseurl": "~1.3.3", 278 | "statuses": "~1.5.0", 279 | "unpipe": "~1.0.0" 280 | }, 281 | "dependencies": { 282 | "debug": { 283 | "version": "2.6.9", 284 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 285 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 286 | "requires": { 287 | "ms": "2.0.0" 288 | } 289 | }, 290 | "parseurl": { 291 | "version": "1.3.3", 292 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 293 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 294 | } 295 | } 296 | }, 297 | "forwarded": { 298 | "version": "0.1.2", 299 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 300 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 301 | }, 302 | "fresh": { 303 | "version": "0.5.2", 304 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 305 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 306 | }, 307 | "function-bind": { 308 | "version": "1.1.1", 309 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 310 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 311 | }, 312 | "get-intrinsic": { 313 | "version": "1.1.1", 314 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 315 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 316 | "requires": { 317 | "function-bind": "^1.1.1", 318 | "has": "^1.0.3", 319 | "has-symbols": "^1.0.1" 320 | } 321 | }, 322 | "has": { 323 | "version": "1.0.3", 324 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 325 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 326 | "requires": { 327 | "function-bind": "^1.1.1" 328 | } 329 | }, 330 | "has-symbols": { 331 | "version": "1.0.2", 332 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", 333 | "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" 334 | }, 335 | "has-tostringtag": { 336 | "version": "1.0.0", 337 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 338 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 339 | "requires": { 340 | "has-symbols": "^1.0.2" 341 | } 342 | }, 343 | "http-errors": { 344 | "version": "1.7.2", 345 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 346 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 347 | "requires": { 348 | "depd": "~1.1.2", 349 | "inherits": "2.0.3", 350 | "setprototypeof": "1.1.1", 351 | "statuses": ">= 1.5.0 < 2", 352 | "toidentifier": "1.0.0" 353 | } 354 | }, 355 | "iconv-lite": { 356 | "version": "0.4.24", 357 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 358 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 359 | "requires": { 360 | "safer-buffer": ">= 2.1.2 < 3" 361 | } 362 | }, 363 | "inherits": { 364 | "version": "2.0.3", 365 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 366 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 367 | }, 368 | "ipaddr.js": { 369 | "version": "1.9.0", 370 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", 371 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" 372 | }, 373 | "is-core-module": { 374 | "version": "2.5.0", 375 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz", 376 | "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==", 377 | "requires": { 378 | "has": "^1.0.3" 379 | } 380 | }, 381 | "is-expression": { 382 | "version": "4.0.0", 383 | "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", 384 | "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", 385 | "requires": { 386 | "acorn": "^7.1.1", 387 | "object-assign": "^4.1.1" 388 | } 389 | }, 390 | "is-promise": { 391 | "version": "2.2.2", 392 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", 393 | "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" 394 | }, 395 | "is-regex": { 396 | "version": "1.1.4", 397 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", 398 | "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", 399 | "requires": { 400 | "call-bind": "^1.0.2", 401 | "has-tostringtag": "^1.0.0" 402 | } 403 | }, 404 | "js-stringify": { 405 | "version": "1.0.2", 406 | "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", 407 | "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" 408 | }, 409 | "jstransformer": { 410 | "version": "1.0.0", 411 | "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", 412 | "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", 413 | "requires": { 414 | "is-promise": "^2.0.0", 415 | "promise": "^7.0.1" 416 | } 417 | }, 418 | "media-typer": { 419 | "version": "0.3.0", 420 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 421 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 422 | }, 423 | "merge-descriptors": { 424 | "version": "1.0.1", 425 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 426 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 427 | }, 428 | "methods": { 429 | "version": "1.1.2", 430 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 431 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 432 | }, 433 | "mime": { 434 | "version": "1.6.0", 435 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 436 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 437 | }, 438 | "mime-db": { 439 | "version": "1.40.0", 440 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 441 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" 442 | }, 443 | "mime-types": { 444 | "version": "2.1.24", 445 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 446 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", 447 | "requires": { 448 | "mime-db": "1.40.0" 449 | } 450 | }, 451 | "morgan": { 452 | "version": "1.9.1", 453 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", 454 | "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", 455 | "requires": { 456 | "basic-auth": "~2.0.0", 457 | "debug": "2.6.9", 458 | "depd": "~1.1.2", 459 | "on-finished": "~2.3.0", 460 | "on-headers": "~1.0.1" 461 | }, 462 | "dependencies": { 463 | "debug": { 464 | "version": "2.6.9", 465 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 466 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 467 | "requires": { 468 | "ms": "2.0.0" 469 | } 470 | } 471 | } 472 | }, 473 | "ms": { 474 | "version": "2.0.0", 475 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 476 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 477 | }, 478 | "negotiator": { 479 | "version": "0.6.2", 480 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 481 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 482 | }, 483 | "object-assign": { 484 | "version": "4.1.1", 485 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 486 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 487 | }, 488 | "on-finished": { 489 | "version": "2.3.0", 490 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 491 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 492 | "requires": { 493 | "ee-first": "1.1.1" 494 | } 495 | }, 496 | "on-headers": { 497 | "version": "1.0.1", 498 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", 499 | "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" 500 | }, 501 | "parseurl": { 502 | "version": "1.3.2", 503 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 504 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 505 | }, 506 | "path-parse": { 507 | "version": "1.0.7", 508 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 509 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" 510 | }, 511 | "path-to-regexp": { 512 | "version": "0.1.7", 513 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 514 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 515 | }, 516 | "promise": { 517 | "version": "7.3.1", 518 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", 519 | "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", 520 | "requires": { 521 | "asap": "~2.0.3" 522 | } 523 | }, 524 | "proxy-addr": { 525 | "version": "2.0.5", 526 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", 527 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", 528 | "requires": { 529 | "forwarded": "~0.1.2", 530 | "ipaddr.js": "1.9.0" 531 | } 532 | }, 533 | "pug": { 534 | "version": "3.0.1", 535 | "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.1.tgz", 536 | "integrity": "sha512-9v1o2yXMfSKJy2PykKyWUhpgx9Pf9D/UlPgIs2pTTxR6DQZ0oivy4I9f8PlWXRY4sjIhDU4TMJ7hQmYnNJc2bw==", 537 | "requires": { 538 | "pug-code-gen": "^3.0.2", 539 | "pug-filters": "^4.0.0", 540 | "pug-lexer": "^5.0.0", 541 | "pug-linker": "^4.0.0", 542 | "pug-load": "^3.0.0", 543 | "pug-parser": "^6.0.0", 544 | "pug-runtime": "^3.0.0", 545 | "pug-strip-comments": "^2.0.0" 546 | } 547 | }, 548 | "pug-attrs": { 549 | "version": "3.0.0", 550 | "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", 551 | "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", 552 | "requires": { 553 | "constantinople": "^4.0.1", 554 | "js-stringify": "^1.0.2", 555 | "pug-runtime": "^3.0.0" 556 | } 557 | }, 558 | "pug-code-gen": { 559 | "version": "3.0.2", 560 | "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", 561 | "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", 562 | "requires": { 563 | "constantinople": "^4.0.1", 564 | "doctypes": "^1.1.0", 565 | "js-stringify": "^1.0.2", 566 | "pug-attrs": "^3.0.0", 567 | "pug-error": "^2.0.0", 568 | "pug-runtime": "^3.0.0", 569 | "void-elements": "^3.1.0", 570 | "with": "^7.0.0" 571 | } 572 | }, 573 | "pug-error": { 574 | "version": "2.0.0", 575 | "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", 576 | "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" 577 | }, 578 | "pug-filters": { 579 | "version": "4.0.0", 580 | "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", 581 | "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", 582 | "requires": { 583 | "constantinople": "^4.0.1", 584 | "jstransformer": "1.0.0", 585 | "pug-error": "^2.0.0", 586 | "pug-walk": "^2.0.0", 587 | "resolve": "^1.15.1" 588 | } 589 | }, 590 | "pug-lexer": { 591 | "version": "5.0.1", 592 | "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", 593 | "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", 594 | "requires": { 595 | "character-parser": "^2.2.0", 596 | "is-expression": "^4.0.0", 597 | "pug-error": "^2.0.0" 598 | } 599 | }, 600 | "pug-linker": { 601 | "version": "4.0.0", 602 | "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", 603 | "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", 604 | "requires": { 605 | "pug-error": "^2.0.0", 606 | "pug-walk": "^2.0.0" 607 | } 608 | }, 609 | "pug-load": { 610 | "version": "3.0.0", 611 | "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", 612 | "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", 613 | "requires": { 614 | "object-assign": "^4.1.1", 615 | "pug-walk": "^2.0.0" 616 | } 617 | }, 618 | "pug-parser": { 619 | "version": "6.0.0", 620 | "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", 621 | "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", 622 | "requires": { 623 | "pug-error": "^2.0.0", 624 | "token-stream": "1.0.0" 625 | } 626 | }, 627 | "pug-runtime": { 628 | "version": "3.0.1", 629 | "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", 630 | "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" 631 | }, 632 | "pug-strip-comments": { 633 | "version": "2.0.0", 634 | "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", 635 | "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", 636 | "requires": { 637 | "pug-error": "^2.0.0" 638 | } 639 | }, 640 | "pug-walk": { 641 | "version": "2.0.0", 642 | "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", 643 | "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" 644 | }, 645 | "qs": { 646 | "version": "6.7.0", 647 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 648 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 649 | }, 650 | "range-parser": { 651 | "version": "1.2.1", 652 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 653 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 654 | }, 655 | "raw-body": { 656 | "version": "2.4.0", 657 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 658 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 659 | "requires": { 660 | "bytes": "3.1.0", 661 | "http-errors": "1.7.2", 662 | "iconv-lite": "0.4.24", 663 | "unpipe": "1.0.0" 664 | } 665 | }, 666 | "resolve": { 667 | "version": "1.20.0", 668 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", 669 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", 670 | "requires": { 671 | "is-core-module": "^2.2.0", 672 | "path-parse": "^1.0.6" 673 | } 674 | }, 675 | "safe-buffer": { 676 | "version": "5.1.2", 677 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 678 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 679 | }, 680 | "safer-buffer": { 681 | "version": "2.1.2", 682 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 683 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 684 | }, 685 | "send": { 686 | "version": "0.17.1", 687 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 688 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 689 | "requires": { 690 | "debug": "2.6.9", 691 | "depd": "~1.1.2", 692 | "destroy": "~1.0.4", 693 | "encodeurl": "~1.0.2", 694 | "escape-html": "~1.0.3", 695 | "etag": "~1.8.1", 696 | "fresh": "0.5.2", 697 | "http-errors": "~1.7.2", 698 | "mime": "1.6.0", 699 | "ms": "2.1.1", 700 | "on-finished": "~2.3.0", 701 | "range-parser": "~1.2.1", 702 | "statuses": "~1.5.0" 703 | }, 704 | "dependencies": { 705 | "debug": { 706 | "version": "2.6.9", 707 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 708 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 709 | "requires": { 710 | "ms": "2.0.0" 711 | }, 712 | "dependencies": { 713 | "ms": { 714 | "version": "2.0.0", 715 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 716 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 717 | } 718 | } 719 | }, 720 | "ms": { 721 | "version": "2.1.1", 722 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 723 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 724 | } 725 | } 726 | }, 727 | "serve-favicon": { 728 | "version": "2.5.0", 729 | "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", 730 | "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=", 731 | "requires": { 732 | "etag": "~1.8.1", 733 | "fresh": "0.5.2", 734 | "ms": "2.1.1", 735 | "parseurl": "~1.3.2", 736 | "safe-buffer": "5.1.1" 737 | }, 738 | "dependencies": { 739 | "ms": { 740 | "version": "2.1.1", 741 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 742 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 743 | }, 744 | "safe-buffer": { 745 | "version": "5.1.1", 746 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 747 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 748 | } 749 | } 750 | }, 751 | "serve-static": { 752 | "version": "1.14.1", 753 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 754 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 755 | "requires": { 756 | "encodeurl": "~1.0.2", 757 | "escape-html": "~1.0.3", 758 | "parseurl": "~1.3.3", 759 | "send": "0.17.1" 760 | }, 761 | "dependencies": { 762 | "parseurl": { 763 | "version": "1.3.3", 764 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 765 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 766 | } 767 | } 768 | }, 769 | "setprototypeof": { 770 | "version": "1.1.1", 771 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 772 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 773 | }, 774 | "statuses": { 775 | "version": "1.5.0", 776 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 777 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 778 | }, 779 | "to-fast-properties": { 780 | "version": "2.0.0", 781 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 782 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" 783 | }, 784 | "toidentifier": { 785 | "version": "1.0.0", 786 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 787 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 788 | }, 789 | "token-stream": { 790 | "version": "1.0.0", 791 | "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", 792 | "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=" 793 | }, 794 | "type-is": { 795 | "version": "1.6.18", 796 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 797 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 798 | "requires": { 799 | "media-typer": "0.3.0", 800 | "mime-types": "~2.1.24" 801 | } 802 | }, 803 | "unpipe": { 804 | "version": "1.0.0", 805 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 806 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 807 | }, 808 | "utils-merge": { 809 | "version": "1.0.1", 810 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 811 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 812 | }, 813 | "vary": { 814 | "version": "1.1.2", 815 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 816 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 817 | }, 818 | "void-elements": { 819 | "version": "3.1.0", 820 | "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", 821 | "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" 822 | }, 823 | "with": { 824 | "version": "7.0.2", 825 | "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", 826 | "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", 827 | "requires": { 828 | "@babel/parser": "^7.9.6", 829 | "@babel/types": "^7.9.6", 830 | "assert-never": "^1.2.1", 831 | "babel-walk": "3.0.0-canary-5" 832 | } 833 | } 834 | } 835 | } 836 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Getting-MEAN-2nd-edition", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.19.0", 10 | "cookie-parser": "~1.4.4", 11 | "debug": "~4.1.1", 12 | "express": "~4.17.1", 13 | "morgan": "~1.9.1", 14 | "pug": "~3.0.1", 15 | "serve-favicon": "~2.5.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', (req, res, next) => { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', (req, res, next) => { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /views/index.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | -------------------------------------------------------------------------------- /views/layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content 8 | --------------------------------------------------------------------------------