Add middleware abstraction
This commit is contained in:
parent
42bda32985
commit
00192d2f3b
@ -19,7 +19,8 @@
|
||||
"@rondo.dev/test-utils": "file:packages/test-utils",
|
||||
"@rondo.dev/validator": "file:packages/validator",
|
||||
"@rondo.dev/db": "file:packages/db",
|
||||
"@rondo.dev/db-typeorm": "file:packages/db-typeorm"
|
||||
"@rondo.dev/db-typeorm": "file:packages/db-typeorm",
|
||||
"@rondo.dev/middleware": "file:packages/middleware"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcrypt": "^3.0.0",
|
||||
@ -104,4 +105,4 @@
|
||||
"watchify": "^3.11.1"
|
||||
},
|
||||
"name": "node"
|
||||
}
|
||||
}
|
||||
7
packages/middleware/README.md
Normal file
7
packages/middleware/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# @rondo.dev/middleware
|
||||
|
||||
This package provides a framework-agnostic way to define middlewares for any
|
||||
framework by using the Node's `http.IncomingMessage` and `http.ServerResponse`
|
||||
types.
|
||||
|
||||
See tests for more information.
|
||||
16
packages/middleware/jest.config.js
Normal file
16
packages/middleware/jest.config.js
Normal file
@ -0,0 +1,16 @@
|
||||
module.exports = {
|
||||
roots: [
|
||||
'<rootDir>/src',
|
||||
],
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'ts-jest',
|
||||
},
|
||||
testRegex: '(/__tests__/.*|\\.(test|spec))\\.tsx?$',
|
||||
moduleFileExtensions: [
|
||||
'ts',
|
||||
'tsx',
|
||||
'js',
|
||||
'jsx',
|
||||
],
|
||||
setupFiles: ['<rootDir>/jest.setup.js'],
|
||||
}
|
||||
4
packages/middleware/jest.setup.js
Normal file
4
packages/middleware/jest.setup.js
Normal file
@ -0,0 +1,4 @@
|
||||
if (!process.env.LOG) {
|
||||
process.env.LOG = 'sql:warn'
|
||||
}
|
||||
process.chdir(__dirname)
|
||||
4
packages/middleware/package-lock.json
generated
Normal file
4
packages/middleware/package-lock.json
generated
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@rondo.dev/middleware",
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
14
packages/middleware/package.json
Normal file
14
packages/middleware/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@rondo.dev/middleware",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"lint": "tslint --project .",
|
||||
"compile": "tsc",
|
||||
"clean": "rm -rf lib/"
|
||||
},
|
||||
"dependencies": {},
|
||||
"main": "lib/index.js",
|
||||
"module": "esm/index.js",
|
||||
"types": "lib/index.d.ts"
|
||||
}
|
||||
6
packages/middleware/src/Context.ts
Normal file
6
packages/middleware/src/Context.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { IncomingMessage, ServerResponse } from 'http'
|
||||
|
||||
export type Context = {
|
||||
req: IncomingMessage
|
||||
res: ServerResponse
|
||||
}
|
||||
3
packages/middleware/src/Middleware.ts
Normal file
3
packages/middleware/src/Middleware.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { Context } from './Context'
|
||||
|
||||
export type Middleware = <C extends Context>(ctx: C) => unknown
|
||||
7
packages/middleware/src/createMiddleware.ts
Normal file
7
packages/middleware/src/createMiddleware.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { Context } from './Context'
|
||||
|
||||
export const createMiddleware =
|
||||
<C extends Context = Context>(fn: (ctx: C) => unknown) => async (ctx: C) => {
|
||||
await fn(ctx)
|
||||
return undefined
|
||||
}
|
||||
49
packages/middleware/src/expressify.test.ts
Normal file
49
packages/middleware/src/expressify.test.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import express from 'express'
|
||||
import { expressify } from './expressify'
|
||||
import request from 'supertest'
|
||||
import { createMiddleware } from './createMiddleware'
|
||||
|
||||
describe('expressify', () => {
|
||||
|
||||
describe('middleware', () => {
|
||||
it('acts as a middleware when returned value is undefined', async () => {
|
||||
const app = express()
|
||||
app.use(
|
||||
expressify(
|
||||
createMiddleware(ctx => (ctx.req as any).id = 'test')))
|
||||
app.get('/test', (req, res) => res.json({ id: (req as any).id }))
|
||||
await request(app)
|
||||
.get('/test')
|
||||
.expect(200)
|
||||
.expect('{"id":"test"}')
|
||||
})
|
||||
})
|
||||
|
||||
describe('response', () => {
|
||||
it('sends a response', async () => {
|
||||
const app = express()
|
||||
app.use(
|
||||
expressify(
|
||||
createMiddleware(ctx => (ctx.req as any).id = 'test')))
|
||||
app.get('/test', expressify(ctx => (ctx.req as any).id))
|
||||
request(app)
|
||||
.get('/test')
|
||||
.expect(200)
|
||||
.expect('"test"')
|
||||
})
|
||||
|
||||
it('can send a response using a custom fn', () => {
|
||||
const app = express()
|
||||
app.use(
|
||||
expressify(
|
||||
createMiddleware(ctx => (ctx.req as any).id = 'test')))
|
||||
app.get('/test',
|
||||
expressify(ctx => (ctx.req as any).id, (res, value) => res.send(value)))
|
||||
request(app)
|
||||
.get('/test')
|
||||
.expect(200)
|
||||
.expect('test')
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
28
packages/middleware/src/expressify.ts
Normal file
28
packages/middleware/src/expressify.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { IncomingMessage, ServerResponse } from 'http'
|
||||
import { Middleware } from './Middleware'
|
||||
|
||||
export const expressify = (
|
||||
handleMiddleware: Middleware,
|
||||
sendResponse: (res: Response, result: unknown) => void =
|
||||
(res, result) => res.json(result),
|
||||
) => async (
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
) => {
|
||||
let result: unknown
|
||||
try {
|
||||
const r: IncomingMessage = req
|
||||
const rr: ServerResponse = res
|
||||
result = await handleMiddleware({req: r, res: rr})
|
||||
} catch (err) {
|
||||
next(err)
|
||||
return
|
||||
}
|
||||
if (result === undefined) {
|
||||
next()
|
||||
return
|
||||
}
|
||||
sendResponse(res, result)
|
||||
}
|
||||
3
packages/middleware/src/index.ts
Normal file
3
packages/middleware/src/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './Context'
|
||||
export * from './expressify'
|
||||
export * from './Middleware'
|
||||
8
packages/middleware/tsconfig.esm.json
Normal file
8
packages/middleware/tsconfig.esm.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "esm"
|
||||
},
|
||||
"references": [
|
||||
]
|
||||
}
|
||||
9
packages/middleware/tsconfig.json
Normal file
9
packages/middleware/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../tsconfig.common.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"references": [
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user