Skip to content

Commit

Permalink
complete 2.0.0 version!!!
Browse files Browse the repository at this point in the history
  • Loading branch information
sevenryze committed Nov 23, 2018
1 parent 2fba8ad commit f489ae6
Show file tree
Hide file tree
Showing 14 changed files with 349 additions and 357 deletions.
159 changes: 87 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,27 @@
* [`Router()`](#router)
* [`mount(path, router)`](#mountpath-router)
* [`METHOD(task)`](#methodtask)
* [Helpers on `Request`](#helpers-on-request)
* [`request. de_originalUrl`: string](#request-de_originalurl-string)
* [`request. de_parsedUrl`: Url](#request-de_parsedurl-url)
* [`request. de_queryString`: object](#request-de_querystring-object)
* [`request. de_response`: Respond](#request-de_response-respond)
* [`request. de_method`: string](#request-de_method-string)
* [`request. de_headers`: object](#request-de_headers-object)
* [`request. de_taskList`: Task[]](#request-de_tasklist-task)
* [`request. de_getIp()`: () => string](#request-de_getip-string)
* [`request.share`: {}](#requestshare)
* [Helpers on `Response`](#helpers-on-response)
* [`response. de_request`: Request](#response-de_request-request)
* [`response. de_setHeader(object)`: (object) => Respond](#response-de_setheaderobject-object-respond)
* [`response. de_setStatus(code)`: (code: number) => Response](#response-de_setstatuscode-code-number-response)
* [`response. de_send(body)`: (body?) => Response](#response-de_sendbody-body-response)
* [`listen(port)`](#listenport)
* [`close()`](#close)
* [`getListeningAddress()`](#getlisteningaddress)
* [Helpers on `Request`](#helpers-on-request)
* [`request.innerRequest`: IncomingMessage](#requestinnerrequest-incomingmessage)
* [`request.innerResponse`: ServerResponse](#requestinnerresponse-serverresponse)
* [`request.originalUrl`: string](#requestoriginalurl-string)
* [`request.parsedUrl`: Url](#requestparsedurl-url)
* [`request.response`: Respond](#requestresponse-respond)
* [`request.method`: string](#requestmethod-string)
* [`request.headers`: object](#requestheaders-object)
* [`request.taskList`: Task[]](#requesttasklist-task)
* [`request.ip`: string](#requestip-string)
* [`request.share`: {}](#requestshare)
* [Helpers on `Response`](#helpers-on-response)
* [`response.request`: Request](#responserequest-request)
* [`response.innerRequest`: IncomingMessage](#responseinnerrequest-incomingmessage)
* [`response.innerResponse`: ServerResponse](#responseinnerresponse-serverresponse)
* [`response.setHeader(object)`: (object) => Respond](#responsesetheaderobject-object-respond)
* [`response.setStatus(code)`: (code: number) => Response](#responsesetstatuscode-code-number-response)
* [`response.send(body)`: (body?) => Response](#responsesendbody-body-response)
* [Build and Test](#build-and-test)
* [Build](#build)
* [Test](#test)
Expand Down Expand Up @@ -100,12 +103,12 @@ For a specific http request, system will give you an integrated **`TPT`**. And t

# How to use

Use `npm` to install `@sevenryze/server`, then import the only exported class.
Use `npm` to install `@sevenryze/server-router`, then import the only exported class.

```
import { Router } from "@sevenryze/server"
import { Router } from "@sevenryze/server-router"
// Or commonjs
const { Router } = require("@sevenryze/server");
const { Router } = require("@sevenryze/server-router");
let router = new Router();
```
Expand Down Expand Up @@ -158,7 +161,7 @@ Want to know why? see my blog, if there are... 🤡

```
// sync task
router.get( (request, response, next) => {
router.get((request, response, next) => {
// Do something.
response.send();
Expand All @@ -173,78 +176,116 @@ router.get(async (request, response, next) => {
})
```

## Helpers on `Request`
## `listen(port)`

### `request. de_originalUrl`: string
- port: The port listening to.

Original, unprocessed request url.
Listen the specific port.

### `request. de_parsedUrl`: Url
If there are under tests case or would like to get a temp port, you should use number `0` as the argument.

The parsed http url, see https://nodejs.org/dist/latest-v9.x/docs/api/url.html#url_url_strings_and_url_objects for more info.
If port is omitted or is 0, the operating system will assign an arbitrary unused port, which can be retrieved by using Router.getListeningAddress().port after the 'listening' event has been emitted.

```
router.listen(7777);
```

## `close()`

Close the server.

```
router.close();
```

## `getListeningAddress()`

Get the bounding server address info.

# Helpers on `Request`

## `request.innerRequest`: IncomingMessage

The underlying http request.

## `request.innerResponse`: ServerResponse

The underlying http response.

## `request.originalUrl`: string

Original, unprocessed request url.

### `request. de_queryString`: object
## `request.parsedUrl`: Url

The query string key-value pairs parsed into object format.
The parsed http url, see https://nodejs.org/dist/latest-v9.x/docs/api/url.html#url_url_strings_and_url_objects for more info.

### `request. de_response`: Respond
## `request.response`: Respond

Point to the accompanied Response object.

### `request. de_method`: string
## `request.method`: string

The request http method.

### `request. de_headers`: object
## `request.headers`: object

The http headers parsed into object format.

### `request. de_taskList`: Task[]
## `request.taskList`: Task[]

The tasks waiting for this request.

### `request. de_getIp()`: () => string
## `request.ip`: string

Get the client ip and be able to handle behind proxy case.

```js
request.de_getIp();
request.ip;
// => "127.0.0.1"
```

### `request.share`: {}
## `request.share`: {}

The app context variable for simply share state between tasks.
The app context variable for simply share states between tasks.

## Helpers on `Response`
# Helpers on `Response`

### `response. de_request`: Request
## `response.request`: Request

Points to the accompanied request object.

### `response. de_setHeader(object)`: (object) => Respond
## `response.innerRequest`: IncomingMessage

The underlying http request.

## `response.innerResponse`: ServerResponse

The underlying http response.

- object <string> - Object used to set the headers, such as { Accept: "text/plain", "X-API-Key": "dde" }.
## `response.setHeader(object)`: (object) => Respond

- `object: Headers` - Object used to set the headers, such as { Accept: "text/plain", "X-API-Key": "dde" }.

Set header `key` to its `value`. If the `Content-Type` field is going to be set, this method will automatically turn the value to extensional form, eg."html" to the standard mime forms "text/html", and add the charset if it can be matched in mime-db package.

Return the this object, aka. Respond to make chain-able calls available.

```js
response.de_setHeader({ Accept: "text/plain", "X-API-Key": "xmt" });
response.setHeader({ Accept: "text/plain", "X-API-Key": "xmt" });
// => Accept: "text/plain"
// => X-API-Key: "xmt"
response.de_setHeader({ "Content-Type": "json" });
response.setHeader({ "Content-Type": "json" });
// => Content-Type: "application/json; charset=utf-8"
response.de_setHeader({ "Content-Type": "html" });
response.setHeader({ "Content-Type": "html" });
// => Content-Type: "text/html; charset=utf-8"
response.de_setHeader({ "Content-Type": "bin" });
response.setHeader({ "Content-Type": "bin" });
// => Content-Type: "application/octet-stream"
```

### `response. de_setStatus(code)`: (code: number) => Response
## `response.setStatus(code)`: (code: number) => Response

- code <number> - Http status code number such as "404"
- `code: number` - Http status code number such as "404"

Set the status `code` of the response.

Expand All @@ -254,9 +295,9 @@ Return this object for chain-able calls.
response.setStatus(404);
```

### `response. de_send(body)`: (body?) => Response
## `response.send(body)`: (body?) => Response

- body <string | object | buffer> - Can be a string such as `"some string"`, an object such as `{some: "haha"}` and a buffer such as `new Buffer("some buffer")`.
- `body: string | object | buffer` - Can be a string such as `"some string"`, an object such as `{some: "haha"}` and a buffer such as `new Buffer("some buffer")`.

Send response to the remote client, and this method will terminate the underlying socket session.

Expand All @@ -266,32 +307,6 @@ response.send({ some: "json" });
response.send("<p>some html</p>");
```

## `listen(port)`

- port: The port listening to.

Listen the specific port.

If there are under tests case or would like to get a temp port, you should use number `0` as the argument.

If port is omitted or is 0, the operating system will assign an arbitrary unused port, which can be retrieved by using Router.getListeningAddress().port after the 'listening' event has been emitted.

```
router.listen(7777);
```

## `close()`

Close the server.

```
router.close();
```

## `getListeningAddress()`

Get the bounding server address info.

# Build and Test

## Build
Expand Down
67 changes: 27 additions & 40 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import { createServer, IncomingMessage, Server, ServerResponse } from "http";
import { AddressInfo } from "net";
import staticServe from "serve-static";
import { parse } from "url";
import { Debug } from "./helper/debugger";
import { RouterError } from "./helper/router-error";
import { IRequest, IResponse, ITask } from "./interface";
import { requestProto } from "./prototype/request";
import { responseProto } from "./prototype/response";
import { Request } from "./prototype/request";
import { Response } from "./prototype/response";
import { buildRunList } from "./runList";
import { schedule } from "./schedule";

const debug = Debug(__filename);

export type IRequest = IRequest;
export type IResponse = IResponse;
export type ITask = ITask;
export type Request = Request;
export type Response = Response;

export function serveStatic(root: string, options?: staticServe.ServeStaticOptions) {
return (staticServe(root, options) as unknown) as ITask;
export interface ITask {
(request: Request, response: Response, next: () => void): void;

mountHttpMethod?: string;

// strimPath = requestPath - absolutePath
strimPath?: string;
}

export function serveStatic(root: string, options?: staticServe.ServeStaticOptions): ITask {
const middleware = staticServe(root, options);

return (request, response, next) => {
request.innerRequest.url = request.trimmedUrl;

middleware(request.innerRequest as any, response.innerResponse as any, next);
};
}

export class Router {
Expand Down Expand Up @@ -158,42 +170,17 @@ export class Router {

// This is actual handler of the incoming message.
private incomingRequestHandler = (request: IncomingMessage, response: ServerResponse): void => {
const requestAppend: any = {};
const responseAppend: any = {};

debug(`Get method: ${request.method} on url: ${request.url}`);

// Protect the original URL from unintentional polluting.
requestAppend.de_originalUrl = request.url;

// Store the url-related info.
requestAppend.de_parsedUrl = parse(request.url!, true);
requestAppend.de_queryString = requestAppend.de_parsedUrl.query;

requestAppend.de_method = request.method;
requestAppend.de_headers = request.headers;

// This taskList is the main ordered task list the current request matched.
// Important!
requestAppend.de_taskList = [];

// Point to each other.
requestAppend.de_response = response;
responseAppend.de_request = request;

// Merge properties of our Request and Response prototypes
// to the incoming request and response objects.
Object.assign(request, requestAppend, requestProto);
Object.assign(response, responseAppend, responseProto);
const perfectRequest = new Request(request, response);
const perfectResponse = new Response(response, request);
perfectRequest.response = perfectResponse;
perfectResponse.request = perfectRequest;

// Build the runList.
buildRunList(this, (request as unknown) as IRequest, ((request as unknown) as IRequest).de_taskList);
buildRunList(this, perfectRequest, perfectRequest.taskList);

// Run the tasks.
schedule(
((request as unknown) as IRequest).de_taskList,
(request as unknown) as IRequest,
(response as unknown) as IResponse
);
schedule(perfectRequest.taskList, perfectRequest, perfectResponse);
};
}
Loading

0 comments on commit f489ae6

Please sign in to comment.