open-index/open-npm huggingface dataset:
npm package: @skax/drag-scroll
Description: drag scroll component for js framework, support mobile and pc
Author: ShineShao
Latest version: 2.0.0

## DragScroll

![build](https://github.com/freeshineit/drag-scroll/workflows/build/badge.svg) ![Download](https://img.shields.io/npm/dm/@skax/drag-scroll.svg) ![Version](https://img.shields.io/npm/v/@skax/drag-scroll.svg) ![License](https://img.shields.io/npm/l/@skax/drag-scroll.svg)

### scripts

```bash
# 安装依赖
pnpm install

# 开发运行
pnpm run dev

# 运行所有测试
pnpm test

# 监听模式（开发时使用）
pnpm test:watch

# 生成覆盖率报告
pnpm test:coverage

# 构建生产
pnpm run build

# 文档
pnpm run docs
```

### Usage

```bash
npm install @skax/drag-scroll
# or
yarn add @skax/drag-scroll
# or
pnpm add @skax/drag-scroll
```

```ts
import '@skax/drag-scroll/dist/style/css.css';
import DragScroll from '@skax/drag-scroll';

const scroll = new DragScroll(document.querySelector('.container'), {
  height: 100,
  content: `
    <div class="list">
        <div class="item" style="height: 100px">1</div>
        <div class="item" style="height: 100px">2</div>
        <div class="item" style="height: 100px">3</div>
        <div class="item" style="height: 100px">4</div>
        <div class="item" style="height: 100px">5</div>
        <div class="item" style="height: 100px">6</div>
        <div class="item" style="height: 100px">7</div>
        <div class="item" style="height: 100px">8</div>
    </div>
    `,
});
```

#### html umd

```html
<!-- node_modules/@skax/drag-scroll/dist/style/css.css -->
<link rel="stylesheet" href="./style/css.css" />
<!-- node_modules/@skax/drag-scroll/dist/index.umd.js-->
<script src="./index.umd.js"></script>

<div class="container"></div>

<script>
  const scroll = new DragScroll(document.querySelector('.container'), {
    height: 100,
    content: `
        <div class="list">
            <div class="item" style="height: 100px">1</div>
            <div class="item" style="height: 100px">2</div>
            <div class="item" style="height: 100px">3</div>
            <div class="item" style="height: 100px">4</div>
            <div class="item" style="height: 100px">5</div>
            <div class="item" style="height: 100px">6</div>
            <div class="item" style="height: 100px">7</div>
            <div class="item" style="height: 100px">8</div>
        </div>`,
  });
</script>
```

[demo](./public/index.html)

## Documentation

## API
npm package: @skax/logger
Description: console logger
Author: ShineShao
Latest version: 1.0.1

## @skax/logger

![build](https://github.com/freeshineit/skax-logger/workflows/build/badge.svg) ![Download](https://img.shields.io/npm/dm/@skax/logger.svg) ![Version](https://img.shields.io/npm/v/@skax/logger.svg) ![License](https://img.shields.io/npm/l/@skax/logger.svg)

### Usage

```sh
yarn add @skax/logger
```

```ts
import Logger from '@skax/logger';

const logger = new Logger();

logger.d('console.debug print'); // debug
logger.v('console.log print'); // log
logger.i('console.info print'); // info
logger.w('console.warn print'); // warn
logger.e('console.error print'); // error
```

### umd

```html
<script src="./index.umd.js"></script>
<script>
  (function () {
    const logger = new Logger();

    logger.v(logger.version());

    logger.d('1234132');
    logger.v('1234132');
    logger.i('1234132');
    logger.w('1234132');
    logger.e('1234132');

    logger.setOptions({ level: 'WARN' });

    logger.d('2-1234132');
    logger.v('2-1234132');
    logger.i('2-1234132');
    logger.w('2-1234132');
    logger.e('2-1234132');
  })();
</script>
```
npm package: @skax/web-components
Description: web components
Author: ShineShao
Latest version: 0.2.0

## Web Components

![build](https://github.com/freeshineit/web-components/workflows/build/badge.svg)
![Download](https://img.shields.io/npm/dm/@skax/web-components.svg)
![Version](https://img.shields.io/npm/v/@skax/web-components.svg)
![License](https://img.shields.io/npm/l/@skax/web-components.svg)

[Web Components](https://developer.mozilla.org/zh-CN/docs/Web/Web_Components) 是一套不同的技术，允许您创建可重用的定制元素（它们的功能封装在您的代码之外）并且在您的 web 应用中使用它们。

## Scripts

```bash
# development
yarn run dev

# production
yarn run build

# build document
# https://github.com/http-party/http-server
# version >= 14
yarn run build:doc
cd docs && http-server -p 8080 .
```

## Use

> yarn install @skax/web-components

### component

`wc-input`, `wc-button`, `wc-list`

### html

```html
<!-- script -->
<script src="./lib/bundle/@skax/web-components.umd.js"></script>

<form action="/get" name="form">
  <label for="name">
    <wc-input type="text" name="name" id="name" placeholder="input name"></wc-input>
  </label>
  <label for="password">
    <wc-input type="password" name="password" id="password" placeholder="input password"></wc-input>
  </label>
  <wc-button type="submit">Submit</wc-button>
  <wc-button type="rest">Rest</wc-button>
</form>
```

### react

```tsx
import '@skax/web-components'
// import '@skax/web-components/es/button'

function App() {
  return <wc-button>Button</wc-button>;
}
```

如果使用了 typescript，在 `react-app-env.d.ts`中添加下面声明。

```ts
/// <reference types="@skax/web-components" />

export declare global {
  namespace JSX {
    interface IntrinsicElements {
      "wc-button": WCButtonElement;
      "wc-input": WCInputElement;
      "wc-list": WCListElement;
    }
  }
}
```

[example](https://codesandbox.io/s/adoring-cdn-f7h4li)

### vue3

```vue
<script setup>
  import '@skax/web-components'
  // import '@skax/web-components/es/button'
</script>

<template>
  <wc-button>Button</wc-button>
</template>
```

[example](https://codesandbox.io/s/cool-cannon-5ou03c)
npm package: @skazka/env
Description: Node.js Environment
Author: skazkajs
Latest version: 0.1.0

# Node.js Environment

Helps to get app env.

```javascript
  import { isProduction, isDevelopment, isTest } from '@skazka/env';

  if (isProduction) {
    ...
  }
```
To see constants:

```javascript
  import { PRODUCTION, DEVELOPMENT, TEST } from '@skazka/env';
```
npm package: @skazka/server
Description: Server
Author: skazkajs
Latest version: 0.0.9

# Server

Simple promised node http request-response handler.

[![NPM](https://nodei.co/npm/@skazka/server.png)](https://npmjs.org/package/@skazka/server)

Each Node.js server is a handler for http(s) server **request** event:

Example:

```javascript
const http = require('http');

const server = http.createServer( (req, res) => {
  ctx.res.statusCode = 200;
  res.end('okay');
});
```
   
[Anatomy of an HTTP Transaction](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/)

There are many popular frameworks like express.js or koa created to handle user requests.

But all of them use ideas from other programming languages or they are too old.

Skazka Server created with deep understanding of JavaScript core (and node.js), its new ideas like promises and async/await.

Core of the server was created to resolve highload problems, work as a separate server or serverless.

And performance is the main reason to maintain this server because in real life you need to pay for each millisecond. 

## How to install

    npm i @skazka/server
    
With yarn:

    yarn add @skazka/server
    
## How to use
    
```javascript
const App = require('@skazka/server');

const app = new App();
    
app.then(async (ctx) => {
  ctx.res.statusCode = 200;
  ctx.res.setHeader('Content-Type', 'application/json');
  ctx.res.end('{"status":"OK"}');
});
    
app.catch(async (error, ctx) => {
  ctx.res.statusCode = 500;
  ctx.res.setHeader('Content-Type', 'application/json');
  ctx.res.end(JSON.stringify({ error }));
});

module.exports = app;
```

## Breaking chain

```javascript
app.then(async (ctx) => {
  ctx.res.statusCode = 200;
  ctx.res.setHeader('Content-Type', 'application/json');
  ctx.res.end('{"status":"OK"}');
      
  return Promise.reject();
}).then(async () => {
  // it won't work
}).catch(async () => {
  // it won't work
});
```

## Real example

Add http server, error handler, logger, router, request and response:
    
    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response
          
With yarn:
    
    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');
        
const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);
    
app.then(async (ctx) => {
  // code for each request
  console.log(ctx.request);
});
    
router.get('/data').then(async (ctx) => {
  return ctx.response('data'); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```
npm package: @skazka/server-body-parser
Description: Server Body Parser
Author: skazkajs
Latest version: 0.0.9

# Server Body Parser

Skazka Server request body parser.

[![NPM](https://nodei.co/npm/@skazka/server-body-parser.png)](https://npmjs.org/package/@skazka/server-body-parser)

## How to install

    npm i @skazka/server @skazka/server-body-parser
    
With yarn:

    yarn add @skazka/server @skazka/server-body-parser
    
Optionally you can add http server, logger, router, request  and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');

const bodyParser = require('@skazka/server-body-parser');

const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
  bodyParser.json(), // it works for all next modules
]);
    
app.then(async (ctx) => {
  // code for each request
  await bodyParser.json(ctx); // it works for all next modules
});
    
router.get('/data').then(async (ctx) => {
  await bodyParser.json(ctx); // it works only for this route
  
  return ctx.response(ctx.get('request').body); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

As this module is wrapper for [body-parser](https://github.com/expressjs/body-parser),
you can use the same options:

```javascript
app.then(bodyParser.json(options));
```

```javascript
app.then(bodyParser.text(options));
```

```javascript
app.then(bodyParser.raw(options));
```

```javascript
app.then(bodyParser.urlencoded(options));
```
npm package: @skazka/server-chaos
Description: Server Chaos
Author: skazkajs
Latest version: 0.0.9

# Server Chaos

Chaos Monkey implementation for Skazka Server.

[![NPM](https://nodei.co/npm/@skazka/server-chaos.png)](https://npmjs.org/package/@skazka/server-chaos)

## How to install

    npm i @skazka/server @skazka/server-chaos
    
With yarn:

    yarn add @skazka/server @skazka/server-chaos
    
Optionally you can add http server, error handler, logger, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

### Config

#### config/default.json

```json
{
  "chaos": {
    "enabled": true,
    "error": {
      "probability": 0.1 // 0..1
    },
    "timeout": {
      "probability": 0.1, // 0..1
      "time": 30 // seconds
    }
  }
}
```

### Server module

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');

const chaos = require('@skazka/server-chaos');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request ');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);
    
app.then(async (ctx) => {
  // it works for any request
  // no chaos for now
});

app.then(chaos()); // it runs chaos next modules

router.get('/data').then(async (ctx) => {
  // with chaos
  return ctx.response(result); 
});

app.then(router.resolve());
        
server.createHttpServer(app);
```
npm package: @skazka/server-context
Description: Server context
Author: skazkajs
Latest version: 0.0.2

# Server Context

Skazka Server Context.

[![NPM](https://nodei.co/npm/@skazka/server-context.png)](https://npmjs.org/package/@skazka/server-context)

See [Skazka Server](https://npmjs.org/package/@skazka/server).
npm package: @skazka/server-cookies
Description: Server cookies parser
Author: skazkajs
Latest version: 0.0.7

# Server cookies parser

Parse **Cookie** header and populate ctx.request.cookies with an object keyed by the cookie names. 

## How to install

    npm i @skazka/server @skazka/server-cookies @skazka/server-request

With yarn:

    yarn add @skazka/server @skazka/server-cookies @skazka/server-request

Optionally you can add http server, error handler, logger, router and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-response

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const cookies = require('@skazka/server-cookies');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  cookies(),
  response(),
]);

app.then(async (ctx) => {
  // it works for each request
  console.log(ctx.request.cookies);
});

router.get('/data').then(async (ctx) => {
  return ctx.response('data'); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

Or you can get cookies for one route:

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const cookies = require('@skazka/server-cookies');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);

router.get('/data').then(async (ctx) => {
  const cookiesObject = await cookies(ctx);
  
  return ctx.response(cookiesObject); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```
npm package: @skazka/server-core
Description: Server Core
Author: skazkajs
Latest version: 0.0.2

# Server Core

Skazka Server Core.

[![NPM](https://nodei.co/npm/@skazka/server-core.png)](https://npmjs.org/package/@skazka/server-core)

See [Skazka Server](https://npmjs.org/package/@skazka/server).
npm package: @skazka/server-error
Description: Server Error Handler
Author: skazkajs
Latest version: 0.0.9

# Server Error Handler

Simple 404/500 error handler.

[![NPM](https://nodei.co/npm/@skazka/server-error.png)](https://npmjs.org/package/@skazka/server-error)

## How to install

    npm i @skazka/server @skazka/server-error
    
With yarn:

    yarn add @skazka/server @skazka/server-error
    
Optionally you can add http server, logger, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);
    
app.then(async (ctx) => {
  // code for each request
});
    
router.get('/data').then(async (ctx) => {
  return ctx.response('data'); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

## Config

### JSON request

To set application/json Content-Type header for each response:

```javascript
app.all([
  // res.setHeader('Content-Type', 'application/json')
  error({ isJSON: true }),
]);
```
     
### Hide user error (404)

If you have own user error handler, you can disable it:

```javascript
app.all([
  error({ hasUserError: false }),
]);
````
     
### Hide server error (500)

If you have own error handler, you can disable it:

```javascript
app.all([
  error({ hasServerError: false }),
]);
```

## Custom error handlers

To add custom user error handler for 404 error you need to add last app.then and finish response:

```javascript
// 404 error handler
app.then(async (ctx) => {
  return ctx.response('Not Found', 404);
  
  // Or
  // return ctx.json({ message: 'Not Found' }, 404);
  
  // Or
  // ctx.res.statusCode = 404;
  // ctx.res.end('Not Found');
});
```

To add app error handler for 500 error you need to add app.catch:

```javascript
// 500 error handler
app.catch(async (err, ctx) => {
  return ctx.response('Internal Server Error', 500);
  
  // Or
  // return ctx.json({ message: 'Internal Server Error' }, 500);
   
  // Or
  // ctx.res.statusCode = 500;
  // ctx.res.end('Internal Server Error');
});
```
npm package: @skazka/server-express
Description: Server Express Wrapper
Author: skazkajs
Latest version: 0.0.7

# Server Express Wrapper

Skazka Server Express wrapper helps to use any Express.js middlawere.

[![NPM](https://nodei.co/npm/@skazka/server-express.png)](https://npmjs.org/package/@skazka/server-express)

## How to install

    npm i @skazka/server @skazka/server-express
    
With yarn:

    yarn add @skazka/server @skazka/server-express
    
Optionally you can add http server, logger, router and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-response

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');
        
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');

const express = require('@skazka/server-express');
const { json } = require('body-parser');

const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  response(),
  express(json()), // works for each next module
]);
    
app.then(async (ctx) => {
  // code for each request
  await express(ctx, json()); // works for each next module
});
    
router.get('/data').then(async (ctx) => {
  await express(ctx, json()); // works only for this route
  
  return ctx.response(ctx.req.body); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

### Examples

```javascript
app.all([
  ...
  express(middleware(options)),
  ...
]);
```

```javascript
app.then(express(middleware(options)));
```

```javascript
app.then(async (context) => {
  await express(context, middleware(options));
})
```

```javascript
app.then(async (context) => {
  await express(middleware(options))(context);
})
npm package: @skazka/server-graphql
Description: Server GraphQL
Author: skazkajs
Latest version: 0.0.10

# Server GraphQL

Express GraphQL for Skazka Server.

[![NPM](https://nodei.co/npm/@skazka/server-graphql.png)](https://npmjs.org/package/@skazka/server-graphql)

## How to install

    npm i @skazka/server @skazka/server-graphql graphql
    
With yarn:

    yarn add @skazka/server @skazka/server-graphql graphql
    
Optionally you can add http server, error handler, logger and router:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');

const graphql = require('@skazka/server-graphql');

const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');
        
const server = require('@skazka/server-http');

const { 
  GraphQLSchema, 
  GraphQLObjectType, 
  GraphQLString,
} = require('graphql');

const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
]);

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
      hello: {
        type: GraphQLString,
        resolve() {
          return 'world';
        },
      },
    },
  }),
});

// for each request
app.then(graphql({ schema }));
  
// for url
router.get('/graphql').then(graphql({ schema }));
app.then(router.resolve());
        
server.createHttpServer(app);
```

To configure Skazka Server GraphQL you can read docs from **[express-graphql](https://github.com/graphql/express-graphql)**.
npm package: @skazka/server-http
Description: HTTP(S) Server
Author: skazkajs
Latest version: 0.2.0

# HTTP(S) Server

It helps to run Skazka app as node.js server.

[![NPM](https://nodei.co/npm/@skazka/server-http.png)](https://npmjs.org/package/@skazka/server-http)

## How to install

    npm i @skazka/server @skazka/server-http
    
With yarn:

    yarn add @skazka/server @skazka/server-http
    
Optionally you can add error handler, logger, router, request and response:

    npm i @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);
    
app.then(async (ctx) => {
  // it works for each request
});
    
router.get('/data').then(async (ctx) => {
  // it works only for "/url"
  return ctx.response('data'); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

### Run with ssl/tls

```javascript
const { readFileSync } = require('fs');
const { resolve } = require('path');

const options = {
  key: readFileSync(resolve(__dirname, 'ssl', 'key.pem')),
  cert: readFileSync(resolve(__dirname, 'ssl', 'cert.pem'))
};
        
server.createHttpsServer(options, app);
```

### With pem

[Pem](https://www.npmjs.com/package/pem) package helps to generate pem files for you.
It could be useful for testing.

    npm i pem
 
With yarn:

    yarn add pem

```javascript
const days = 1;
const selfSigned = true;
    
pem.createCertificate({ days, selfSigned }, (err, { serviceKey: key, certificate: cert }) => {
  if (err) {
    throw err;
  }
  server.createHttpsServer({ key, cert }, app);
});
```

And async/await:

```javascript
const util = require('util');

const createCertificate = util.promisify(pem.createCertificate);

(async () => {
  const days = 1;
  const selfSigned = true;
  
  const { 
    serviceKey: key, 
    certificate: cert,
  } = await createCertificate({ days, selfSigned });
  
  server.createHttpsServer({ key, cert }, app);
})();
```

### Port

By default server uses port from **process.env.PORT**:

    PORT=3000 node index.js

But you can set port in the code:

```javascript
server.createHttpServer(app, 80);
server.createHttpsServer({ key, cert }, app, 443);
```
npm package: @skazka/server-index
Description: Server index
Author: skazkajs
Latest version: 0.0.9

# Server index

Skazka Server Index is serving "index.html" file without caching.

There are 3 Skazka Server modules for working with static files:
- **Skazka Server Index** should be the first module for checking url and returning index.html file without cache.
- **Skazka Server Static** should be the second module for serving any static files with a cache system.
- **Skazka Server SPA** module should be the last module in the app chain (after router, graphQL...).
It returns index.html file for any request - the main idea of any SPA server.

[![NPM](https://nodei.co/npm/@skazka/server-index.png)](https://npmjs.org/package/@skazka/server-index)

## How to install

    npm i @skazka/server @skazka/server-index
    
With yarn:

    yarn add @skazka/server @skazka/server-index
    
##### Skazka Server static and spa:

    npm i @skazka/server @skazka/server-static @skazka/server-spa
    
With yarn:

    yarn add @skazka/server @skazka/server-static @skazka/server-spa
    
Optionally you can add http server, error handler, logger, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

```javascript
const { resolve } = require('path');

const App = require('@skazka/server');
const Router = require('@skazka/server-router');

const index = require('@skazka/server-index');
const serve = require('@skazka/server-static');
const spa = require('@skazka/server-spa');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();

const root = resolve(__dirname, 'dist');

app.all([
  error(),
  logger(),
  request(),
  response(),
  index({ root }),
]).then(serve({ root, index: false }));
    
app.then(async (ctx) => {
  // it works for any request
});
    
router.get('/data').then(async (ctx) => {
  return ctx.response('data'); 
});
        
app.then(router.resolve());

app.then(spa({ root }));

server.createHttpServer(app);
```

### Options

- **root** - directory with index file, by default: __dirname.
- **index** - file name, by default: index.html (you can use for example index.htm...).
- **url** - it works only for this url, by default: "/".

Example with all options:

```javascript
app.all([
  ...
  index({
    root: resolve(__dirname, 'dist'),
    index: 'index.html',
    url: '/',
  }),
]);
```
npm package: @skazka/server-init
Description: Pack of useful packages: cookies, error, helmet, logger, request and response
Author: skazkajs
Latest version: 0.0.11

# Server Init

Pack of useful packages: 
- [cookies](https://npmjs.org/package/@skazka/server-cookies),
- [error](https://npmjs.org/package/@skazka/server-error),
- [helmet](https://npmjs.org/package/@skazka/server-helmet),
- [logger](https://npmjs.org/package/@skazka/server-logger),
- [request](https://npmjs.org/package/@skazka/server-request),
- [response](https://npmjs.org/package/@skazka/server-response).

[![NPM](https://nodei.co/npm/@skazka/server-init.png)](https://npmjs.org/package/@skazka/server-init)

## How to install

    npm i @skazka/server @skazka/server-init
    
With yarn:

    yarn add @skazka/server @skazka/server-init
    
Optionally you can add http server and router:

    npm i @skazka/server-http @skazka/server-router
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');

const init = require('@skazka/server-init');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.then(init());
    
app.then(async (ctx) => {
  // it works for each request
});
    
router.get('/data').then(async (ctx) => {
  return ctx.response('data'); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

## Configuration

To enable or disable any module:

```javascript
app.then(init({ moduleName: true }));
```
Or
```javascript
app.then(init({ moduleName: false }));
```
By default all modules are enabled.

Fo example, to disable cookies:

```javascript
app.then(init({ cookies: false }));
```

Modules error, logger and helmet have own options.
You can set this option by setting "object" instead of "true":

```javascript
app.then(init({ error: { hasUserError: false } }));
```

To see more info check each module documentation.
npm package: @skazka/server-logger
Description: Server Logger
Author: skazkajs
Latest version: 0.0.7

# Server Logger

It helps to work with logs.


[![NPM](https://nodei.co/npm/@skazka/server-logger.png)](https://npmjs.org/package/@skazka/server-logger)

## How to install

    npm i @skazka/server @skazka/server-logger
    
With yarn:

    yarn add @skazka/server @skazka/server-logger
    
Optionally you can add http server, error handler, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-request @skazka/server-response

## How to use

You can use any system for logging.
By default it's console.

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);
    
app.then(async (ctx) => {
  try {
    ctx.logger.info('some text');
    // some code with errors
    throw new Error('test');
  } catch(error) {
    ctx.logger.error(error);
  }
});
    
router.get('/data').then(async (ctx) => {
  try {
      ctx.logger.log('/url');
      // some code with errors
      throw new Error('test');
    } catch(error) {
      ctx.logger.error(error);
    }
            
  return ctx.response(); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

### log4js

**[log4js](https://www.npmjs.com/package/log4js)** - a framework to work with node.

    npm i log4js

With yarn

    yarn add log4js
    
```javascript
const log4js = require('log4js');
const log4jsLogger = log4js.getLogger();

app.all([
  ...
  logger(log4jsLogger),
  ...
]);
```

### winston

**[Winston](https://www.npmjs.com/package/winston)** - a logger for just about everything.

    npm i winston

With yarn

    yarn add winston
    
```javascript
const winston = require('winston');

const winstonLogger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    //
    // - Write to all logs with level `info` and below to `combined.log` 
    // - Write all logs error (and below) to `error.log`.
    //
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});
 
//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
// 
if (process.env.NODE_ENV !== 'production') {
  winstonLogger.add(new winston.transports.Console({
    format: winston.format.simple()
  }));
}


app.all([
  ...
  logger(winstonLogger),
  ...
]);
```
npm package: @skazka/server-module
Description: Server Module Builder
Author: skazkajs
Latest version: 0.0.4

# Server Module Builder

Skazka Server Module Builder helps to create a new modules.

[![NPM](https://nodei.co/npm/@skazka/server-module.png)](https://npmjs.org/package/@skazka/server-module)

## How to install

    npm i @skazka/server @skazka/server-module
    
With yarn:

    yarn add @skazka/server @skazka/server-module
    
Optionally you can add http server, logger, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');

const moduleBuilder = require('@skazka/server-module');

const app = new App();
const router = new Router();

const newModule = moduleBuilder((context) => {
  // use context
});

app.all([
  error(),
  logger(),
  request(),
  response(),
  newModule(),
]);
    
app.then(async (ctx) => {
  // code for each request
  await newModule(ctx); // works for each next module
});
    
router.get('/data').then(async (ctx) => {
  await newModule(ctx); // works only for this route
  
  return ctx.response(ctx.req.body); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

### Examples

Create module:

```javascript
module.exports = moduleBuilder((context) => {
  // use context
});
```

```javascript
module.exports = moduleBuilder((context, options) => {
  // use context and options
});
```

```javascript
module.exports = moduleBuilder((context, option1, option2) => {
  // use context and options
});
```

Using a new module:

```javascript
app.then(module());
app.then(module(options));
app.then(module(option1, option2));
```

```javascript
app.then(async (ctx) => {
  await module(ctx);
  await module(ctx, options);
  await module(ctx, option1, option2);
});
```  

```javascript
app.then(async (ctx) => {
  await module()(ctx);
  await module(options)(ctx);
  await module(option1, option2)(ctx);
});
```
npm package: @skazka/server-mongoose
Description: Server Mongoose
Author: skazkajs
Latest version: 0.0.8

# Server Mongoose

Skazka Server Promise based Mongoose client.

[![NPM](https://nodei.co/npm/@skazka/server-mongoose.png)](https://npmjs.org/package/@skazka/server-mongoose)

## How to install

    npm i @skazka/server @skazka/server-mongoose mongoose config
    
With yarn:

    yarn add @skazka/server @skazka/server-mongoose mongoose config
    
Optionally you can add http server, error handler, logger, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

### Config

#### config/default.json

```json
{
  "mongoose": {
    "uri": "mongodb://localhost/test",
    "parameters": {
      "useNewUrlParser": true
    }
  }
}
```

See https://mongoosejs.com/docs/connections.html.

### Server module

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');

const mongoose = require('@skazka/server-mongoose');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  mongoose(),
  response(),
]);
    
router.get('/data').then(async (ctx) => {
  const { Schema } = ctx.mongoose;
          
  const UserSchema = new Schema({
    name: {
      type: String,
      required: [true, 'Name is required.'],
    },
  });
          
  const User = mongoose.model('user', UserSchema);
            
  const testUser = new User({ name: 'Test' });
          
  await testUser.save();
          
  // const user = await User.findOne({ _id: testUser._id });
          
  await testUser.remove();
  
  const users = await User.find({ name: 'Test' });
            
  return ctx.response(users); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

### Any other module

```javascript
const mongoose = require('@skazka/server-mongoose/mongoose');

const { Schema } = mongoose;
    
const UserSchema = new Schema({
  name: {
    type: String,
    required: [true, 'Name is required.'],
  },
});
        
const User = mongoose.model('user', UserSchema);
    
module.exports = User;
```
npm package: @skazka/server-redis
Description: Server Redis
Author: skazkajs
Latest version: 0.0.10

# Server Redis

Skazka Server Redis client.

[![NPM](https://nodei.co/npm/@skazka/server-redis.png)](https://npmjs.org/package/@skazka/server-redis)

## How to install

    npm i @skazka/server @skazka/server-redis config ioredis
    
With yarn:

    yarn add @skazka/server @skazka/server-redis config ioredis
    
Optionally you can add http server, error handler, logger, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

### Config

#### config/default.json

```json
{
  "redis": {
    "host": "127.0.0.1",
    "port": 6379
  }
}
```
    
### Server module

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
    
const redis = require('@skazka/server-redis');
    
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
    
const server = require('@skazka/server-http');
    
const app = new App();
const router = new Router();
    
app.all([
  error(),
  logger(),
  request(),
  redis(),
  response(),
]);
    
app.then(async (ctx) => {
  await ctx.redis.set('data', 'test');
  const data = await ctx.redis.get('data');
});
    
router.get('/data').then(async (ctx) => {
  await ctx.redis.set('data', 'test');
  const data = await ctx.redis.get('data');
        
  return ctx.response(data); 
});
    
app.then(router.resolve());
    
server.createHttpServer(app);
```   

### Any other module

You can use redis client in any app module:
```javascript
const redis = require('@skazka/server-redis/redis');
    
async () => {
  await redis.set('test', 'test');
  const data = await redis.get('test');
}
```
npm package: @skazka/server-request
Description: Server request
Author: skazkajs
Latest version: 0.0.8

# Server Request

Skazka Server Request.

[![NPM](https://nodei.co/npm/@skazka/server-request.png)](https://npmjs.org/package/@skazka/server-request)

## How to install

    npm i @skazka/server @skazka/server-request
    
With yarn:

    yarn add @skazka/server @skazka/server-request
    
Optionally you can add http server, error handler, logger and  response:

    npm i @skazka/server-http @skazka/server-error @skazka/server-logger @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-error @skazka/server-logger @skazka/server-response

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);
    
router.get('/data').then(async (ctx) => {
  console.log(ctx.request);
  
  return ctx.response(ctx.request.url);
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```
npm package: @skazka/server-response
Description: Server response
Author: skazkajs
Latest version: 0.0.8

# Server response

Skazka Server response.

[![NPM](https://nodei.co/npm/@skazka/server-response.png)](https://npmjs.org/package/@skazka/server-response)

## How to install

    npm i @skazka/server @skazka/server-response
    
With yarn:

    yarn add @skazka/server @skazka/server-response
    
Optionally you can add http server, error handler, logger, router and request:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request

## How to use

```javascript
const App = require('@skazka/server');
const Router = require('@skazka/server-router');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();
        
app.all([
  error(),
  logger(),
  request(),
  response(),
]);
    
app.then(async (ctx) => {
  // it works for each request
  // it stops all other modules
  return ctx.response('data'); 
});
    
router.get('/data').then(async (ctx) => {
  // it works only for this route
  return ctx.response('data'); 
});
        
app.then(router.resolve());
        
server.createHttpServer(app);
```

### Without response

```javascript
app.then(async (ctx) => {
  ctx.res.statusCode = 200;
  ctx.res.end('data');
      
  return Promise.reject();
});

router.get('/data').then(async (ctx) => {
  ctx.res.statusCode = 200;
  ctx.res.end('data');
        
  return Promise.reject();
});
```

### Custom response

```javascript
const Response = require('@skazka/server-response/response');

app.then(async (ctx) => {
  const response = new Response(ctx);
    
  return response.send(data = '', code = 200, contentType = 'text/plain');
});
```

## Redirect

```javascript
app.then(async (ctx) => {
  return ctx.redirect(url = '/', code = 301);
});
```

### Custom redirect

```javascript
app.then(async (ctx) => {
  const response = new Response(ctx);

  return response.redirect(url = '/', code = 301);
});
```

## Set header

```javascript
app.then(async (ctx) => {
  ctx.setHeader('Content-Type', 'text/plain');
  
  return ctx.response('');
});
```

### Custom response

```javascript
app.then(async (ctx) => {
  const response = new Response(ctx);

  response.setHeader('Content-Type', 'text/plain');
  
  return response.send('');
});
```

## JSON

```javascript
app.then(async (ctx) => {
  return ctx.json(data, code = 200);
});
```

### Custom json response

```javascript
app.then(async (ctx) => {
  const response = new Response(ctx);

  return response.sendJSON(data, code = 200);
});
```
npm package: @skazka/server-spa
Description: Server SPA
Author: skazkajs
Latest version: 0.0.7

# Server SPA

Skazka Server single page application (SPA) is serving index.html file without cache.

There are 3 Skazka Server modules for working with static files:
- **Skazka Server Index** should be the first module for checking url and returning index.html file without caching.
- **Skazka Server Static** should be second module for serving any static files with a cache system.
- **Skazka Server SPA** module should be the last module in the app chain (after router, graphQL...).
It returns index.html file for any request - the main idea of any SPA server.

[![NPM](https://nodei.co/npm/@skazka/server-spa.png)](https://npmjs.org/package/@skazka/server-spa)

## How to install

    npm i @skazka/server @skazka/server-spa
    
With yarn:

    yarn add @skazka/server @skazka/server-spa
    
##### Skazka Server index and static:

    npm i @skazka/server @skazka/server-index @skazka/server-static
    
With yarn:

    yarn add @skazka/server @skazka/server-index @skazka/server-static
    
Optionally you can add http server, error handler, logger, router, request and response:

    npm i @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response
      
With yarn:

    yarn add @skazka/server-http @skazka/server-router @skazka/server-error @skazka/server-logger @skazka/server-request @skazka/server-response

## How to use

```javascript
const { resolve } = require('path');

const App = require('@skazka/server');
const Router = require('@skazka/server-router');

const index = require('@skazka/server-index');
const serve = require('@skazka/server-static');
const spa = require('@skazka/server-spa');
        
const error = require('@skazka/server-error');
const logger = require('@skazka/server-logger');

const request = require('@skazka/server-request');
const response = require('@skazka/server-response');
        
const server = require('@skazka/server-http');
        
const app = new App();
const router = new Router();

const root = resolve(__dirname, 'dist');

app.all([
  error(),
  logger(),
  request(),
  response(),
  index({ root }),
]).then(serve({ root, index: false }));
    
app.then(async (ctx) => {
  // it works for any request
});
    
router.get('/data').then(async (ctx) => {
  return ctx.response('data'); 
});
        
app.then(router.resolve());

app.then(spa({ root }));

server.createHttpServer(app);
```

### Options

- **root** - directory with index file, by default: __dirname.
- **index** - file name, by default: index.html (you can use for example index.htm...).

Example with all options:

```javascript
app.all([
  ...
  spa({
    root: resolve(__dirname, 'dist'),
    index: 'index.html',
  }),
]);
```