dekoa-hd

Decorators for Koa

Usage no npm install needed!

<script type="module">
  import dekoaHd from 'https://cdn.skypack.dev/dekoa-hd';
</script>

README

This is a folk from dekoa with the change https://github.com/jimzhan/dekoa/pull/2

dekoa - Decorators for Koa with :revolving_hearts:

build codecov Standard Version

JavaScript Style Guide Styled with Prettier Commitizen friendly dependencies npm version npm downloads

Handy decorators & middlewares dedicated for Koa, batteris included:

  • Class based routes supports (full HTTP method supports, RFC7231).
  • JSON Schema based validators (via koa-body).
  • Common middleware helpers.

Installation

npm install dekoa-hd

Decorators

  • route.js#bind(server, files, options)

    • assuming we have all the view controllers under src/resources/.
    // src/server.js
    import Koa from 'koa'
    import glob from 'glob'
    import debug from 'debug'
    import * as dekoa from 'dekoa-hd'
    
    const log = debug('debug')
    const server = new Koa()
    
    // all of the view controllers defined in `src/resources` will be automatically registered.
    const views = glob.sync(`${__dirname}/resources/*.js`)
    dekoa.bind(server, views, { prefix: '/v1' })
    
    const port = process.env.PORT || 9394;
    server.listen(port, () => {
      log(`Server started at port: ${port}`)
    })
    
    • sample view controllers with decorators supports.
    // src/resources/accounts.js
    import Status from 'http-status-codes'
    import { resource, get, post } from 'dekoa'
    
    @resource('accounts')
    export default class Account {
      @get('/:id')
      async findById(ctx) {
        const params = ctx.params
        ctx.status = Status.OK
        ctx.body = { id: params.id, username: 'test@example.com' }
      }
    
      @post('/')
      async create(ctx) {
        ctx.status = Status.CREATED
        ctx.body = { username: 'test@example.com' }
      }
    }
    
    import Status from 'http-status-codes'
    import { resource, post } from 'dekoa'
    
    // `resource` decorator without prefix will be injected as top level URL.
    @resource
    export default class Auth {
      @post('/login')
      async login(ctx) {
        ctx.status = Status.RESET_CONTENT
      }
    
      @post('/logout')
      async logout(ctx) {
        ctx.status = Status.RESET_CONTENT
      }
    }
    
  • JSON Schema, e.g. NewAccount.json.

    {
      "properties": {
        "username": {
          "type": "string",
          "format": "email",
          "minLength": 5,
          "maxLength": 255
        },
        "password": {
          "type": "string",
          "minLength": 6,
          "maxLength": 20
        }
      },
      "required": ["username", "password"]
    }
    
  • validate incoming form data

    const NewAccount = require('./NewAccount.json')
    
    @resource('inputs')
    export default class Input {
      @post('/', NewAccount)
      async create(ctx) {
        ctx.status = Status.CREATED
        ctx.body = { username: 'test@example.com' }
      }
    }
    
  • validate incoming http query (GET|HEAD|DELETE ONLY)

    const Account = require('./Account.json')
    
    @resource('inputs')
    export default class Input {
      @get('/', Account)
      async find(ctx) {
        ctx.status = Status.OK
        ctx.body = { username: 'test@example.com' }
      }
    }
    

Middlewares

  • XSRF (aka. CSRF) - built on top of CSRF, set for SPA without session dependency via cookie and header. Available options:
    • xsrfCookieName - cookie name for saving XSRF token (default xsrftoken).
    • xsrfHeaderName - http header name for responsing XSRF token, value is same as cookie's one (default X-XSRF-Token).
    • invalidTokenMessage - error message responded for client (default Invalid XSRF Token).
    • invalidTokenStatusCode - error http status code responded for client (default 403).
    • excludedMethods - methods bypass for XSRF token checking (default [ 'GET', 'HEAD', 'OPTIONS' ]).
    • renewPostWrite - whether XSRF token should be renew after each write (default: false).
import Koa from 'koa'
import { middleware } from 'dekoa'

const server = new Koa()
server.use(middleware.XSRF('<my-app-secret>'))
server.listen(port, () => {
  log(`Server started at port: ${port}`)
})

Regular Expression Helpers

  • dekoa.regex.chinese - chinese characters.
  • dekoa.regex.email - email address.
  • dekoa.regex.password - valid password (>= 6 bits, includes at least 1 lower & 1 upper letter, 1 number & 1 special character).
  • dekoa.regex.integer - positive/negative integer.
  • dekoa.regex.number - positive/negative number.
  • dekoa.regex.url - http/ftp/file address.
  • dekoa.regex.ipv4 - IP address version 4.