diff --git a/index.d.ts b/index.d.ts index f2d9195..ed2f348 100644 --- a/index.d.ts +++ b/index.d.ts @@ -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 {} @@ -269,9 +271,14 @@ declare module 'pure-http' { stale?: boolean; } - export interface IPureHttpServer extends net.Server, IRouter {} + export interface ILocals { + set(key: string, value: any): this; + get(key: string): T; + } + + export interface IPureHttpServer extends net.Server, IRouter, ILocals {} - export interface IPureHttpSecureServer extends tls.Server, IRouter {} + export interface IPureHttpSecureServer extends tls.Server, IRouter, ILocals {} export interface IOptions { server?: net.Server | tls.Server; diff --git a/lib/locals.js b/lib/locals.js new file mode 100644 index 0000000..a10ef3d --- /dev/null +++ b/lib/locals.js @@ -0,0 +1,20 @@ +function set(key, value) { + if (!this.locals) { + this.locals = {}; + } + + this.locals[key] = value; +} + +function get(key) { + if (!this.locals) { + return undefined; + } + + return this.locals[key]; +} + +module.exports = { + set, + get, +}; diff --git a/lib/pure-http.js b/lib/pure-http.js index 399a840..5a9e0b2 100644 --- a/lib/pure-http.js +++ b/lib/pure-http.js @@ -1,12 +1,11 @@ const http = require('http'); const https = require('https'); +const locals = require('./locals'); 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(); @@ -18,7 +17,17 @@ function pureHttp(options) { server = existedServer; } - server.get = router.get; + const router = new Router(); + + server.set = locals.set.bind(server); + server.get = function get() { + if (arguments.length === 1) { + const key = arguments[0]; + return locals.get.call(server, key); + } + + return router.get.apply(router, arguments); + }; server.post = router.post; server.put = router.put; server.patch = router.patch; @@ -28,12 +37,18 @@ 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; + }); + defineGetter(res, 'views', function () { + return viewOptions; + }); + defineGetter(res, 'cache', function () { + return cache; + }); return router.lookup(req, res); } diff --git a/tests/locals/index.test.js b/tests/locals/index.test.js new file mode 100644 index 0000000..e411394 --- /dev/null +++ b/tests/locals/index.test.js @@ -0,0 +1,41 @@ +const supertest = require('supertest'); +const pureHttp = require('../..'); + +describe('configs', () => { + it('should set and get configs', async () => { + const app = pureHttp(); + app.set('foo', 'bar'); + app.set('lorem', 'ipsum'); + + app.use((req, res) => { + const foo = req.app.get('foo'); + const lorem = req.app.get('lorem'); + res.send({ + foo, + lorem, + }); + }); + + const request = supertest(app); + const res = await request.get('/'); + + const expected = { + foo: 'bar', + lorem: 'ipsum', + }; + + expect(res.body).toEqual(expected); + }); + + it('should return undefined if the config is not set', async () => { + const app = pureHttp(); + + app.use((req, res) => { + const foo = req.app.get('foo'); + res.send(String(foo)); + }); + + const request = supertest(app); + await request.get('/').expect(200, 'undefined'); + }); +});