Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

Commit 311b9fe

Browse files
authored
feat(hapi): upgrade to Hapi v17 (#1015)
BREAKING CHANGE: * The `ngHapiEngine` is no longer supported for Hapi v16. The `RESPONSE` token provided under `@nguniversal/hapi-engine/tokens` now uses the new `ResponseToolkit`, which is unavailable in Hapi v16. Updated instructions are available in the package's README
1 parent b417300 commit 311b9fe

11 files changed

Lines changed: 291 additions & 251 deletions

File tree

integration/hapi-engine/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"babel-loader": "^6.4.0",
3030
"babel-preset-es2015": "^6.22.0",
3131
"concurrently": "3.1.0",
32-
"inert": "^4.2.1",
32+
"inert": "^5.1.0",
3333
"protractor": "file:../../node_modules/protractor",
3434
"raw-loader": "^0.5.1",
3535
"webpack": "^2.2.1"

integration/hapi-engine/src/server.ts

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,48 @@ import {ngHapiEngine} from '@nguniversal/hapi-engine';
1111
require('zone.js/dist/zone-node.js');
1212

1313
import {enableProdMode} from '@angular/core';
14-
import * as Hapi from 'hapi';
14+
import {Server, Request} from 'hapi';
1515
import * as Inert from 'inert';
1616

1717
import {HelloWorldServerModuleNgFactory} from './helloworld/app.server.ngfactory';
18-
import {Base_Reply} from 'hapi';
1918
const helloworld = require('raw-loader!./helloworld/index.html');
2019

21-
const server = new Hapi.Server();
22-
server.connection({ port: 9876, host: 'localhost' });
23-
server.register(Inert, () => {});
20+
const server = new Server({ port: 9876, host: 'localhost' });
2421

2522
enableProdMode();
2623

27-
// Client bundles will be statically served from the built/ directory.
28-
server.route({
29-
method: 'GET',
30-
path: '/built/{file*}',
31-
handler: {
32-
directory: {
33-
path: 'built'
34-
}
35-
}
36-
});
37-
3824
// Keep the browser logs free of errors.
3925
server.route({
4026
method: 'GET',
4127
path: '/favicon.ico',
42-
handler: function (request, reply) {
43-
reply('');
44-
}
28+
handler: () => ''
4529
});
4630

4731
//-----------ADD YOUR SERVER SIDE RENDERED APP HERE ----------------------
4832
server.route({
4933
method: 'GET',
5034
path: '/helloworld',
51-
handler: (req: Request, reply: Base_Reply) => {
35+
handler: (req: Request) =>
5236
ngHapiEngine({
5337
bootstrap: HelloWorldServerModuleNgFactory,
5438
req,
5539
document: helloworld
56-
} as any).then(html => reply(html));
57-
}
40+
})
5841
});
5942

60-
server.start((err) => {
61-
if (err) {
62-
throw err;
63-
}
64-
console.log('Server listening on port 9876!');
65-
});
43+
(async() => {
44+
await server.register(Inert);
45+
46+
// Client bundles will be statically served from the built/ directory.
47+
server.route({
48+
method: 'GET',
49+
path: '/built/{file*}',
50+
handler: {
51+
directory: {
52+
path: 'built'
53+
}
54+
}
55+
});
56+
57+
await server.start();
58+
})();

