Skip to content

Commit

Permalink
Merge pull request #297 from htdangkhoa/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
htdangkhoa committed May 2, 2024
2 parents 77f879e + 448069a commit e2096e9
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 41 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
node: ['10', '12', '14', '16', '18']
node: ['16', '18', '20']

name: Node ${{ matrix.node }} testing

Expand All @@ -39,6 +39,14 @@ jobs:
- name: Test
run: yarn test:cov

- name: Test report with Node ${{ matrix.node }}
uses: dorny/test-reporter@v1
if: always()
with:
name: Test report with Node ${{ matrix.node }}
path: junit.xml
reporter: jest-junit

- name: Coveralls
uses: coverallsapp/github-action@v1.1.2
with:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,6 @@ dist
# TernJS port file
.tern-port

jest.config.js
jest.config.js

junit.xml
80 changes: 65 additions & 15 deletions API.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
# API References

## Application & Router
## Application

- Application Options:
### Options:

- `server`: Allows to optionally override the HTTP server instance to be used.
- `server`: Allows to optionally override the HTTP server instance to be used.

> Default: `undefined`.
> Default: `undefined`.
- `views`: An object to configuration [render](#resrenderview--options--callback) function.
- `views`: An object to configuration [render](#resrenderview--options--callback) function.

> Default: `undefined`.
> Default: `undefined`.
- `dir`: A directory for the application's views.
- `dir`: A directory for the application's views.

- `ext`: The default engine extension to use when omitted.
- `ext`: The default engine extension to use when omitted.

- `engine`: Registers the given template engine.
- `engine`: Registers the given template engine.

- Router Options:
### Properties:

- `prefix`: Allow append the path before each route.
- `cache`: An instance of the [Cache](#Cache) class.

> Default: `undefined`.
- `settings`: An object that contains the application settings.

- `views`: An object that contains the application's views configuration.

### Methods:

The `pure-http` is an instance of the `http.Server` class, so you can use all methods from the [Node.js HTTP module](https://nodejs.org/api/http.html). Additionally `pure-http` provides methods of the [Router](#Router) class and some other methods.

#### app.set(name, value)

> Assigns setting name to value. You may store any value that you want, but certain names can be used to configure the behavior of the server.
#### app.get(name)

> Returns the value of name setting.
## Router

### Options:

- `prefix`: Allow append the path before each route.

> Default: `undefined`.
### Methods:

#### get(route, handler [, handler...])

Expand Down Expand Up @@ -72,6 +96,12 @@

The req object is an enhanced version of Node’s own request object and supports all [built-in fields and methods](https://nodejs.org/api/http.html#http_class_http_incomingmessage).

### Properties

#### req.app

> Contains a reference to the instance of the `pure-http` that the request is being processed by. This allows you to access the methods and properties of the `pure-http` instance. See [Application](#Application).
#### req.body

> Contains key-value pairs of data submitted in the request body. By default, it is `undefined`, and is populated when you use body-parsing middleware.
Expand Down Expand Up @@ -112,13 +142,17 @@ The req object is an enhanced version of Node’s own request object and support

> This property is an object containing a property for each query string parameter in the route. When query parser is set to disabled, it is an empty object `{}`, otherwise it is the result of the configured query parser.
### Methods

#### req.header(name)

> Returns the specified HTTP request header field (case-insensitive match).
## Response

The res object is an enhanced version of Node’s own response object and supports all [built-in fields and methods](https://nodejs.org/api/http.html#http_class_http_serverresponse).

#### res.cache

> Get [Cache](#Cache) from application options.
### Methods

#### res.header(name, value)

Expand Down Expand Up @@ -174,6 +208,22 @@ The res object is an enhanced version of Node’s own response object and suppor
## Cache

### Options:

- `max`: The maximum number of items that can be stored in the cache.

> Default: `Infinity`.
- `maxAge`: The maximum age of an item in the cache.

> Default: `0`.
- `stale`: Allow stale items to be returned until they are removed from the cache.

> Default: `false`.
### Methods:

#### clear()

> Reset the cache(s) and counter.
Expand Down
20 changes: 14 additions & 6 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import net from 'net';
import tls from 'tls';
import http from 'http';
import http2 from 'http2';
import * as net from 'net';
import * as tls from 'tls';
import * as http from 'http';
import * as http2 from 'http2';

declare module 'pure-http' {
export interface ICookieSerializeOptions {
Expand Down Expand Up @@ -53,6 +53,8 @@ declare module 'pure-http' {
body?: any;

header(name: string): undefined | string | string[];

app: IPureHttpServer | IPureHttpSecureServer;
}

export interface IRequestHttp extends http.IncomingMessage, IRequest {}
Expand Down Expand Up @@ -269,9 +271,15 @@ declare module 'pure-http' {
stale?: boolean;
}

export interface IPureHttpServer extends net.Server, IRouter {}
export interface IApplication extends IRouter {
set(key: string, value: any): void;
get<T = any>(key: string): T;
get(path: string | RegExp, ...handler: Array<Handler>): this;
}

export interface IPureHttpServer extends net.Server, IApplication {}

export interface IPureHttpSecureServer extends tls.Server, IRouter {}
export interface IPureHttpSecureServer extends tls.Server, IApplication {}

export interface IOptions {
server?: net.Server | tls.Server;
Expand Down
2 changes: 1 addition & 1 deletion lib/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Cache {

const { max = Infinity, maxAge, stale } = opts;

this.max = max;
this.max = typeof max === 'number' ? max : Infinity;

this.maxAge = typeof maxAge === 'number' ? maxAge : 0;

Expand Down
3 changes: 2 additions & 1 deletion lib/extend/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const { defineGetter } = require('../utils');

const req = Object.create(IncomingMessage.prototype);

const URL_PATTERN = /^(https?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)/;
const URL_PATTERN =
/^(https?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)/;

const getFullUrl = function () {
return `${this.protocol}://${this.headers.host}${this.url}`;
Expand Down
5 changes: 3 additions & 2 deletions lib/extend/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ res.send = function (data) {
return this.end('');
}

const cache = this.cache;
const { cache } = this.request.app;

let body = data;

Expand Down Expand Up @@ -342,9 +342,10 @@ res.sendFile = function (filePath, options) {

res.render = function (filename, options, callback) {
const self = this;
const { views } = self.request.app;

const viewsOption = {};
Object.assign(viewsOption, self.views);
Object.assign(viewsOption, views);

const { dir, ext, engine } = viewsOption;

Expand Down
30 changes: 23 additions & 7 deletions lib/pure-http.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
const http = require('http');
const https = require('https');

const settings = require('./settings');
const Router = require('./router');
const { defineProperty } = require('./utils');
const { defineGetter } = require('./utils');

function pureHttp(options) {
const router = new Router();

const { server: existedServer, views: viewOptions, cache } = options || {};

let server = http.createServer();
Expand All @@ -18,7 +17,24 @@ function pureHttp(options) {
server = existedServer;
}

server.get = router.get;
defineGetter(server, 'cache', function () {
return cache;
});
defineGetter(server, 'views', function () {
return viewOptions;
});

const router = new Router();

server.set = settings.set.bind(server);
server.get = function get() {
if (arguments.length === 1) {
const key = arguments[0];
return settings.get.call(server, key);
}

return router.get.apply(router, arguments);
};
server.post = router.post;
server.put = router.put;
server.patch = router.patch;
Expand All @@ -28,12 +44,12 @@ function pureHttp(options) {
server.trace = router.trace;
server.connect = router.connect;
server.all = router.all;

server.use = router.use;

function requestListener(req, res) {
defineProperty(res, 'views', viewOptions);
defineProperty(res, 'cache', cache);
defineGetter(req, 'app', function () {
return server;
});

return router.lookup(req, res);
}
Expand Down
20 changes: 20 additions & 0 deletions lib/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function set(key, value) {
if (!this.settings) {
this.settings = {};
}

this.settings[key] = value;
}

function get(key) {
if (!this.settings) {
return undefined;
}

return this.settings[key];
}

module.exports = {
set,
get,
};
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"fastify-express": "^0.3.3",
"husky": "^7.0.2",
"jest": "^27.2.2",
"jest-junit": "^16.0.0",
"pem": "^1.14.4",
"prettier": "^2.4.1",
"serve-static": "^1.14.1",
Expand All @@ -69,11 +70,17 @@
"wrk": "^1.2.1"
},
"engines": {
"node": ">= 10.12.0"
"node": ">= 16"
},
"husky": {
"hooks": {
"pre-push": "npm test"
}
},
"jest": {
"reporters": [
"default",
"jest-junit"
]
}
}
12 changes: 6 additions & 6 deletions tests/cache/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ module.exports = function (options) {
cookieParser(),
timeout('30s'),
(req, res, next) => {
res.cache.has({});
res.cache.get({});
req.app.cache.has({});
req.app.cache.get({});

res.cache.set('/get-cache', {
req.app.cache.set('/get-cache', {
raw: JSON.stringify('data'),
method: 'GET',
headers: { 'X-Timezone': 'Asia/Ho_Chi_Minh' },
});

res.cache.set('/override-key', {
req.app.cache.set('/override-key', {
raw: JSON.stringify('data'),
method: 'POST',
headers: { 'X-Timezone': 'Asia/Ho_Chi_Minh' },
Expand Down Expand Up @@ -69,8 +69,8 @@ module.exports = function (options) {
res.jsonp({ '&': '\u2028<script>\u2029' }, true, { escape: true });
});

app.all('/error', (req, res) => {
res.cache.set({}, 'error');
app.all('/error', (req) => {
req.app.cache.set({}, 'error');
});

return app;
Expand Down
Loading

0 comments on commit e2096e9

Please sign in to comment.