Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ $ yarn add @hapiness/core rxjs

```javascript
"dependencies": {
"@hapiness/core": "^1.2.2",
"@hapiness/core": "^1.3.0",
//...
}
//...
```

### Use Hapiness API

Actually, we're in : **v1.2.1**
Actually, we're in : **v1.3.0**

See [API](https://github.com/hapinessjs/hapiness/blob/master/API.md) Reference to know what's already implemented.

Expand All @@ -115,6 +115,10 @@ To set up your development environment:
[Back to top](#table-of-contents)

## Change History
* v1.3.0 (2017-11-30)
* Option that allow WS Server Ext to share Http Server Ext port
* Handle HapiJS connections system to listen multiple ports
* Documentation
* v1.2.2 (2017-11-20)
* Export `createDecorator()`, `extractMetadata()`, `extractMetadataByDecorator`, `errorHandler()` methods and `DependencyInjection` class
* Documentation
Expand Down
40 changes: 20 additions & 20 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hapiness/core",
"version": "1.2.2",
"version": "1.3.0",
"description": "Project to have a HapiJS (https://hapijs.com/) based framework to create easier NodeJS back-end with some awesome features",
"main": "commonjs/index.js",
"types": "index.d.ts",
Expand Down Expand Up @@ -75,12 +75,12 @@
"dependencies": {
"@types/hapi": "^16.1.11",
"@types/hoek": "^4.1.3",
"@types/joi": "^13.0.0",
"@types/joi": "^13.0.1",
"@types/node": "^8.0.53",
"@types/websocket": "^0.0.34",
"@types/websocket": "^0.0.35",
"debug": "^3.1.0",
"hapi": "^16.6.2",
"injection-js": "^2.2.0",
"injection-js": "^2.2.1",
"reflect-metadata": "^0.1.10",
"websocket": "^1.0.25"
},
Expand All @@ -95,7 +95,7 @@
"rxjs": "^5.5.2",
"ts-node": "^3.3.0",
"tslint": "^5.8.0",
"typescript": "^2.6.1",
"typescript": "^2.6.2",
"unit.js": "^2.0.0"
},
"engines": {
Expand Down
16 changes: 15 additions & 1 deletion src/extensions/http-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ The extension is based on HapiJS
);
```

```
{
host: string
port: number
options?: ServerOptions
}
//or
{
connections: ConnectionOptions[]
options?: ServerOptions
}
```

Configuration - [HapiJS Connection options](https://hapijs.com/api#serverconnectionoptions)

## Extension provider
Expand All @@ -37,6 +50,7 @@ Declare HTTP routes
- `method` - can be an array, values: (get, post, put, delete, patch, options)
- `config` - partially implemented, see [HapiJS Route config](https://hapijs.com/api#route-configuration)
- `providers` - Providers to add in the request DI, it means at each request a new instance of the provider will be created
- `labels`- `string | string[]` Used to attach a route to a connection for multiple connections

- interfaces
- see request and reply on [HapiJS Docs](https://hapijs.com/api#requests)
Expand Down Expand Up @@ -82,7 +96,7 @@ Request lifecycle component

- `event` - request lifecycle event, see [HapiJS Request lifecycle](https://hapijs.com/api#request-lifecycle)
events: (onPreAuth, onPostAuth, onPreHandler, onPostHandler, onPreResponse)

- interfaces

- see request and reply on [HapiJS Docs](https://hapijs.com/api#requests)
Expand Down
4 changes: 3 additions & 1 deletion src/extensions/http-server/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ export interface Route {
method: string | string[];
config?: RouteConfig;
providers?: Array<Type<any>|any>;
labels?: string | string[];
}
export const Route: CoreDecorator<Route> = createDecorator<Route>('Route', {
path: undefined,
method: undefined,
config: undefined,
providers: undefined
providers: undefined,
labels: undefined
});

export interface Lifecycle {
Expand Down
101 changes: 80 additions & 21 deletions src/extensions/http-server/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Type } from '../../core/decorators';
import { enumByMethod, LifecycleComponentEnum } from './enums';
import { LifecycleManager } from './lifecycle';
import { RouteBuilder } from './route';
import { CoreRoute, HapiConfig, HapinessHTTPHandlerResponse } from './interfaces';
import { ConnectionOptions, CoreRoute, HapiConfig, HTTPHandlerResponse } from './interfaces';
import { Observable } from 'rxjs';
import { RouteConfiguration, Server, Request, ReplyNoContinue, ReplyWithContinue } from 'hapi';

Expand All @@ -32,7 +32,12 @@ export class HttpServerExt implements OnExtensionLoad, OnModuleInstantiated {
onExtensionLoad(module: CoreModule, config: HapiConfig): Observable<Extension> {
return Observable
.of(new Server(config.options))
.do(_ => _.connection(Object.assign({}, config, { options: undefined })))
.flatMap(server => Observable
.of(Object.assign({}, config, { options: undefined }))
.map(_ => this.formatConnections(_))
.do(_ => _.forEach(connection => server.connection(connection)))
.map(_ => server)
)
.flatMap(server =>
Observable
.of({
Expand Down Expand Up @@ -63,6 +68,23 @@ export class HttpServerExt implements OnExtensionLoad, OnModuleInstantiated {
.flatMap(_ => server.start());
}

/**
* Format the config provided
* to a list of ConnectionOptions
*
* @param {HapiConfig} config
* @returns ConnectionOptions
*/
private formatConnections(config: HapiConfig): ConnectionOptions[] {
return []
.concat(!!(<any>config).connections ?
(<any>config).connections :
config
)
.filter(_ => !!_)
.map(_ => <ConnectionOptions>_);
}

/**
* Register a HapiJS Plugin
*
Expand All @@ -71,36 +93,50 @@ export class HttpServerExt implements OnExtensionLoad, OnModuleInstantiated {
* @returns Observable
*/
private registerPlugin(module: CoreModule, server: Server): Observable<CoreRoute[]> {
const register: any = (s, o, n) => n();
register.attributes = {
name: module.name,
version: module.version
};
return Observable
.fromPromise(server.register(register))
.flatMap(_ => this.addRoutes(module, server));
return this
.buildRoutes(module)
.flatMap(routes => Observable
.of(<any>this.registerHandler(routes))
.do(_ => _.attributes = { name: module.name, version: module.version })
.flatMap(_ => Observable
.fromPromise(server.register(_))
.map(__ => routes)
)
);
}

/**
* Add routes from CoreModule
*
* @param {CoreModule} module
* @param {Server} server
* @param {CoreRoute[]} module
* @returns Observable
*/
private addRoutes(module: CoreModule, server: Server): Observable<CoreRoute[]> {
return Observable
.from(RouteBuilder.buildRoutes(module))
.do(_ =>
server
.route(<RouteConfiguration>{
private registerHandler(routes: CoreRoute[] = []): (s, o, n) => void {
return (server: Server, options, next) => {
routes
.forEach(_ => {
const _server = !!_.labels ? server.select(_.labels) : server;
_server.route(<RouteConfiguration>{
method: _.method,
path: _.path,
config: Object.assign({
handler: (request, reply) => this.httpHandler(request, reply, _)
}, _.config)
})
)
});
});
next();
}
}

/**
* Build CoreRoute based on a module
*
* @param {CoreModule} module
* @returns Observable
*/
private buildRoutes(module: CoreModule): Observable<CoreRoute[]> {
return Observable
.from(RouteBuilder.buildRoutes(module))
.toArray();
}

Expand Down Expand Up @@ -135,14 +171,26 @@ export class HttpServerExt implements OnExtensionLoad, OnModuleInstantiated {
);
}

private formatResponse(data: any): HapinessHTTPHandlerResponse {
/**
* Format response to HTTPHandlerResponse object
*
* @param {any} data
* @returns HTTPHandlerResponse
*/
private formatResponse(data: any): HTTPHandlerResponse {
return {
statusCode: !!data ? data.statusCode || 200 : 200,
headers: !!data ? data.headers || {} : {},
response: !!data ? data.response || data : data
};
}

/**
* Check of response is not empty
*
* @param {any} response
* @returns boolean
*/
private isValid(response: any): boolean {
return typeof(response) !== 'undefined' && response !== null;
}
Expand Down Expand Up @@ -172,6 +220,17 @@ export class HttpServerExt implements OnExtensionLoad, OnModuleInstantiated {
.map(_ => module);
}

/**
* Lifecycle Event Handler
* Instantiate the Lifecycle component
* And trigger the hook
*
* @param {Type<any>} lifecycle
* @param {CoreModule} module
* @param {Request} request
* @param {ReplyWithContinue} reply
* @returns Observable
*/
private eventHandler(lifecycle: Type<any>, module: CoreModule, request: Request, reply: ReplyWithContinue): Observable<any> {
return Observable
.of(lifecycle)
Expand Down
Loading