Skip to content

Boulangerie/hapiour-decorators

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status npm version npm downloads dependencies npm devDependencies npm license

hapiour-decorators

Typescript decorators for Hapi

Install

npm install -g typescript
npm install --save hapi
npm install --save hapiour-decorators

Example

Files

src/
  -> main.ts
  -> app.ts
  -> beer.module.ts
  -> awesome.plugin.ts
  -> health.plugin.ts

Declare your app

src/app.ts

import { Server } from 'hapi'
import { App, IApp, Inject, Plugins } from 'hapiour-decorators'
import { Beer } from './beer.module'
import { AwesomePlugin } from './awesome.plugin'
import { HealthPluginConfigurator } from './health.plugin'

@App({
  port: 3000
})
@Inject([Beer])
@Plugins([AwesomePlugin, HealthPluginConfigurator])
export class MyApp implements IApp {

  public server: Server

  public constructor(server: Server) {
    this.server = server
  }

  public onInit(): void {
    console.log('Server init done')
  }

  public onRegister(): void {
    // server decorated by the AwesomePlugin
    if (this.server['isBeerAwesome']) {
      console.log('Beer is awesome')
    }
  }

  public onStart(): void {
    console.log('Server running at:', this.server.info.uri)
  }

}

Declare a module

src/beer.module.ts

import { Route, Module } from 'hapiour-decorators'
import { Request, ReplyNoContinue } from 'hapi'

@Module({
  basePath: '/beer'
})
export class Beer {

  private beerCount: number

  public constructor() {
    this.beerCount = 0
  }

  @Route({
    method: 'GET',
    path: '',
    config: {}
  })
  public getABeer(request: Request, reply: ReplyNoContinue) {
    this.beerCount++
    reply({
      'data': 'Hey! Take this beer !'
    })
  }

  @Route({
    method: 'GET',
    path: '/count',
    config: {}
  })
  public getCount(request: Request, reply: ReplyNoContinue) {
    reply({
      'data': this.beerCount
    })
  }

  @Route({
    method: 'DELETE',
    path: '/count',
    config: {}
  })
  public resetCount(request: Request, reply: ReplyNoContinue) {
    this.beerCount = 0
    reply({
      'data': 'Done'
    })
  }

}

Declare and configure a plugin

src/health.plugin.ts

import { PluginConfigurator, IPluginConfigurator, IPluginOptions } from 'hapiour-decorators'
import { Server } from 'hapi'
import * as alive from 'hapi-alive'

@PluginConfigurator(alive)
export class HealthPluginConfigurator implements IPluginConfigurator {

  public options: IPluginOptions

  public constructor() {
    this.options = {
      path: '/health',
      tags: ['health', 'monitor'],
      healthCheck: this.healthCheck
    }
  }

  private healthCheck(server: Server, callback: () => void): void {
    callback()
  }

}

Create a plugin

src/awesome.plugin.ts

import { Plugin, IPlugin, IPluginOptions } from 'hapiour-decorators'
import { Server } from 'hapi'

@Plugin({
  name: 'Awesome',
  version: '0.1.0'
})
export class AwesomePlugin implements IPlugin {

  public constructor() {
  }

  public register(server: Server, options: IPluginOptions, next: () => void): void {
    server.decorate('server', 'isBeerAwesome', () => {
      return true
    })
    next()
  }

}

Bootstrap your app

src/main.ts

import { bootstrap } from 'hapiour-decorators'
import { MyApp } from './app'

bootstrap(MyApp)

Or you can Bootstrap your app with options

src/main.ts

In this example apps are bootstraped with an external dependency injection library typedi

import { bootstrap } from 'hapiour-decorators'
import { MyApp } from './app'
import { Container } from 'typedi';

bootstrapWithOptions([MyApp], {
  injector: Container
})

API

Decorators

Class Decorators

  • @App(config: Hapi.IServerConnectionOptions) : Declare a new App (correspond to a new Hapi.Server instance).
  • @Module(config: IModuleConfig) : Declare a new Module (class containing routes).
  • @Inject(modules: Array<Module>) : Assign an array of modules to an App or a Module.
  • @Plugins(plugins: Array<IPlugin|IPluginConfigurator>) : Assign an array of plugins to an App.
  • @Plugin(attributes: {'name': String, 'version': String}) : Declare a new plugin.
  • @PluginConfigurator(plugin: IPlugin) : Declare and configure a plugin.

Method decorators

  • @Route(config: Hapi.IRouteConfiguration) : Declare a new Route inside a Module. The target method will become the route handler.

Interfaces

IApp

  • constructor(server: Hapi.Server) : App will be constructed with Hapi server instance as first argument.
  • onInit(): Method called when Hapi server initialization is done.
  • onRegister(): Method called when Hapi plugin registration is done.
  • onStart(): Method called when Hapi server is started.

IModuleConfig

  • basePath: string : Base path applied to all contained routes in the module.

IPlugin

  • register(server: Server, options: IPluginOptions, next: () => void): void : Plugin core function to be registered into Hapi.

IPluginConfigurator

  • options: IPluginOptions : Options used to configure a given plugin.

IBootstrapOptions

  • injector?: IInjector : Set a custom injector to your apps.

IInjector

  • get<T>(Dependency: IStatic<T>): T : Injector should at least have a get method to get dependencies.

Methods

  • bootstrap(...apps: Array<IApp>): Array<IApp> : Bootstrap your apps. Return an array of bootstraped apps.
  • bootstrapWithOptions(apps: Array<IApp>, options: IBootstrapOptions): Array<IApp> : Bootstrap your apps with options. Return an array of bootstraped apps.