modules/express-engine/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"@angular/common": "NG_VERSION",
1313
"@angular/core": "NG_VERSION",
1414
"@angular/platform-server": "NG_VERSION",
15-
"express": "^4.15.2"
15+
"express": "EXPRESS_VERSION"
1616
},
1717
"ng-update": {
1818
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"

modules/hapi-engine/README.md

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This is a Hapi Engine for running Angular Apps on the server for server side ren
99
To use it, set the engine and then route requests to it
1010

1111
```ts
12-
import { Base_Reply, Request, Server } from 'hapi';
12+
import { Request, Server } from 'hapi';
1313
import { ngHapiEngine } from '@nguniversal/hapi-engine';
1414

1515
const server = new Server();
@@ -18,20 +18,10 @@ server.connection({
1818
port: 8000
1919
});
2020

21-
// Set the engine
22-
const hapiEngine = ngHapiEngine({
23-
bootstrap: ServerAppModule // Give it a module to bootstrap
24-
});
25-
2621
server.route({
2722
method: 'GET',
2823
path: '/{path*}',
29-
handler: (req: Request, reply: Base_Reply) => {
30-
hapiEngine({
31-
req
32-
}).then(html => reply(html))
33-
.then(err => reply(boom.wrap(err)));
34-
}
24+
handler: (req: Request) => ngHapiEngine({req, bootstrap: ServerAppModule})
3525
});
3626
```
3727

@@ -44,15 +34,14 @@ is called. To do so, simply pass in a `url` and/or `document` string to the rend
4434
server.route({
4535
method: 'GET',
4636
path: '/{path*}',
47-
handler: (req: Request, reply: Base_Reply) => {
48-
let url = 'http://someurl.com';
49-
let doc = '<html><head><title>New doc</title></head></html>';
50-
hapiEngine({
37+
handler: (req: Request) => {
38+
const url = 'http://someurl.com';
39+
const document = '<html><head><title>New doc</title></head></html>';
40+
return ngHapiEngine({
5141
req,
5242
url,
53-
document: doc
54-
}).then(html => reply(html))
55-
.then(err => reply(boom.wrap(err)));
43+
document,
44+
});
5645
}
5746
});
5847
```
@@ -80,23 +69,21 @@ The Bootstrap module as well as more providers can be passed on request
8069
server.route({
8170
method: 'GET',
8271
path: '/{path*}',
83-
handler: (req: Request, reply: Base_Reply) => {
84-
hapiEngine({
72+
handler: (req: Request) =>
73+
ngHapiEngine({
8574
bootstrap: OtherServerAppModule,
8675
providers: [
8776
OtherServerService
8877
],
8978
req
90-
}).then(html => reply(html))
91-
.then(err => reply(boom.wrap(err)));
92-
}
79+
})
9380
});
9481
```
9582

9683
### Using the Request and Response
9784

9885
The Request and Response objects are injected into the app via injection tokens.
99-
You can access them by @Inject
86+
You can access them by `@Inject`
10087

10188
```ts
10289
import { Request } from 'hapi';

modules/hapi-engine/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"@angular/common": "NG_VERSION",
1313
"@angular/core": "NG_VERSION",
1414
"@angular/platform-server": "NG_VERSION",
15-
"hapi": "^16.1.1"
15+
"hapi": "HAPI_VERSION"
1616
},
1717
"ng-update": {
1818
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,69 @@
1+
import {Component, destroyPlatform, getPlatform, NgModule} from '@angular/core';
2+
import {ServerModule} from '@angular/platform-server';
3+
import {ngHapiEngine} from '@nguniversal/hapi-engine';
4+
import {ServerInjectResponse, Request, Server} from 'hapi';
5+
import 'zone.js';
6+
import {BrowserModule} from '@angular/platform-browser';
7+
8+
@Component({selector: 'app', template: `Works!`})
9+
class MyServerApp {
10+
}
11+
12+
13+
@NgModule({
14+
bootstrap: [MyServerApp],
15+
declarations: [MyServerApp],
16+
imports: [ServerModule, BrowserModule.withServerTransition({appId: 'hapi-test'})],
17+
})
18+
class ExampleModule {
19+
}
20+
21+
122
describe('test runner', () => {
2-
it('can run a test', () => {
3-
expect(true).toBe(true);
23+
24+
const server = new Server({ debug: false });
25+
server.route([
26+
{
27+
method: 'GET',
28+
path: '/',
29+
handler: (req: Request) => ngHapiEngine({
30+
bootstrap: ExampleModule,
31+
req,
32+
document: '<html><body><app></app></body></html>'
33+
})
34+
},
35+
{
36+
method: 'GET',
37+
path: '/test',
38+
handler: () => 'ok'
39+
},
40+
]);
41+
42+
beforeEach(async () => {
43+
if (getPlatform()) {
44+
destroyPlatform();
45+
}
46+
});
47+
48+
it('should test the server', async () => {
49+
const request = {
50+
method: 'GET',
51+
url: '/test'
52+
};
53+
54+
const res = await server.inject(request);
55+
expect(res.result).toBeDefined();
56+
expect(res.result).toBe('ok' as any);
57+
});
58+
59+
it('Returns a reply on successful request', async () => {
60+
const request = {
61+
method: 'GET',
62+
url: '/'
63+
};
64+
65+
const res: ServerInjectResponse = await server.inject(request);
66+
expect(res.result).toBeDefined();
67+
expect(res.result).toContain('Works!');
468
});
569
});

modules/hapi-engine/src/main.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import * as fs from 'fs';
9-
import { Request, Response } from 'hapi';
9+
import { Request, ResponseToolkit } from 'hapi';
1010

1111
import { NgModuleFactory, Type, CompilerFactory, Compiler, StaticProvider } from '@angular/core';
1212
import { ResourceLoader } from '@angular/compiler';
@@ -32,7 +32,7 @@ export interface NgSetupOptions {
3232
*/
3333
export interface RenderOptions extends NgSetupOptions {
3434
req: Request;
35-
res?: Response;
35+
res?: ResponseToolkit;
3636
url?: string;
3737
document?: string;
3838
}
@@ -90,16 +90,8 @@ export function ngHapiEngine(options: RenderOptions) {
9090
]);
9191

9292
getFactory(moduleOrFactory, compiler)
93-
.then(factory => {
94-
return renderModuleFactory(factory, {
95-
extraProviders
96-
});
97-
})
98-
.then((html: string) => {
99-
resolve(html);
100-
}, (err) => {
101-
reject(err);
102-
});
93+
.then(factory => renderModuleFactory(factory, {extraProviders}))
94+
.then(resolve, reject);
10395
});
10496
}
10597

@@ -128,9 +120,7 @@ function getFactory(
128120
.then((factory) => {
129121
factoryCacheMap.set(moduleOrFactory, factory);
130122
resolve(factory);
131-
}, (err => {
132-
reject(err);
133-
}));
123+
}, reject);
134124
}
135125
});
136126
}

modules/hapi-engine/tokens/tokens.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import { Request, Response } from 'hapi';
8+
import { Request, ResponseToolkit } from 'hapi';
99
import { InjectionToken } from '@angular/core';
1010

1111
export const REQUEST = new InjectionToken<Request>('REQUEST');
12-
export const RESPONSE = new InjectionToken<Response>('RESPONSE');
12+
export const RESPONSE = new InjectionToken<ResponseToolkit>('RESPONSE');

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@
8787
"@bazel/ibazel": "^0.3.1",
8888
"@types/express": "^4.0.39",
8989
"@types/fs-extra": "^4.0.5",
90-
"@types/hapi": "^16.1.2",
90+
"@types/hapi": "^17.0.12",
9191
"@types/jasmine": "^2.8.6",
9292
"@types/node": "^9.4.6",
9393
"camelcase": "^4.1.0",
9494
"express": "^4.15.2",
9595
"fs-extra": "^3.0.1",
9696
"glob": "^7.1.2",
97-
"hapi": "^16.1.1",
97+
"hapi": "^17.5.1",
9898
"jasmine-core": "^2.8.0",
9999
"karma": "^2.0.0",
100100
"karma-chrome-launcher": "^2.2.0",

tools/defaults.bzl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ DEFAULT_NODE_MODULES = "//:node_modules"
88

99
NG_VERSION = "^6.0.0-rc.0"
1010
RXJS_VERSION = "^6.0.0-beta.0"
11+
HAPI_VERSION = "^17.0.0"
12+
EXPRESS_VERSION = "^4.15.2"
1113

1214
NGUNIVERSAL_SCOPED_PACKAGES = ["@nguniversal/%s" % p for p in [
1315
"aspnetcore-engine",
@@ -20,6 +22,8 @@ NGUNIVERSAL_SCOPED_PACKAGES = ["@nguniversal/%s" % p for p in [
2022
PKG_GROUP_REPLACEMENTS = {
2123
"NG_VERSION": NG_VERSION,
2224
"RXJS_VERSION": RXJS_VERSION,
25+
"HAPI_VERSION": HAPI_VERSION,
26+
"EXPRESS_VERSION": EXPRESS_VERSION,
2327
"\"NG_UPDATE_PACKAGE_GROUP\"": """[
2428
%s
2529
]""" % ",\n ".join(["\"%s\"" % s for s in NGUNIVERSAL_SCOPED_PACKAGES])
@@ -39,14 +43,14 @@ GLOBALS = {
3943
"@nguniversal/express-engine/tokens": "nguniversal.expressEngine.tokens",
4044
"@nguniversal/hapi-engine/tokens": "nguniversal.hapiEngine.tokens",
4145
'tslib': 'tslib',
42-
"rxjs": "Rx",
43-
"rxjs/operators": "Rx.operators",
46+
"rxjs": "rxjs",
47+
"rxjs/operators": "rxjs.operators",
4448
"fs": "fs",
4549
"express": "express",
4650
"hapi": "hapi"
4751
}
4852

49-
# TODO: when a better api for defaults is avilable use that isntead of these macros
53+
# TODO(Toxicable): when a better api for defaults is avilable use that instead of these macros
5054
def ts_test_library(node_modules=None, **kwargs):
5155
ts_library(testonly=1, **kwargs)
5256

0 commit comments

Comments
 (0)