{"id":14989453,"url":"https://github.com/jimzhan/dekoa","last_synced_at":"2025-04-12T00:32:23.984Z","repository":{"id":22744724,"uuid":"97202685","full_name":"jimzhan/dekoa","owner":"jimzhan","description":"Decorators for Koa","archived":false,"fork":false,"pushed_at":"2023-01-23T20:38:00.000Z","size":2908,"stargazers_count":12,"open_issues_count":15,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T10:43:49.112Z","etag":null,"topics":["decorator","decorators","es6","es7","koa","koa-router","koa2","koajs","router","typescript"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jimzhan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-14T06:50:04.000Z","updated_at":"2024-01-21T10:40:53.000Z","dependencies_parsed_at":"2023-02-13T03:01:47.745Z","dependency_job_id":null,"html_url":"https://github.com/jimzhan/dekoa","commit_stats":null,"previous_names":[],"tags_count":60,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimzhan%2Fdekoa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimzhan%2Fdekoa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimzhan%2Fdekoa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimzhan%2Fdekoa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jimzhan","download_url":"https://codeload.github.com/jimzhan/dekoa/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248501425,"owners_count":21114674,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decorator","decorators","es6","es7","koa","koa-router","koa2","koajs","router","typescript"],"created_at":"2024-09-24T14:18:23.760Z","updated_at":"2025-04-12T00:32:23.687Z","avatar_url":"https://github.com/jimzhan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dekoa - Decorators for Koa with :revolving_hearts:\n\n[![build](https://travis-ci.org/jimzhan/dekoa.svg?branch=master)](https://travis-ci.org/jimzhan/dekoa)\n[![codecov](https://codecov.io/gh/jimzhan/dekoa/branch/master/graph/badge.svg)](https://codecov.io/gh/jimzhan/dekoa)\n[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)\n\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n[![Styled with Prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n[![dependencies](https://david-dm.org/jimzhan/dekoa.svg)](https://david-dm.org/jimzhan/dekoa.svg)\n[![npm version](https://img.shields.io/npm/v/dekoa.svg)](https://www.npmjs.com/package/dekoa)\n[![npm downloads](https://img.shields.io/npm/dt/dekoa.svg)](https://www.npmjs.com/package/dekoa)\n\n\nHandy decorators \u0026 middlewares dedicated for Koa, batteris included:\n* Class based routes supports (full HTTP method supports, [RFC7231](https://tools.ietf.org/html/rfc7231#section-4)).\n* [JSON Schema](http://json-schema.org/) based validators (via [koa-body](https://github.com/dlau/koa-body)).\n* Common middleware helpers.\n\n## Installation\n\n```bash\nnpm install dekoa\n```\n\n## Decorators\n\n* route.js#bind(server, files, options)\n\n  - assuming we have all the view controllers under `src/resources/`.\n\n  ```javascript\n  // src/server.js\n  import Koa from 'koa'\n  import glob from 'glob'\n  import debug from 'debug'\n  import * as dekoa from 'dekoa'\n\n  const log = debug('debug')\n  const server = new Koa()\n\n  // all of the view controllers defined in `src/resources` will be automatically registered.\n  const views = glob.sync(`${__dirname}/resources/*.js`)\n  dekoa.bind(server, views, { prefix: '/v1' })\n\n  const port = process.env.PORT || 9394;\n  server.listen(port, () =\u003e {\n    log(`Server started at port: ${port}`)\n  })\n  ```\n\n  - sample view controllers with decorators supports.\n\n  ```javascript\n  // src/resources/accounts.js\n  import Status from 'http-status-codes'\n  import { resource, get, post } from 'dekoa'\n\n  @resource('accounts')\n  export default class Account {\n    @get('/:id')\n    async findById(ctx) {\n      const params = ctx.params\n      ctx.status = Status.OK\n      ctx.body = { id: params.id, username: 'test@example.com' }\n    }\n\n    @post('/')\n    async create(ctx) {\n      ctx.status = Status.CREATED\n      ctx.body = { username: 'test@example.com' }\n    }\n  }\n  ```\n\n  ```javascript\n  import Status from 'http-status-codes'\n  import { resource, post } from 'dekoa'\n\n  // `resource` decorator without prefix will be injected as top level URL.\n  @resource\n  export default class Auth {\n    @post('/login')\n    async login(ctx) {\n      ctx.status = Status.RESET_CONTENT\n    }\n\n    @post('/logout')\n    async logout(ctx) {\n      ctx.status = Status.RESET_CONTENT\n    }\n  }\n  ```\n\n* JSON Schema, e.g. `NewAccount.json`.\n\n  ```javascript\n  {\n    \"properties\": {\n      \"username\": {\n        \"type\": \"string\",\n        \"format\": \"email\",\n        \"minLength\": 5,\n        \"maxLength\": 255\n      },\n      \"password\": {\n        \"type\": \"string\",\n        \"minLength\": 6,\n        \"maxLength\": 20\n      }\n    },\n    \"required\": [\"username\", \"password\"]\n  }\n  ```\n\n* validate incoming form data\n\n  ```javascript\n  const NewAccount = require('./NewAccount.json')\n\n  @resource('inputs')\n  export default class Input {\n    @post('/', NewAccount)\n    async create(ctx) {\n      ctx.status = Status.CREATED\n      ctx.body = { username: 'test@example.com' }\n    }\n  }\n  ```\n\n* validate incoming http query (`GET`|`HEAD`|`DELETE` ONLY)\n\n  ```javascript\n  const Account = require('./Account.json')\n\n  @resource('inputs')\n  export default class Input {\n    @get('/', Account)\n    async find(ctx) {\n      ctx.status = Status.OK\n      ctx.body = { username: 'test@example.com' }\n    }\n  }\n  ```\n\n## Middlewares\n\n* XSRF (aka. CSRF) - built on top of [CSRF](https://www.npmjs.com/package/csrf), set for SPA without `session` dependency via cookie and header. Available options:\n  - `xsrfCookieName` - cookie name for saving XSRF token (default `xsrftoken`).\n  - `xsrfHeaderName` - http header name for responsing XSRF token, value is same as cookie's one (default `X-XSRF-Token`).\n  - `invalidTokenMessage` - error message responded for client (default `Invalid XSRF Token`).\n  - `invalidTokenStatusCode` - error http status code responded for client (default `403`).\n  - `excludedMethods` - methods bypass for XSRF token checking (default `[ 'GET', 'HEAD', 'OPTIONS' ]`).\n  - `renewPostWrite` - whether XSRF token should be renew after each write (default: `false`).\n\n```javascript\nimport Koa from 'koa'\nimport { middleware } from 'dekoa'\n\nconst server = new Koa()\nserver.use(middleware.XSRF('\u003cmy-app-secret\u003e'))\nserver.listen(port, () =\u003e {\n  log(`Server started at port: ${port}`)\n})\n```\n\n\n## Regular Expression Helpers\n\n- `dekoa.regex.chinese` - chinese characters.\n- `dekoa.regex.email` - email address.\n- `dekoa.regex.password` - valid password (\u003e= 6 bits, includes at least 1 lower \u0026 1 upper letter, 1 number \u0026 1 special character).\n- `dekoa.regex.integer` - positive/negative integer.\n- `dekoa.regex.number` - positive/negative number.\n- `dekoa.regex.url` - http/ftp/file address.\n- `dekoa.regex.ipv4` - IP address version 4.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimzhan%2Fdekoa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjimzhan%2Fdekoa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimzhan%2Fdekoa/lists"}