open-index/open-npm huggingface dataset:
npm package: @koenbrouwer/cra-template-crr
Description: My custom template for Create React App with Chakra UI and React Router.
Latest version: 1.0.1

# cra-template-crr

This is my custom template for [Create React App](https://github.com/facebook/create-react-app).
This template includes some boilerplate for React Router and Chakra UI.

To use this template, add `--template @koenbrouwer/cra-template-crr` when creating a new app.

```sh
npx create-react-app my-app --template @koenbrouwer/cra-template-crr
```
npm package: @koenbrouwer/find-path-by-value
Description: A little NodeJS package with a single function that returns the path inside a haystack object where a needle as value was found.
Author: Koen Brouwer
Latest version: 1.0.0

### 🙋‍♂️ Made by [@koenbrouwer](https://twitter.com/KoenBrouwer).
---

# Welcome to find-path-by-value 👋

[![Version](https://img.shields.io/npm/v/@koenbrouwer/find-path-by-value.svg)](https://www.npmjs.com/package/@koenbrouwer/find-path-by-value)

This package contains a single function that returns the path inside a haystack object where a needle as value was found.

This is a [Node.js](https://nodejs.org/en/) package available through the [npm registry](https://nodejs.org/en/). \
You can install `find-path-by-value` with the [`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally).

# Install

```sh
npm install --save @koenbrouwer/find-path-by-value
```

# Usage

It's really straight forward, you will need a JS(ON) object as the haystack and a string as the needle,
`findPathByValue` will find the path(s) in the haystack where the needle was found:

```typescript
const data = {
	rootBad: "bad",
	level0: {
		whatever: "good",
		bad: "bad",
		level1: {
			good: "good",
			bad: "bad",
			some: {
				good: "good",
				other: {
					good: "good",
					deep: {
						good: "good",
						nested: {
							key: {
								that: {
									isBad: "bad",
								},
							},
						},
					},
				},
			},
		},
	},
};

const paths = findPathsByValue(haystack, needle);
```

The result of `paths` is:

```typescript
[
	'rootBad',
	'level0.bad',
	'level0.level1.bad',
	'level0.level1.some.other.deep.nested.key.that.isBad'
]
```

# Author

👤 **Koen Brouwer**

* Website: [KoenBrouwer.com](http://www.koenbrouwer.com/)
* Twitter: [@KoenBrouwer](https://twitter.com/KoenBrouwer)
* Github: [@KoenBrouwer](https://github.com/KoenBrouwer)

# 🤝 Contributing

Feel free to open an issue on the [issues page](https://github.com/KoenBrouwer/find-path-by-value/issues) or a pull request in
the [repo on GitHub](https://github.com/KoenBrouwer/find-path-by-value/pulls)!

# Show your support

Give a ⭐️ if this project helped you!

# License

[MIT](https://en.wikipedia.org/wiki/MIT_License)

Contributions, issues and feature requests are welcome!
npm package: @koenkivits/sapper
Description: Fork of the next small thing in web development, powered by Svelte
Author: Rich Harris
Latest version: 0.28.10

# sapper

[The next small thing in web development, powered by Svelte.](https://sapper.svelte.dev)


## What is Sapper?

Sapper is a framework for building high-performance universal web apps. [Read the guide](https://sapper.svelte.dev/docs) or the [introductory blog post](https://svelte.dev/blog/sapper-towards-the-ideal-web-app-framework) to learn more.


## Get started

Clone the [starter project template](https://github.com/sveltejs/sapper-template) with [degit](https://github.com/rich-harris/degit)...
When cloning you have to choose between rollup or webpack:

```bash
npx degit "sveltejs/sapper-template#rollup" my-app
# or: npx degit "sveltejs/sapper-template#webpack" my-app
```

...then install dependencies and start the dev server...

```bash
cd my-app
npm install
npm run dev
```

...and navigate to [localhost:3000](http://localhost:3000). To build and run in production mode:

```bash
npm run build
npm start
```

## Development

Pull requests are encouraged and always welcome. [Pick an issue](https://github.com/sveltejs/sapper/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) and help us out!

To install and work on Sapper locally:

```bash
git clone https://github.com/sveltejs/sapper.git
cd sapper
npm install
npm run dev
```

### Linking to a Live Project

You can make changes locally to Sapper and test it against a local Sapper project. For a quick project that takes almost no setup, use the default [sapper-template](https://github.com/sveltejs/sapper-template) project. Instruction on setup are found in that project repository.

To link Sapper to your project, from the root of your local Sapper git checkout:

```bash
cd sapper
npm link
```

Then, to link from `sapper-template` (or any other given project):

```bash
cd sapper-template
npm link sapper
```

You should be good to test changes locally.

### Running Tests

```bash
npm run test
```

## License

[MIT](LICENSE)
npm package: @koerber/mqtt-simple-level-store
Description: A simple level-backed store for MQTT.js
Author: Pier Fumagalli
Latest version: 1.0.0

MQTT.js Level Simple Store
=======================

This project implements a [`Store`](https://www.npmjs.com/package/mqtt#store)
as required by [MQTT.js](https://www.npmjs.com/package/mqtt), backed by a
simple [level](https://www.npmjs.com/package/level) database.

This is basically equivalent to the already-existing
[mqtt-level-store](https://www.npmjs.com/package/mqtt-level-store) project,
but sans the `level-sublevel` dependancy, and without double-lookups for
messages.

Usage
-----

Very simply:

```javascript
const mqtt = require('mqtt')
const simple = require('@koerber/mqtt-simple-level-store')

const outgoingStore = simple('/path/to/our/db/outgoing')
const incomingStore = simple('/somewhere/else/incoming')

const client = mqtt.connect('mqtts://some_mqtt_host:1234/', {
  outgoingStore,
  incomingStore,
  // ... other options
})
```
npm package: @koerber/plc-reader
Description: Simple PLC reader with many protocols
Author: Pier Fumagalli
Latest version: 1.1.8

Read from PLCs and process data in a pipeline
=============================================

This little project contains a framework from reading data from various PLC
devices (for now S7 and Rockwell/Allan Bradley), process data in a pipeline
using various processors, and transmit it using MQTT.
npm package: @koerber/yaml
Description: Simple extension to JS-YAML
Author: Pier Fumagalli
Latest version: 1.0.5

Simple YAML parser wrapper with extensions
==========================================

This simply wraps the `js-yaml` package providing a `parse(...)` convenience
method to parse files *synchronously*, and adding a couple of useful tags.

Usage
-----

Very simply:

```javascript
const { parse } = require('@koerber/yaml')
let parsed = parse('my_file.yml')
```

An optional *second argument* to the `parse(...)` function allows to specify
the base schema for parsing (defaulting to `DEFAULT_SAFE_SCHEMA)`.

The module also exposes `dump(...)` as an alias to `js-yaml`'s `safeDump(...)`.


The `!include` tag
------------------

The `!include` tag will include another YAML file in the current one. For example:

```yaml
object:
  <<: !include other.yml
```

Given the contents of `other.yml` as:

```yaml
foo: bar
```

And noting the use of the `<<:` merging tag in this example, the resulting
parsed JSON will be:

```json
"object" {
  "foo": "bar"
}
```

The `!include` tag can be used also in included documents, and will resolve
file names relative to the _real path_ of the document where the tag is
specified (in other words, symlinks are followed).


The `!merge` tag
----------------

The `!merge` tag merges arrays of arrays into one single array. For example:

```yaml
array: !merge
  -
    - one
    - two
  -
    - three
    - four
  - five
  -
    - six
    - seven
```

Will be parsed as the following JSON:

```json
{
  "array": [
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven"
  ]
}
```

This is quite useful when used with references where a file like the following:

```yaml
base: &base
  - a
  - b
merged: !merge
  - *base
  - c
```

Will be parsed as the following JSON:

```json
{
  "base": [ "a", "b" ],
  "merged": [ "a", "b", "c" ]
}
```

Ultimately, this can also be used in conjunction with `!include` whereas:

```yaml
!merge
- !include other.yml
- baz
```

Given the following contents for `other.yml`:

```yaml
- foo
- bar
```

Will be parsed as the following JSON:

```json
[ "foo", "bar", "baz" ]
```

The `!join` tag
----------------

The `!join` tag joins array members into a string. For example:

```yaml
joined: !join
  - One
  - Two
  - Three
```

Will be parsed as the following JSON:

```json
{ "joined": "OneTwoThree" }
```

The same output can be expected for the following YAML syntax:

```yaml
joined: !join [ One, Two, Three ]
```

License
-------

This work is licensed under the [MIT License Agreement](LICENSE.md)
npm package: @koeroesi86/cache
Description: Cache library
Author: Krisztian Korosi
Latest version: 21.5.5-f6599b3

# @koeroesi86/cache [![Build Status](https://travis-ci.com/Koeroesi86/cache.svg?branch=main)](https://travis-ci.com/Koeroesi86/cache) [![npm version](https://badge.fury.io/js/%40koeroesi86%2Fcache.svg)](https://badge.fury.io/js/%40koeroesi86%2Fcache)

### Install

```shell
yarn add @koeroesi86/cache
```

or
```shell
npm install --save @koeroesi86/cache
```

Usage example

```javascript
const { InmemoryCache } = require('@koeroesi86/cache')

const initialState = {};
const expiredCallback = console.log;
const cache = new InmemoryCache(initialState, expiredCallback);

// key, value, expiry
cache.set("example", { data: "thing" }, 5000);

console.log("cached:", cache.get("example"));
```

```typescript
declare class InmemoryCache<T = any> {
  has: (key: string) => boolean;
  get: (key: string) => T;
  set: (key: string, data: T, interval?: number) => void;
  all: () => { [key: string]: T };
  flush: () => void;
}
```

See full example in [example/index.js](example/index.js)
npm package: @koeroesi86/node-lambda-invoke
Description: A local Lambda implementation
Author: Krisztian Korosi
Latest version: 1.0.21-d1fa702

# Node Lambda invoke [![Build status](https://api.travis-ci.org/Koeroesi86/node-lambda-invoke.svg?branch=master)](https://travis-ci.org/Koeroesi86/node-lambda-invoke)

A library that can be easily used for AWS lambda functions locally

## Dependencies

* [Node](https://nodejs.org/en/)
* [Yarn](https://yarnpkg.com/lang/en/) (optional)

## Usage

```bash
yarn add @koeroesi86/node-lambda-invoke
```

Or with npm
```bash
npm i --save @koeroesi86/node-lambda-invoke
```

## Example

```javascript
const http = require('http');
const { httpMiddleware } = require('@koeroesi86/node-lambda-invoke');

const host = 'localhost';
const port = 8080;

const lambdaPath = './pathOfLambda.js';
const handlerKey = 'handler';
const logger = console.log;
const limit = 100; // overall limit ox running lambdas

http
  .createServer(httpMiddleware({
    lambdaPath,
    handlerKey,
    logger,
    limit,
    communication: {
      // file|ipc|custom --- When 'custom' used, path is needed
      type: 'ipc',
    }
  }))
  .listen(
    { host, port, exclusive: true },
    () => console.log(`Server running on http://${host}:${port}`)
  );
```


## Running locally

```bash
yarn start
```

## Configuration

Coming soon, currently a basic `.env` way is available...
npm package: @koeroesi86/node-webserver
Description: A local Lambda implementation
Author: Krisztian Korosi
Latest version: 22.3.132-5e488e1

# NodeJS Web Server

This package brings ability to deploy webapps a lot easier. Just copy [configuration.example.js](configuration.example.js) to `configuration.js`, modify it to your needs and start server instantly. Configuration also supported in `configuration.json` format.

### Dependencies to run
* [NodeJS](https://nodejs.org/en/)
* [Yarn](https://yarnpkg.com/en/)
* For Windows usage
    1. [Python](https://www.python.org/)
    1. [Visual C++ Build Tools](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017)
    1. Windows build tools
     
        From an administrator console:

        ```npm install --global --production windows-build-tools```


### Usage

Please enter in a console/terminal:
    
    yarn install
    yarn start


### Build

TODO: Set up tests for build

[![Build Status](https://travis-ci.com/Koeroesi86/node-webserver.svg?branch=master)](https://travis-ci.com/Koeroesi86/node-webserver)
npm package: @koeroesi86/node-webserver-cli
Description: A local Lambda implementation
Author: Krisztian Korosi
Latest version: 22.3.5-e1c0d5d

# @koeroesi86/node-webserver-cli [![Build Status](https://travis-ci.com/Koeroesi86/node-webserver-cli.svg?branch=master)](https://travis-ci.com/Koeroesi86/node-webserver-cli)

### Dependencies to run
* [NodeJS](https://nodejs.org/en/)
* [Yarn](https://yarnpkg.com/en/)

### Usage:

```shell script
yarn nws-cli --config </path/to/config>
```
npm package: @koeroesi86/node-webserver-service
Description: OS service integration for @koeroesi86/node-webserver
Author: Krisztian Korosi
Latest version: 22.3.25-9a65a76

# node-webserver-service [![Build Status](https://travis-ci.com/Koeroesi86/node-webserver-service.svg?branch=master)](https://travis-ci.com/Koeroesi86/node-webserver-service)

OS service integration for @koeroesi86/node-webserver

This package brings ability to deploy webapps a lot easier. Just copy [configuration.example.js](configuration.example.js) to `configuration.js`, modify it to your needs and start server instantly. Configuration also supported in `configuration.json` format.

### Dependencies to run
* [NodeJS](https://nodejs.org/en/)
* [Yarn](https://yarnpkg.com/en/)
* For Windows usage
    1. [Python](https://www.python.org/)
    1. [Visual C++ Build Tools](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017)
    1. Windows build tools
     
        From an administrator console:

        ```shell script
        npm install --global --production windows-build-tools
       ```


### Usage

```shell script
yarn add @koeroesi86/node-webserver-service
```

Please enter in a console/terminal:

```shell script
yarn nws-service [argument]

arguments:
    --add      Installs the service
    --remove   Removes the service
    --run      Attempt to run the program as a service
```
npm package: @koeroesi86/node-worker
Description: NodeJS implementation of WebWorkers
Author: Krisztian Korosi
Latest version: 23.3.4408728827-main

# Node Worker

[![Publish](https://github.com/Koeroesi86/node-worker/actions/workflows/publish.yml/badge.svg)](https://github.com/Koeroesi86/node-worker/actions/workflows/publish.yml)

NodeJS implementation of WebWorkers

```typescript
interface Worker {
    terminate: void;
    postMessage: void;
    onmessage: Function;
    onerror: Function;
    addEventListener: void;
    removeEventListener: void;
    dispatchEvent: void;
}
```

## Usage

```javascript
const Worker = require('@koeroesi86/node-worker');

const instance = new Worker('ls');
instance.terminate();
```

Or checkout the pproject and run
```javascript
yarn example
```
npm package: @koeroesi86/node-worker-express
Description: Express JS library for [@koeroesi86/node-worker](https://www.npmjs.com/package/@koeroesi86/node-worker)
Author: Krisztian Korosi
Latest version: 23.3.4508640840-main

# Node Worker Express [![Publish](https://github.com/Koeroesi86/node-worker-express/actions/workflows/publish.yml/badge.svg)](https://github.com/Koeroesi86/node-worker-express/actions/workflows/publish.yml)

Express JS library for [@koeroesi86/node-worker](https://www.npmjs.com/package/@koeroesi86/node-worker)

Usage:
```javascript
const { middleware } = require('@koeroesi86/node-worker-express');
const express = require('express');
const path = require('path');

const app = express();
app.use(middleware({ root: path.resolve('./public') }));
app.listen(80);
```

### To run the example included:
```bash
yarn install
yarn start
```

For all options see [types](https://github.com/Koeroesi86/node-worker-express/blob/main/src/middleware/index.ts).
npm package: @koeroesi86/react-pdf-components
Description: React PDF components
Author: Krisztian Korosi
Latest version: 23.3.4330880333-main

# @koeroesi86/react-pdf-components
[![Publish](https://github.com/Koeroesi86/react-pdf-components/actions/workflows/publish.yml/badge.svg)](https://github.com/Koeroesi86/react-pdf-components/actions/workflows/publish.yml) [![npm version](https://badge.fury.io/js/%40koeroesi86%2Freact-pdf-components.svg)](https://badge.fury.io/js/%40koeroesi86%2Freact-pdf-components)

### Dependencies
* [NodeJS](https://nodejs.org/en/)
* [Yarn](https://yarnpkg.com/en/)

### Usage

```shell
yarn add @koeroesi86/react-pdf-components
```

### Running locally

```shell
yarn storybook
```
npm package: @koeroesi86/react-reviver
Description: React component reviver
Author: Krisztian Korosi
Latest version: 23.3.4329683321-main

# @koeroesi86/react-reviver
[![Publish](https://github.com/Koeroesi86/react-reviver/actions/workflows/publish.yml/badge.svg)](https://github.com/Koeroesi86/react-reviver/actions/workflows/publish.yml) [![npm version](https://badge.fury.io/js/%40koeroesi86%2Freact-reviver.svg)](https://badge.fury.io/js/%40koeroesi86%2Freact-reviver)

### Dependencies
* [NodeJS](https://nodejs.org/en/)
* [Yarn](https://yarnpkg.com/en/)

### Usage

```shell
yarn add @koeroesi86/react-reviver
```

```typescript jsx
/* eslint-disable react/prop-types */
import React from "react";
import ReactDOM from "react-dom";
import { ReviverProvider, ReviverLayout, ComponentRegistry, RevivableComponentType } from "@koeroesi86/react-reviver";

export const components: ComponentRegistry = {
  wrapper: ({ children, background }) => <div style={{ backgroundColor: background }}>{children}</div>,
  hello: ({ text }) => <h1>{text}</h1>,
}

type RevivableComponent =
  | RevivableComponentType<"wrapper", { background: string }, RevivableComponent>
  | RevivableComponentType<"hello", { text: string }, RevivableComponent>;

export const layout: RevivableComponent = {
  type: "wrapper",
  props: { background: "#efefef" },
  children: [
    { type: "hello", props: { text: "It works!" }, children: [] },
  ]
};

if (window && document.getElementById("root")) {
  ReactDOM.render(
    <ReviverProvider components={components}>
      Example:
      <ReviverLayout data={layout}/>
    </ReviverProvider>,
    document.getElementById("root"),
  );
}
```

### Running locally

```shell
yarn dev
```

Open [example/index.html](example/index.html) in the browser.
npm package: @koex/body
Description: body parser for koex
Author: Zero
Latest version: 1.0.2

# router

[![NPM version](https://img.shields.io/npm/v/@koex/router.svg?style=flat)](https://www.npmjs.com/package/@koex/router)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/router.svg?style=flat)](https://coveralls.io/r/koexjs/router)
[![Dependencies](https://img.shields.io/david/koexjs/router.svg)](https://github.com/koexjs/router)
[![Build Status](https://travis-ci.com/koexjs/router.svg?branch=master)](https://travis-ci.com/koexjs/router)
![license](https://img.shields.io/github/license/koexjs/router.svg)
[![issues](https://img.shields.io/github/issues/koexjs/router.svg)](https://github.com/koexjs/router/issues)
> Simple Router for Koa

### Install

```
$ npm install @koex/router
```

### Usage

```javascript
// See more in test
import * as router from '@koex/router';

import * as Koa from 'koa';
const app = new Koa();

app.use(router.get('/', async (ctx) => {
  ctx.body = 'home';
}));

app.use(router.get('/health', async (ctx) => {
  ctx.status = 200;
  ctx.body = 'ok';
}));

app.use(router.get('/product/:pid', async (ctx) => {
  ctx.body = ctx.params.pid;
}));

// support middlewares for router
const md5 = crypto.createHash('md5').update('123').digest('hex');

const responseTime = async (ctx, next) => {
  const start = Date.now();
  await next();
  ctx.set('X-Response-Time', Date.now() - start);
};

const requestId = async (ctx, next) => {
  await next();
  const id = md5(ctx.url + Date.now());
  ctx.set('X-Request-Id', id);
};

const handler = async (ctx) => {
  ctx.body = ctx.params.pid + ': ' + ctx.params.cid;
};

app.use(router.get('/product/:pid/:cid', responseTime, requestId, handler));

// fallback
app.use(async (ctx) => {
  ctx.body = {
    name: 'name',
    value: 'value',
  };
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-router](https://github.com/alexmingoia/koa-router)
* [koa-route](https://github.com/koajs/route)
* [koa-compose](https://github.com/koajs/compose)
npm package: @koex/cache
Description: cahe hits for koa
Author: Zero
Latest version: 0.0.8

# cache

[![NPM version](https://img.shields.io/npm/v/@koex/cache.svg?style=flat)](https://www.npmjs.com/package/@koex/cache)
[![NPM quality](https://npm.packagequality.com/shield/%40koex%2Fcache.svg)](https://packagequality.com/#?package=@koex/cache)
[![Coverage Status](https://img.shields.io/codecov/c/github/koexjs/cache/master.svg?style=flat-square)](https://codecov.io/gh/koexjs/cache)
[![Dependencies](https://img.shields.io/david/koexjs/cache.svg?style=flat-square)](https://david-dm.org/koexjs/cache)
[![Build Status](https://travis-ci.com/koexjs/cache.svg?branch=master)](https://travis-ci.com/koexjs/cache)
[![Known Vulnerabilities](https://snyk.io/test/npm/@koex/cache/badge.svg?style=flat-square)](https://snyk.io/test/npm/@koex/cache)
[![NPM download](https://img.shields.io/npm/dm/@koex/cache.svg?style=flat-square)](https://www.npmjs.com/package/@koex/cache)
![license](https://img.shields.io/github/license/koexjs/cache.svg)
[![issues](https://img.shields.io/github/issues/koexjs/cache.svg)](https://github.com/koexjs/cache/issues)

> cache for koa extend. And you can custom auto cache db, like redis.

### Install

```
$ npm install @koex/cache
```

### Usage

```javascript
// See more in test
import cache from '@koex/cache';

import * as Koa from 'koa';
const app = new Koa();
app.use(cache(options));
app.use(async (ctx) => {
  if (ctx.path === '/') {
    ctx.body = 'hello, world';
  } else if (ctx.path === '/json') {
    ctx.body = {
      name: 'name',
      value: 'value',
    };
  }
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start');
});
```

### Related
* [cash](https://github.com/koajs/cash)
* [koa-cache-lite](https://github.com/mkozjak/koa-cache-lite)
* [rsshub/lru-cache](https://github.com/DIYgod/RSSHub/blob/master/middleware/lru-cache.js)
npm package: @koex/cluster
Description: cluster for koa extend
Author: Zero
Latest version: 0.0.3

# cluster

[![NPM version](https://img.shields.io/npm/v/@koex/cluster.svg?style=flat)](https://www.npmjs.com/package/@koex/cluster)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/cluster.svg?style=flat)](https://coveralls.io/r/koexjs/cluster)
[![Dependencies](https://img.shields.io/david/koexjs/cluster.svg)](https://github.com/koexjs/cluster)
[![Build Status](https://travis-ci.com/koexjs/cluster.svg?branch=master)](https://travis-ci.com/koexjs/cluster)
![license](https://img.shields.io/github/license/koexjs/cluster.svg)
[![issues](https://img.shields.io/github/issues/koexjs/cluster.svg)](https://github.com/koexjs/cluster/issues)

> cluster for koa extend.

### Install

```
$ npm install @koex/cluster
```

### Usage
* 1 command line
* 2 import { startApp } from 'cluster';

```javascript
// app.js / app.ts
import * as Koa from 'koa';

const app = new Koa();

app.use(ctx => {
  ctx.body = 'hi, koa-cluster';
});

export default app;

// 1 command line
> koex-cluster app.js

// 2 code: server.js
import { startApp } from '@koex/cluster';
import app from './app';

startApp(app.callback(), {
  port: 8000,
  host: '0.0.0.0',
});
```

### Related
* [koa-cluster](https://github.com/koajs/cluster)
* [recluster](https://github.com/doxout/recluster)
* [pm2](https://github.com/Unitech/pm2)
npm package: @koex/compress
Description: compress for koa extend
Author: Zero
Latest version: 0.0.2

# compress

[![NPM version](https://img.shields.io/npm/v/@koex/compress.svg?style=flat)](https://www.npmjs.com/package/@koex/compress)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/compress.svg?style=flat)](https://coveralls.io/r/koexjs/compress)
[![Dependencies](https://img.shields.io/david/koexjs/compress.svg)](https://github.com/koexjs/compress)
[![Build Status](https://travis-ci.com/koexjs/compress.svg?branch=master)](https://travis-ci.com/koexjs/compress)
![license](https://img.shields.io/github/license/koexjs/compress.svg)
[![issues](https://img.shields.io/github/issues/koexjs/compress.svg)](https://github.com/koexjs/compress/issues)

> compress for koa extend.

### Install

```
$ npm install @koex/compress
```

### Usage

```javascript
// See more in test
import compress from '@koex/compress';

import * as Koa from 'koa';
const app = new Koa();

app.use(compress());

app.use(ctx => {
  ctx.body = 'hello, world!';
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-compress](https://github.com/koajs/compress)
npm package: @koex/cors
Description: cors for koa extend
Author: Zero
Latest version: 0.0.2

# cors

[![NPM version](https://img.shields.io/npm/v/@koex/cors.svg?style=flat)](https://www.npmjs.com/package/@koex/cors)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/cors.svg?style=flat)](https://coveralls.io/r/koexjs/cors)
[![Dependencies](https://img.shields.io/david/koexjs/cors.svg)](https://github.com/koexjs/cors)
[![Build Status](https://travis-ci.com/koexjs/cors.svg?branch=master)](https://travis-ci.com/koexjs/cors)
![license](https://img.shields.io/github/license/koexjs/cors.svg)
[![issues](https://img.shields.io/github/issues/koexjs/cors.svg)](https://github.com/koexjs/cors/issues)

> cors for koa extend.

### Install

```
$ npm install @koex/cors
```

### Usage

```javascript
// See more in test
import cors from '@koex/cors';

import * as Koa from 'koa';
const app = new Koa();

app.use(cors());

app.use(ctx => {
  ctx.body = 'Hello, World!';
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-cors](https://github.com/koajs/cors)
npm package: @koex/ejs
Description: ejs for koa
Author: Zero
Latest version: 0.0.1

# ejs

[![NPM version](https://img.shields.io/npm/v/@koex/ejs.svg?style=flat)](https://www.npmjs.com/package/@koex/ejs)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/ejs.svg?style=flat)](https://coveralls.io/r/koexjs/ejs)
[![Dependencies](https://img.shields.io/david/koexjs/ejs.svg)](https://github.com/koexjs/ejs)
[![Build Status](https://travis-ci.com/koexjs/ejs.svg?branch=master)](https://travis-ci.com/koexjs/ejs)
![license](https://img.shields.io/github/license/koexjs/ejs.svg)
[![issues](https://img.shields.io/github/issues/koexjs/ejs.svg)](https://github.com/koexjs/ejs/issues)

> ejs for koa extend.

### Install

```
$ npm install @koex/ejs
```

### Usage

```javascript
// See more in test
import * as path from 'path';
import ejs from '@koex/ejs';

import * as Koa from 'koa';
const app = new Koa();

app.use(ejs({
  dir: path.join(__dirname, './view'),
}));

app.use(ctx => {
  ctx.render('index');
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-ejs](https://github.com/koajs/ejs)
* [ejs](https://github.com/mde/ejs)
npm package: @koex/extend
Description: extend for koa extend
Author: Zero
Latest version: 0.0.1

# extend

[![NPM version](https://img.shields.io/npm/v/@koex/extend.svg?style=flat)](https://www.npmjs.com/package/@koex/extend)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/extend.svg?style=flat)](https://coveralls.io/r/koexjs/extend)
[![Dependencies](https://img.shields.io/david/koexjs/extend.svg)](https://github.com/koexjs/extend)
[![Build Status](https://travis-ci.com/koexjs/extend.svg?branch=master)](https://travis-ci.com/koexjs/extend)
![license](https://img.shields.io/github/license/koexjs/extend.svg)
[![issues](https://img.shields.io/github/issues/koexjs/extend.svg)](https://github.com/koexjs/extend/issues)

> extend for koa extend.

### Install

```
$ npm install @koex/extend
```

### Usage

```javascript
// See more in test
import extend, { extendBatch } from '@koex/extend';

import * as Koa from 'koa';

declare module 'koa' {
  export interface Context {
    render(html: string): Promise<any>;
    logger(html: string): void;
  }
}

const app = new Koa();

extend(app, 'context', 'render', async function (html: string) {
  const ctx: Koa.Context = this;
  ctx.body = html;
});

// or extend batch
extendBatch(app, 'context', {
  async render(html: string) {
    const ctx: Koa.Context = this;
    ctx.body = html;
  },
  logger(message: string) {
    console.log(message);
  },
});

app.use(router.post('/', ctx => {
  ctx.logger('post: ', ctx.path, ctx.query, ctx.request.body);
  await ctx.render(`
    <h1>Hello, World</h1>
  `);
}));

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [eggjs](https://github.com/eggjs)
* [thinkjs](https://github.com/thinkjs)
npm package: @koex/favicon
Description: favicon for koa extend
Author: Zero
Latest version: 0.0.1

# favicon

[![NPM version](https://img.shields.io/npm/v/@koex/favicon.svg?style=flat)](https://www.npmjs.com/package/@koex/favicon)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/favicon.svg?style=flat)](https://coveralls.io/r/koexjs/favicon)
[![Dependencies](https://img.shields.io/david/koexjs/favicon.svg)](https://github.com/koexjs/favicon)
[![Build Status](https://travis-ci.com/koexjs/favicon.svg?branch=master)](https://travis-ci.com/koexjs/favicon)
![license](https://img.shields.io/github/license/koexjs/favicon.svg)
[![issues](https://img.shields.io/github/issues/koexjs/favicon.svg)](https://github.com/koexjs/favicon/issues)

> favicon for koa extend.

### Install

```
$ npm install @koex/favicon
```

### Usage

```javascript
// See more in test
import { join } from 'path';
import favicon from '@koex/favicon';

import * as Koa from 'koa';
const app = new Koa();

app.use(favicon({
  path: join(__dirname, 'assets', 'favicon.ico'),
}));

app.use(ctx => {
  ctx.body = 'Hello, Koex!';
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-favicon](https://github.com/koajs/favicon)
npm package: @koex/helmet
Description: helmet for koa extend
Author: Zero
Latest version: 0.0.3

# helmet

[![NPM version](https://img.shields.io/npm/v/@koex/helmet.svg?style=flat)](https://www.npmjs.com/package/@koex/helmet)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/helmet.svg?style=flat)](https://coveralls.io/r/koexjs/helmet)
[![Dependencies](https://img.shields.io/david/koexjs/helmet.svg)](https://github.com/koexjs/helmet)
[![Build Status](https://travis-ci.com/koexjs/helmet.svg?branch=master)](https://travis-ci.com/koexjs/helmet)
![license](https://img.shields.io/github/license/koexjs/helmet.svg)
[![issues](https://img.shields.io/github/issues/koexjs/helmet.svg)](https://github.com/koexjs/helmet/issues)

> helmet for koa extend, wrapper with helmet.

### Install

```
$ npm install @koex/helmet
```

### Usage

```javascript
// See more in test
import helmet from '@koex/helmet';

import * as Koa from 'koa';
const app = new Koa();

app.use(helmet());

app.use(ctx => {
  ctx.body = 'Hello, World!';
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [helmet](https://github.com/helmetjs/helmet)
* [koa-helmet](https://github.com/venables/koa-helmet)
npm package: @koex/joi
Description: joi for koa extend
Author: Zero
Latest version: 0.0.5

# joi

[![NPM version](https://img.shields.io/npm/v/@koex/joi.svg?style=flat)](https://www.npmjs.com/package/@koex/joi)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/joi.svg?style=flat)](https://coveralls.io/r/koexjs/joi)
[![Dependencies](https://img.shields.io/david/koexjs/joi.svg)](https://github.com/koexjs/joi)
[![Build Status](https://travis-ci.com/koexjs/joi.svg?branch=master)](https://travis-ci.com/koexjs/joi)
![license](https://img.shields.io/github/license/koexjs/joi.svg)
[![issues](https://img.shields.io/github/issues/koexjs/joi.svg)](https://github.com/koexjs/joi/issues)

> joi for koa extend.

### Install

```
$ npm install @koex/joi
```

### Usage

```javascript
// See more in test
import * as bodyParser from 'koa-body';
import onerror from '@zcorky/onerror';
import joi from '@koex/joi';
import * as router from '@koex/router';

import * as Koa from 'koa';
const app = new Koa();

app.use(onerror());
app.use(bodyParse());
app.use(joi());

app.use(router.post('/', (ctx, next) => {
  const data = await ctx.validate({
    name: 'string',
    age: 'int',
  });

  ctx.body = data;
}));

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [joi](https://github.com/hapijs/joi)
npm package: @koex/oauth2
Description: Single Package Template
Author: Zero
Latest version: 1.2.3

# moment

[![NPM version](https://img.shields.io/npm/v/@zcorky/moment.svg?style=flat)](https://www.npmjs.com/package/@zcorky/moment)
[![NPM quality](http://npm.packagequality.com/shield/%40zcorky%2Fmoment.svg)](http://packagequality.com/#?package=@zcorky/moment)
[![Coverage Status](https://codecov.io/gh/zcorky/moment/branch/master/graph/badge.svg)](https://codecov.io/gh/zcorky/moment)
[![Dependencies](https://img.shields.io/david/zcorky/moment.svg?style=flat-square)](https://david-dm.org/zcorky/moment)
[![Build Status](https://travis-ci.com/zcorky/moment.svg?branch=master)](https://travis-ci.com/zcorky/moment)
[![Known Vulnerabilities](https://snyk.io/test/npm/@zcorky/moment/badge.svg?style=flat-square)](https://snyk.io/test/npm/@zcorky/moment)
[![NPM download](https://img.shields.io/npm/dm/@zcorky/moment.svg?style=flat-square)](https://www.npmjs.com/package/@zcorky/moment)
![license](https://img.shields.io/github/license/zcorky/moment.svg)
[![issues](https://img.shields.io/github/issues/zcorky/moment.svg)](https://github.com/zcorky/moment/issues)

> A minimalist JavaScript library that parses, validates, manipulates, and displays dates and times for modern browsers with a largely Moment.js-compatible API, written with TypeScript, inspired by Dayjs and Moment.js

```js
moment()
  .startOf('month')
  .add(1, 'day')
  .set('year', 2019)
  .format('YYYY-MM-DD HH:mm:ss');
```

- 🕒 Familiar Moment.js API & patterns
- 💪 Immutable
- 🔥 Chainable
- :sparkle: TypeScript
- 🌐 I18n support (WIP, will be soon)
- 🔌 Plugin System (WIP, will be soon)

## Install

```
$ npm install @zcorky/moment
```

## Usage

```js
// typescript
import moment from '@zcorky/moment';

moment('2018-08-08'); // parse

moment().format('{YYYY} MM-DDTHH:mm:ss SSS [Z] A'); // display

moment().set('month', 3).month(); // get & set

moment().add(1, 'year'); // manipulate
```

### Relatived

- [dayjs](https://github.com/iamkun/dayjs) - immutable date time library alternative to Moment.js with the same modern API.
- [moment](https://github.com/moment/moment/) - Parse, validate, manipulate, and display dates in javascript.
- [luxon](https://github.com/moment/luxon) - ⏱ A library for working with dates and times in JS.

## License

MIT © [Moeover](https://moeover.com)
npm package: @koex/onerror
Description: onerror for koa extend
Author: Zero
Latest version: 0.0.3

# onerror

[![NPM version](https://img.shields.io/npm/v/@koex/onerror.svg?style=flat)](https://www.npmjs.com/package/@koex/onerror)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/onerror.svg?style=flat)](https://coveralls.io/r/koexjs/onerror)
[![Dependencies](https://img.shields.io/david/koexjs/onerror.svg)](https://github.com/koexjs/onerror)
[![Build Status](https://travis-ci.com/koexjs/onerror.svg?branch=master)](https://travis-ci.com/koexjs/onerror)
![license](https://img.shields.io/github/license/koexjs/onerror.svg)
[![issues](https://img.shields.io/github/issues/koexjs/onerror.svg)](https://github.com/koexjs/onerror/issues)

> onerror for koa extend.

### Install

```
$ npm install @koex/onerror
```

### Usage

```javascript
// See more in test
import onerror from '@koex/onerror';

import * as Koa from 'koa';
const app = new Koa();

app.use(onerror());

// fallback
app.use(async (ctx) => {
  const error = new Error('Unauthorized');
  (error as any).status = 401;
  throw error;
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa](https://github.com/koajs/koa)
* [rsshub/onerror](https://github.com/DIYgod/RSSHub/blob/master/middleware/onerror.js)
npm package: @koex/puppeteer
Description: puppeteer as a service
Author: Zero
Latest version: 1.0.3

# Puppeteer as a Service

## Getting Started

```bash
# Step 1: start browserless chrome
docker run -d -p 3000:3000 --name browserless whatwewant/browserless-chrome:v1-0

# Step 2: start puppeteer service
docker run -d -p 8080:8080 --name puppeteer-as-a-service \
  -e BROWSER_WS_ENDPOINT=ws://browserless:3000 \
  whatwewant/puppeteer:latest
```

## Usage

### 1. Generate PDF
* Params
  * url: The URL to site url
    * required: true
  * format: The format of the outputted PDF
    * required: false
    * default: A4
  
```bash
curl -X POST \
  http://localhost:8887/pdf \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://www.baidu.com"
  }'
```

### 2. Generate Screenshot (Image)
* Params
  * url: The URL to site url
    * required: true
  * fullPage: When true, takes a screenshot of the full scrollable page
    * required: false
    * default: true
  * encoding: The encoding of the image, can be either base64 or undefined
    * required: false
    * default: none
    * available: base64 | undefined
  * width: The width of the image
    * required: false
  * height: The height of the image
    * required: false

```bash
curl -X POST \
  http://localhost:8080/image \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://www.baidu.com"
  }'
```

## License
* MIT
npm package: @koex/ratelimit
Description: ratelimit for koa extend
Author: Zero
Latest version: 1.0.4

# ratelimit

[![NPM version](https://img.shields.io/npm/v/@koex/ratelimit.svg?style=flat)](https://www.npmjs.com/package/@koex/ratelimit)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/ratelimit.svg?style=flat)](https://coveralls.io/r/koexjs/ratelimit)
[![Dependencies](https://img.shields.io/david/koexjs/ratelimit.svg)](https://github.com/koexjs/ratelimit)
[![Build Status](https://travis-ci.com/koexjs/ratelimit.svg?branch=master)](https://travis-ci.com/koexjs/ratelimit)
![license](https://img.shields.io/github/license/koexjs/ratelimit.svg)
[![issues](https://img.shields.io/github/issues/koexjs/ratelimit.svg)](https://github.com/koexjs/ratelimit/issues)

> ratelimit for koa extend

### Install

```
$ npm install @koex/ratelimit
```

### Usage

```javascript
// See more in test
import ratelimit from '@koex/ratelimit';

import * as Koa from 'koa';
const app = new Koa();
app.use(ratelimit());
app.use(async (ctx) => {
  if (ctx.path === '/') {
    ctx.body = 'hello, world';
  } else if (ctx.path === '/json') {
    ctx.body = {
      name: 'name',
      value: 'value',
    };
  }
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start');
});
```

### Related
* [ratelimit](https://github.com/koajs/ratelimit)
npm package: @koex/redis
Description: redis for koa extend
Author: Zero
Latest version: 0.0.2

# redis

[![NPM version](https://img.shields.io/npm/v/@koex/redis.svg?style=flat)](https://www.npmjs.com/package/@koex/redis)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/redis.svg?style=flat)](https://coveralls.io/r/koexjs/redis)
[![Dependencies](https://img.shields.io/david/koexjs/redis.svg)](https://github.com/koexjs/redis)
[![Build Status](https://travis-ci.com/koexjs/redis.svg?branch=master)](https://travis-ci.com/koexjs/redis)
![license](https://img.shields.io/github/license/koexjs/redis.svg)
[![issues](https://img.shields.io/github/issues/koexjs/redis.svg)](https://github.com/koexjs/redis/issues)

> redis for koa extend, based on ioredis.

### Install

```
$ npm install @koex/redis
```

### Usage

```javascript
// See more in test
import redis from '@koex/redis';

import * as Koa from 'koa';
const app = new Koa();

app.use(redis());
app.use(redis({
  port: 6379,          // Redis port
  host: '127.0.0.1',   // Redis host
  family: 4,           // 4 (IPv4) or 6 (IPv6)
  password: 'auth',
  db: 0
}));

app.use(ctx => {
  ctx.body = 'Hello, World!';
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [ioredis](https://github.com/luin/ioredis)
* [egg-redis](https://github.com/eggjs/egg-redis)
npm package: @koex/response-time
Description: response time for koa
Author: Zero
Latest version: 0.0.2

# response-time

[![NPM version](https://img.shields.io/npm/v/@koex/response-time.svg?style=flat)](https://www.npmjs.com/package/@koex/response-time)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/response-time.svg?style=flat)](https://coveralls.io/r/koexjs/response-time)
[![Dependencies](https://img.shields.io/david/koexjs/response-time.svg)](https://github.com/koexjs/response-time)
[![Build Status](https://travis-ci.com/koexjs/response-time.svg?branch=master)](https://travis-ci.com/koexjs/response-time)
![license](https://img.shields.io/github/license/koexjs/response-time.svg)
[![issues](https://img.shields.io/github/issues/koexjs/response-time.svg)](https://github.com/koexjs/response-time/issues)

> response time for koa extend.

### Install

```
$ npm install @koex/response-time
```

### Usage

```javascript
// See more in test
import * as path from 'path';
import responeTime from '@koex/response-time';

import * as Koa from 'koa';
const app = new Koa();

app.use(responeTime());

app.use(ctx => {
  ctx.body = 'hello, world!';
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-response-time](https://github.com/koajs/response-time)
npm package: @koex/router
Description: router for koa extend
Author: Zero
Latest version: 1.0.2

# router

[![NPM version](https://img.shields.io/npm/v/@koex/router.svg?style=flat)](https://www.npmjs.com/package/@koex/router)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/router.svg?style=flat)](https://coveralls.io/r/koexjs/router)
[![Dependencies](https://img.shields.io/david/koexjs/router.svg)](https://github.com/koexjs/router)
[![Build Status](https://travis-ci.com/koexjs/router.svg?branch=master)](https://travis-ci.com/koexjs/router)
![license](https://img.shields.io/github/license/koexjs/router.svg)
[![issues](https://img.shields.io/github/issues/koexjs/router.svg)](https://github.com/koexjs/router/issues)
> Simple Router for Koa

### Install

```
$ npm install @koex/router
```

### Usage

```javascript
// See more in test
import * as router from '@koex/router';

import * as Koa from 'koa';
const app = new Koa();

app.use(router.get('/', async (ctx) => {
  ctx.body = 'home';
}));

app.use(router.get('/health', async (ctx) => {
  ctx.status = 200;
  ctx.body = 'ok';
}));

app.use(router.get('/product/:pid', async (ctx) => {
  ctx.body = ctx.params.pid;
}));

// support middlewares for router
const md5 = crypto.createHash('md5').update('123').digest('hex');

const responseTime = async (ctx, next) => {
  const start = Date.now();
  await next();
  ctx.set('X-Response-Time', Date.now() - start);
};

const requestId = async (ctx, next) => {
  await next();
  const id = md5(ctx.url + Date.now());
  ctx.set('X-Request-Id', id);
};

const handler = async (ctx) => {
  ctx.body = ctx.params.pid + ': ' + ctx.params.cid;
};

app.use(router.get('/product/:pid/:cid', responseTime, requestId, handler));

// fallback
app.use(async (ctx) => {
  ctx.body = {
    name: 'name',
    value: 'value',
  };
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-router](https://github.com/alexmingoia/koa-router)
* [koa-route](https://github.com/koajs/route)
* [koa-compose](https://github.com/koajs/compose)
npm package: @koex/serve
Description: a simple commandline static server
Author: zero
Latest version: 0.12.2

# `@koex/serve`

> A simple commandline static server

## Usage

```bash
Usage: koex-serve [options]

a simple commandline static server

Options:
  -V, --version          output the version number
  -h, --host <PORT>      Listen port
  -p, --port <HOST>      Listen port
  -d, --dir <DIRECTORY>  Listen directory
  -c, --cors             Enable CORS
  -s, --single           Rewrite alk not-found requests to `index.html`
  -C, --cache            Cache files
  --help                 display help for command
```
npm package: @koex/socket.io
Description: socket.io for koa extend
Author: Zero
Latest version: 0.0.1

# socket.io

[![NPM version](https://img.shields.io/npm/v/@koex/socket.io.svg?style=flat)](https://www.npmjs.com/package/@koex/socket.io)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/socket.io.svg?style=flat)](https://coveralls.io/r/koexjs/socket.io)
[![Dependencies](https://img.shields.io/david/koexjs/socket.io.svg)](https://github.com/koexjs/socket.io)
[![Build Status](https://travis-ci.com/koexjs/socket.io.svg?branch=master)](https://travis-ci.com/koexjs/socket.io)
![license](https://img.shields.io/github/license/koexjs/socket.io.svg)
[![issues](https://img.shields.io/github/issues/koexjs/socket.io.svg)](https://github.com/koexjs/socket.io/issues)


> socket.io for koa extend.

### Install

```
$ npm install @koex/socket.io
```

### Usage

```javascript
import withSocketIO from '@koex/socket.io';

import * as Koa from 'koa';
const app = new Koa();
withSocketIO(app);

app.use(cors());

app.use(ctx => {
  ctx.body = 'Hello, World!';
});

// app.io is the socket.io instance
app.io.on('connection', socket => {
  // do something
});

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa.io](https://github.com/koajs/koa.io)
* [egg-socket.io](https://github.com/eggjs/egg-socket.io)
npm package: @koex/static
Description: static cache for koa extend
Author: Zero
Latest version: 1.0.2

# static

[![NPM version](https://img.shields.io/npm/v/@koex/static.svg?style=flat)](https://www.npmjs.com/package/@koex/static)
[![Coverage Status](https://img.shields.io/coveralls/koexjs/static.svg?style=flat)](https://coveralls.io/r/koexjs/static)
[![Dependencies](https://img.shields.io/david/koexjs/static.svg)](https://github.com/koexjs/static)
[![Build Status](https://travis-ci.com/koexjs/static.svg?branch=master)](https://travis-ci.com/koexjs/static)
![license](https://img.shields.io/github/license/koexjs/static.svg)
[![issues](https://img.shields.io/github/issues/koexjs/static.svg)](https://github.com/koexjs/static/issues)

> static for koa extend. used as public assets or static assets.

### Install

```
$ npm install @koex/static
```

### Usage

```javascript
// See more in test
import staticCache from '@koex/static';

import * as Koa from 'koa';
const app = new Koa();

app.use(staticCache('/static', {
  dir: path.join(__dirname, './public'),
}));

app.listen(8000, '0.0.0.0', () => {
  console.log('koa server start at port: 8000');
});
```

### Related
* [koa-static-cache](https://github.com/koajs/static-cache)
* [express.static/serve-static](https://github.com/expressjs/serve-static)