├── .gitignore ├── src ├── tsconfig.json ├── package.json └── index.ts ├── package.json ├── README.md └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "../dist/packages-dist", 4 | "sourceMap": true, 5 | "declaration": true, 6 | "moduleResolution": "node", 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "target": "es5", 10 | "typeRoots": [ 11 | "node_modules/@types" 12 | ], 13 | "lib": [ 14 | "es2017", 15 | "dom" 16 | ] 17 | }, 18 | "files": [ 19 | "index.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-universal-express", 3 | "version": "0.0.3", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 0", 8 | "build": "node_modules/.bin/tsc -p src/tsconfig.json && cp src/package.json dist/packages-dist" 9 | }, 10 | "keywords": [ 11 | "angular", 12 | "ssr", 13 | "express" 14 | ], 15 | "author": "David East", 16 | "license": "MIT", 17 | "dependencies": { 18 | "@angular/animations": "^4.2.4", 19 | "@angular/common": "^4.2.4", 20 | "@angular/compiler": "^4.2.4", 21 | "@angular/core": "^4.2.4", 22 | "@angular/forms": "^4.2.4", 23 | "@angular/http": "^4.2.4", 24 | "@angular/platform-browser": "^4.2.4", 25 | "@angular/platform-browser-dynamic": "^4.2.4", 26 | "@angular/platform-server": "^4.3.3", 27 | "@angular/router": "^4.2.4", 28 | "@types/express": "^4.0.36", 29 | "core-js": "^2.4.1", 30 | "express": "^4.15.3", 31 | "rxjs": "^5.4.2", 32 | "zone.js": "^0.8.14" 33 | }, 34 | "devDependencies": { 35 | "typescript": "^2.4.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-universal-express", 3 | "version": "0.0.3", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 0", 8 | "build": "../node_modules/.bin/tsc && cp package.json dist/packages-dist" 9 | }, 10 | "keywords": [ 11 | "angular", 12 | "ssr", 13 | "express" 14 | ], 15 | "author": "David East", 16 | "license": "MIT", 17 | "dependencies": { 18 | "@types/express": "^4.0.36", 19 | "express": "^4.15.3" 20 | }, 21 | "peerDependencies": { 22 | "@angular/animations": "^4.2.4", 23 | "@angular/common": "^4.2.4", 24 | "@angular/compiler": "^4.2.4", 25 | "@angular/core": "^4.2.4", 26 | "@angular/forms": "^4.2.4", 27 | "@angular/http": "^4.2.4", 28 | "@angular/platform-browser": "^4.2.4", 29 | "@angular/platform-browser-dynamic": "^4.2.4", 30 | "@angular/platform-server": "^4.3.3", 31 | "@angular/router": "^4.2.4", 32 | "core-js": "^2.4.1", 33 | "rxjs": "^5.4.2", 34 | "zone.js": "^0.8.14" 35 | }, 36 | "devDependencies": { 37 | "typescript": "^2.4.2" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import 'zone.js/dist/zone-node'; 2 | import * as express from 'express'; 3 | import { enableProdMode as enableProd, Provider } from '@angular/core'; 4 | import { renderModuleFactory } from '@angular/platform-server'; 5 | import * as fs from 'fs'; 6 | import { Observable, Observer } from 'rxjs'; 7 | 8 | export interface ServerConfiguration { 9 | main: string; 10 | index: string; 11 | enableProdMode?: boolean; 12 | staticDirectory?: string; 13 | extraProviders?: Provider[]; 14 | } 15 | 16 | /** 17 | * Create a single observable of a file system read 18 | * @param file the file path to read 19 | */ 20 | function readFile$(file: string): Observable { 21 | return Observable.create((observer: Observer) => { 22 | fs.readFile(file, 'utf8', (err, data) => { 23 | if(err) { 24 | observer.error(err); 25 | } else { 26 | observer.next(data); 27 | observer.complete(); 28 | } 29 | }); 30 | }); 31 | } 32 | 33 | /** 34 | * Create the Angular Universal request handler 35 | * @param config 36 | */ 37 | export function angularUniversal({ index, main, staticDirectory, enableProdMode = false, extraProviders }: ServerConfiguration) { 38 | if (enableProdMode) { enableProd(); } 39 | return (req: express.Request, res: express.Response) => { 40 | readFile$(index) 41 | .mergeMap(document => { 42 | const url = req.path; 43 | const AppServerModuleNgFactory = require(main).AppServerModuleNgFactory; 44 | return Observable.from(renderModuleFactory(AppServerModuleNgFactory, { document, url, extraProviders: extraProviders })) 45 | }) 46 | .take(1) 47 | .subscribe(html => { res.send(html); }); 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

Angular Universal Express

3 |

4 | A (somehow even simplier) setup for Angular Universal and Express. 5 |

6 |
7 | 8 | ## Status 9 | Alpha: This package is in an infant stage. Any usage and feedback is welcome. 10 | 11 | ## Install 12 | ```bash 13 | npm i angular-universal-express 14 | # or 15 | yarn add angular-universal-express 16 | ``` 17 | 18 | ## Basic usage (TypeScript) 19 | ```ts 20 | import { angularUniversal } from 'angular-universal-express'; 21 | import * as express from 'express'; 22 | 23 | const app = express(); 24 | /* 25 | I usually copy my Angular CLI "dist" build into my "dist-server" build 26 | and serve them as static files so they aren't treated as dynamic routes. 27 | */ 28 | app.use(express.static(__dirname + '/dist')); 29 | app.get('/*', angularUniversal({ 30 | index: 'path/to/index.html', 31 | main: 'path/to/main..bundle', 32 | enableProdMode: true, 33 | extraOptions: [ 34 | provideModuleMap(LAZY_MODULE_MAP) 35 | ] 36 | })); 37 | app.listen(3005, () => { console.log('Listening on 3005'); }); 38 | ``` 39 | 40 | ## Setup 41 | There are two parts to an Angular Universal app: the **server build** and the **server**. 42 | 43 | ### Server Build 44 | The current RC version of the Angular CLI covers the server build. [Follow these steps to setup the CLI to get a server build.](https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/universal-rendering.md) 45 | 46 | #### Build both browser and server Angular builds 47 | At this point you should have two app entries in your `angularcli.json` file: **browser** and **server**. The browser build writes to the `dist` folder and the server build writes to the `dist-server` folder. 48 | 49 | #### Delete `dist/index.html`. 50 | This index file is uneeded because Angular Universal uses the assets in `dist-server` to generate the initial HTML. 51 | 52 | #### Copy `dist` to `dist-server/dist` 53 | 54 | The server responds to requests from the browser. There are two types of requests to handle: dynamic and static. For dynamic routes Express will respond with HTML generated from Angular Universal. But for static routes you don't want to run Angular Universal. 55 | 56 | For this example, copying the contents of `dist` into `dist-server/dist` will allow you to set up a static directory for `dist-server/dist`. This way Express won't treat those requests as dynamic. 57 | 58 | ### Server 59 | 60 | In your Angular CLI project find the `dist-server` folder and add an `index.js` file inside of it. 61 | 62 | ```js 63 | const { angularUniversal } = require('angular-universal-express'); 64 | const express = require('express'); 65 | 66 | const app = express(); 67 | // This will treat each file in `/dist` as static. However, it will not 68 | // map the URL for the request to "/dist/file.js". It actually treats 69 | // the files in "/dist" as if they are at the root. This means the 70 | // request is actually "file.js" rather than "dist/file.js". 71 | app.use(express.static(__dirname + '/dist')); 72 | app.get('/*', angularUniversal({ 73 | index: 'path/to/index.html', 74 | main: 'path/to/main..bundle', 75 | enableProdMode: true 76 | })); 77 | app.listen(3005, () => { console.log('Listening on 3005'); }); 78 | ``` 79 | 80 | #### Run 81 | 82 | ```bash 83 | node dist-server/index.js 84 | # site will serve on localhost:3005 85 | ``` 86 | 87 | ## Deploying 88 | 89 | Angular Universal Express can be run on any node.js host. See the list below for setting up specific hosts: 90 | - [Firebase Hosting + Cloud Functions](https://github.com/davideast/angular-universal-express-firebase) 91 | - Contribute more! 92 | 93 | 94 | ## Contribute!? 95 | ```bash 96 | git clone https://github.com/davideast/angular-universal-express.git 97 | # npm setup 98 | npm i 99 | npm run build 100 | # yarn setup 101 | yarn 102 | yarn build 103 | ``` 104 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@angular/animations@^4.2.4": 6 | version "4.3.3" 7 | resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.3.3.tgz#b71ddd453673929f550b171cca99952b3aaa831c" 8 | dependencies: 9 | tslib "^1.7.1" 10 | 11 | "@angular/common@^4.2.4": 12 | version "4.3.3" 13 | resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.3.3.tgz#1fafbea33af4eba4cddd8677ef57a0f76a50488c" 14 | dependencies: 15 | tslib "^1.7.1" 16 | 17 | "@angular/compiler@^4.2.4": 18 | version "4.3.3" 19 | resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.3.3.tgz#8c1582fe28a784401325e51a04a9b36b6712033e" 20 | dependencies: 21 | tslib "^1.7.1" 22 | 23 | "@angular/core@^4.2.4": 24 | version "4.3.3" 25 | resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.3.3.tgz#8e6a76914661db407fa2d88dd2441c4c016ff625" 26 | dependencies: 27 | tslib "^1.7.1" 28 | 29 | "@angular/forms@^4.2.4": 30 | version "4.3.3" 31 | resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.3.3.tgz#0912aebb818a176f4e08b7df0ec9fd4021efcb6b" 32 | dependencies: 33 | tslib "^1.7.1" 34 | 35 | "@angular/http@^4.2.4": 36 | version "4.3.3" 37 | resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.3.3.tgz#cbe3639010362b681076f0b606673a0e62fd940d" 38 | dependencies: 39 | tslib "^1.7.1" 40 | 41 | "@angular/platform-browser-dynamic@^4.2.4": 42 | version "4.3.3" 43 | resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.3.3.tgz#b16c09dfe97b5b83daa0581b233f5ea3c3eefb3a" 44 | dependencies: 45 | tslib "^1.7.1" 46 | 47 | "@angular/platform-browser@^4.2.4": 48 | version "4.3.3" 49 | resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.3.3.tgz#623b659794f079096d4f7685b4bebcb49e3b9a71" 50 | dependencies: 51 | tslib "^1.7.1" 52 | 53 | "@angular/platform-server@^4.3.3": 54 | version "4.3.3" 55 | resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.3.3.tgz#404c00208d7258d4f9a54c9a5dda2147b21b6c9b" 56 | dependencies: 57 | parse5 "^3.0.1" 58 | tslib "^1.7.1" 59 | xhr2 "^0.1.4" 60 | 61 | "@angular/router@^4.2.4": 62 | version "4.3.3" 63 | resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.3.3.tgz#f3f9004ec31b4fe4d15477e1e63e118df36ad46d" 64 | dependencies: 65 | tslib "^1.7.1" 66 | 67 | "@types/express-serve-static-core@*": 68 | version "4.0.49" 69 | resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.49.tgz#3438d68d26e39db934ba941f18e3862a1beeb722" 70 | dependencies: 71 | "@types/node" "*" 72 | 73 | "@types/express@^4.0.36": 74 | version "4.0.36" 75 | resolved "https://registry.yarnpkg.com/@types/express/-/express-4.0.36.tgz#14eb47de7ecb10319f0a2fb1cf971aa8680758c2" 76 | dependencies: 77 | "@types/express-serve-static-core" "*" 78 | "@types/serve-static" "*" 79 | 80 | "@types/mime@*": 81 | version "1.3.1" 82 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.1.tgz#2cf42972d0931c1060c7d5fa6627fce6bd876f2f" 83 | 84 | "@types/node@*": 85 | version "8.0.19" 86 | resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.19.tgz#e46e2b0243de7d03f15b26b45c59ebb84f657a4e" 87 | 88 | "@types/node@^6.0.46": 89 | version "6.0.85" 90 | resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.85.tgz#ec02bfe54a61044f2be44f13b389c6a0e8ee05ae" 91 | 92 | "@types/serve-static@*": 93 | version "1.7.31" 94 | resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.7.31.tgz#15456de8d98d6b4cff31be6c6af7492ae63f521a" 95 | dependencies: 96 | "@types/express-serve-static-core" "*" 97 | "@types/mime" "*" 98 | 99 | accepts@~1.3.3: 100 | version "1.3.3" 101 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" 102 | dependencies: 103 | mime-types "~2.1.11" 104 | negotiator "0.6.1" 105 | 106 | array-flatten@1.1.1: 107 | version "1.1.1" 108 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 109 | 110 | content-disposition@0.5.2: 111 | version "0.5.2" 112 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 113 | 114 | content-type@~1.0.2: 115 | version "1.0.2" 116 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" 117 | 118 | cookie-signature@1.0.6: 119 | version "1.0.6" 120 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 121 | 122 | cookie@0.3.1: 123 | version "0.3.1" 124 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 125 | 126 | core-js@^2.4.1: 127 | version "2.4.1" 128 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" 129 | 130 | debug@2.6.7: 131 | version "2.6.7" 132 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" 133 | dependencies: 134 | ms "2.0.0" 135 | 136 | depd@1.1.0: 137 | version "1.1.0" 138 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" 139 | 140 | depd@~1.1.0: 141 | version "1.1.1" 142 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" 143 | 144 | destroy@~1.0.4: 145 | version "1.0.4" 146 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 147 | 148 | ee-first@1.1.1: 149 | version "1.1.1" 150 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 151 | 152 | encodeurl@~1.0.1: 153 | version "1.0.1" 154 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" 155 | 156 | escape-html@~1.0.3: 157 | version "1.0.3" 158 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 159 | 160 | etag@~1.8.0: 161 | version "1.8.0" 162 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051" 163 | 164 | express@^4.15.3: 165 | version "4.15.3" 166 | resolved "https://registry.yarnpkg.com/express/-/express-4.15.3.tgz#bab65d0f03aa80c358408972fc700f916944b662" 167 | dependencies: 168 | accepts "~1.3.3" 169 | array-flatten "1.1.1" 170 | content-disposition "0.5.2" 171 | content-type "~1.0.2" 172 | cookie "0.3.1" 173 | cookie-signature "1.0.6" 174 | debug "2.6.7" 175 | depd "~1.1.0" 176 | encodeurl "~1.0.1" 177 | escape-html "~1.0.3" 178 | etag "~1.8.0" 179 | finalhandler "~1.0.3" 180 | fresh "0.5.0" 181 | merge-descriptors "1.0.1" 182 | methods "~1.1.2" 183 | on-finished "~2.3.0" 184 | parseurl "~1.3.1" 185 | path-to-regexp "0.1.7" 186 | proxy-addr "~1.1.4" 187 | qs "6.4.0" 188 | range-parser "~1.2.0" 189 | send "0.15.3" 190 | serve-static "1.12.3" 191 | setprototypeof "1.0.3" 192 | statuses "~1.3.1" 193 | type-is "~1.6.15" 194 | utils-merge "1.0.0" 195 | vary "~1.1.1" 196 | 197 | finalhandler@~1.0.3: 198 | version "1.0.3" 199 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89" 200 | dependencies: 201 | debug "2.6.7" 202 | encodeurl "~1.0.1" 203 | escape-html "~1.0.3" 204 | on-finished "~2.3.0" 205 | parseurl "~1.3.1" 206 | statuses "~1.3.1" 207 | unpipe "~1.0.0" 208 | 209 | forwarded@~0.1.0: 210 | version "0.1.0" 211 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" 212 | 213 | fresh@0.5.0: 214 | version "0.5.0" 215 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" 216 | 217 | http-errors@~1.6.1: 218 | version "1.6.1" 219 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257" 220 | dependencies: 221 | depd "1.1.0" 222 | inherits "2.0.3" 223 | setprototypeof "1.0.3" 224 | statuses ">= 1.3.1 < 2" 225 | 226 | inherits@2.0.3: 227 | version "2.0.3" 228 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 229 | 230 | ipaddr.js@1.4.0: 231 | version "1.4.0" 232 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0" 233 | 234 | media-typer@0.3.0: 235 | version "0.3.0" 236 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 237 | 238 | merge-descriptors@1.0.1: 239 | version "1.0.1" 240 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 241 | 242 | methods@~1.1.2: 243 | version "1.1.2" 244 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 245 | 246 | mime-db@~1.29.0: 247 | version "1.29.0" 248 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.29.0.tgz#48d26d235589651704ac5916ca06001914266878" 249 | 250 | mime-types@~2.1.11, mime-types@~2.1.15: 251 | version "2.1.16" 252 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.16.tgz#2b858a52e5ecd516db897ac2be87487830698e23" 253 | dependencies: 254 | mime-db "~1.29.0" 255 | 256 | mime@1.3.4: 257 | version "1.3.4" 258 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" 259 | 260 | ms@2.0.0: 261 | version "2.0.0" 262 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 263 | 264 | negotiator@0.6.1: 265 | version "0.6.1" 266 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 267 | 268 | on-finished@~2.3.0: 269 | version "2.3.0" 270 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 271 | dependencies: 272 | ee-first "1.1.1" 273 | 274 | parse5@^3.0.1: 275 | version "3.0.2" 276 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.2.tgz#05eff57f0ef4577fb144a79f8b9a967a6cc44510" 277 | dependencies: 278 | "@types/node" "^6.0.46" 279 | 280 | parseurl@~1.3.1: 281 | version "1.3.1" 282 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" 283 | 284 | path-to-regexp@0.1.7: 285 | version "0.1.7" 286 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 287 | 288 | proxy-addr@~1.1.4: 289 | version "1.1.5" 290 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918" 291 | dependencies: 292 | forwarded "~0.1.0" 293 | ipaddr.js "1.4.0" 294 | 295 | qs@6.4.0: 296 | version "6.4.0" 297 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" 298 | 299 | range-parser@~1.2.0: 300 | version "1.2.0" 301 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 302 | 303 | rxjs@^5.4.2: 304 | version "5.4.2" 305 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.2.tgz#2a3236fcbf03df57bae06fd6972fd99e5c08fcf7" 306 | dependencies: 307 | symbol-observable "^1.0.1" 308 | 309 | send@0.15.3: 310 | version "0.15.3" 311 | resolved "https://registry.yarnpkg.com/send/-/send-0.15.3.tgz#5013f9f99023df50d1bd9892c19e3defd1d53309" 312 | dependencies: 313 | debug "2.6.7" 314 | depd "~1.1.0" 315 | destroy "~1.0.4" 316 | encodeurl "~1.0.1" 317 | escape-html "~1.0.3" 318 | etag "~1.8.0" 319 | fresh "0.5.0" 320 | http-errors "~1.6.1" 321 | mime "1.3.4" 322 | ms "2.0.0" 323 | on-finished "~2.3.0" 324 | range-parser "~1.2.0" 325 | statuses "~1.3.1" 326 | 327 | serve-static@1.12.3: 328 | version "1.12.3" 329 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.3.tgz#9f4ba19e2f3030c547f8af99107838ec38d5b1e2" 330 | dependencies: 331 | encodeurl "~1.0.1" 332 | escape-html "~1.0.3" 333 | parseurl "~1.3.1" 334 | send "0.15.3" 335 | 336 | setprototypeof@1.0.3: 337 | version "1.0.3" 338 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" 339 | 340 | "statuses@>= 1.3.1 < 2", statuses@~1.3.1: 341 | version "1.3.1" 342 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" 343 | 344 | symbol-observable@^1.0.1: 345 | version "1.0.4" 346 | resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" 347 | 348 | tslib@^1.7.1: 349 | version "1.7.1" 350 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.1.tgz#bc8004164691923a79fe8378bbeb3da2017538ec" 351 | 352 | type-is@~1.6.15: 353 | version "1.6.15" 354 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" 355 | dependencies: 356 | media-typer "0.3.0" 357 | mime-types "~2.1.15" 358 | 359 | typescript@^2.4.2: 360 | version "2.4.2" 361 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.2.tgz#f8395f85d459276067c988aa41837a8f82870844" 362 | 363 | unpipe@~1.0.0: 364 | version "1.0.0" 365 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 366 | 367 | utils-merge@1.0.0: 368 | version "1.0.0" 369 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" 370 | 371 | vary@~1.1.1: 372 | version "1.1.1" 373 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" 374 | 375 | xhr2@^0.1.4: 376 | version "0.1.4" 377 | resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" 378 | 379 | zone.js@^0.8.14: 380 | version "0.8.16" 381 | resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.8.16.tgz#ac31b6c418f88c0f918ad6acd8a402aca9313abb" 382 | --------------------------------------------------------------------------------