Skip to content

Commit

Permalink
feat(ton): add the specific method route, such as post, get, put, del
Browse files Browse the repository at this point in the history
  • Loading branch information
trylovetom committed Apr 29, 2020
1 parent 1764347 commit 159a0c4
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 40 deletions.
69 changes: 49 additions & 20 deletions packages/ton/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,25 @@ export type TonLogger = {
debug: (...args: any[]) => void
verbose: (...args: any[]) => void
}
export type TonMethods =
export type TonHTTPMethods =
| 'get'
| 'post'
| 'options'
| 'del'
| 'path'
| 'patch'
| 'put'
| 'head'
| 'connect'
| 'trace'
| 'any'
| 'ws'
| 'publish'
// eslint-disable-next-line camelcase, @typescript-eslint/camelcase
export type TonListenSocket = uWS.us_listen_socket
export type TonRoutes = {
[patter: string]: { methods: TonMethods; handler: TonHandler }
[patter: string]: {
methods: TonHTTPMethods
handler: TonHandler
options: { logger: TonLogger }
}
}
export const TonStatusCodes = STATUS_CODES

Expand Down Expand Up @@ -159,6 +161,7 @@ export function sendJSON(
export function sendError(
res: TonResponse,
err: TonError | Error,
headers: TonHeaders = {},
/* istanbul ignore next */
{ logger = tonLogger }: { logger?: TonLogger } = {}
): void {
Expand All @@ -176,9 +179,9 @@ export function sendError(
const data = { message }

if (process.env.NODE_ENV === 'production' && statusCode >= 500) {
sendJSON(res, statusCode, { message: TonStatusCodes[statusCode] })
sendJSON(res, statusCode, { message: TonStatusCodes[statusCode] }, headers)
} else {
sendJSON(res, statusCode, data)
sendJSON(res, statusCode, data, headers)
}

if (statusCode < 500) {
Expand Down Expand Up @@ -304,7 +307,7 @@ export function send(
}

if (data instanceof Error) {
sendError(res, data, options)
sendError(res, data, headers, options)
return
}

Expand Down Expand Up @@ -376,31 +379,57 @@ export function handler(fn: TonHandler, options?: { logger: TonLogger }) {
return
}

send(res, res.statusCode || 200, result)
send(res, res.statusCode || 200, result, undefined, options)
} catch (err) {
sendError(res, create5xxError(500, TonStatusCodes[500], err), options)
sendError(
res,
create5xxError(500, TonStatusCodes[500], err),
undefined,
options
)
}
}
}

export function route(
app: TonApp,
methods: TonMethods,
methods: TonHTTPMethods,
pattern: string,
routeHandler: TonHandler
routeHandler: TonHandler,
options?: { logger: TonLogger }
) {
app[methods](pattern, handler(routeHandler))
app[methods](pattern, handler(routeHandler, options))
}

export function createRoute(methods: TonHTTPMethods) {
return (
app: TonApp,
pattern: string,
routeHandler: TonHandler,
options?: { logger: TonLogger }
) => route(app, methods, pattern, routeHandler, options)
}

export function createApp(options: TonAppSSLOptions = {}): TonApp {
if (options.ssl) {
export const any = createRoute('any')
export const connect = createRoute('connect')
export const del = createRoute('del')
export const get = createRoute('get')
export const head = createRoute('head')
export const options = createRoute('options')
export const patch = createRoute('patch')
export const post = createRoute('post')
export const put = createRoute('put')
export const trace = createRoute('trace')

export function createApp(opts: TonAppSSLOptions = {}): TonApp {
if (opts.ssl) {
/* eslint-disable @typescript-eslint/camelcase */
return uWS.SSLApp({
key_file_name: options.key,
cert_file_name: options.cert,
passphrase: options.passphrase,
dh_params_file_name: options.dhParams,
ssl_prefer_low_memory_usage: options.preferLowMemoryUsage
key_file_name: opts.key,
cert_file_name: opts.cert,
passphrase: opts.passphrase,
dh_params_file_name: opts.dhParams,
ssl_prefer_low_memory_usage: opts.preferLowMemoryUsage
})
/* eslint-enable @typescript-eslint/camelcase */
}
Expand Down
14 changes: 7 additions & 7 deletions packages/ton/src/send.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ describe('sendError', () => {

it('should not send anything, if response is aborted', () => {
mockRes.aborted = true
ton.sendError(mockRes, errorNormal, { logger: mockLogger })
ton.sendError(mockRes, errorNormal, undefined, { logger: mockLogger })

expect(mockLogger.error).toHaveBeenCalledTimes(1)
expect(mockLogger.error).toHaveBeenCalledWith(
Expand All @@ -243,7 +243,7 @@ describe('sendError', () => {
})

it('should send normal error with 500 statusCode', () => {
ton.sendError(mockRes, errorNormal, { logger: mockLogger })
ton.sendError(mockRes, errorNormal, undefined, { logger: mockLogger })

expect(mockRes.writeStatus).toHaveBeenCalledTimes(1)
expect(mockRes.writeStatus).toHaveBeenCalledWith(
Expand All @@ -265,7 +265,7 @@ describe('sendError', () => {
})

it('should send 500 error and logger.error message of normal error', () => {
ton.sendError(mockRes, error500, { logger: mockLogger })
ton.sendError(mockRes, error500, undefined, { logger: mockLogger })

expect(mockRes.writeStatus).toHaveBeenCalledTimes(1)
expect(mockRes.writeStatus).toHaveBeenCalledWith(
Expand All @@ -289,7 +289,7 @@ describe('sendError', () => {
})

it('should send 400 error and should not logger.error it', () => {
ton.sendError(mockRes, error400, { logger: mockLogger })
ton.sendError(mockRes, error400, undefined, { logger: mockLogger })

expect(mockRes.writeStatus).toHaveBeenCalledTimes(1)
expect(mockRes.writeStatus).toHaveBeenCalledWith(
Expand All @@ -315,7 +315,7 @@ describe('sendError', () => {
should send normal error with 500 statusCode and message of TonStatusCode, \
if process.env.NODE_ENV equal to 'production'`, () => {
process.env.NODE_ENV = 'production'
ton.sendError(mockRes, errorNormal, { logger: mockLogger })
ton.sendError(mockRes, errorNormal, undefined, { logger: mockLogger })

expect(mockRes.writeStatus).toHaveBeenCalledTimes(1)
expect(mockRes.writeStatus).toHaveBeenCalledWith(
Expand All @@ -342,7 +342,7 @@ if process.env.NODE_ENV equal to 'production'`, () => {
if message is empty`, () => {
const errorEmpty = new Error() as ton.TonError
errorEmpty.statusCode = 502
ton.sendError(mockRes, errorEmpty, { logger: mockLogger })
ton.sendError(mockRes, errorEmpty, undefined, { logger: mockLogger })

expect(mockRes.writeStatus).toHaveBeenCalledTimes(1)
expect(mockRes.writeStatus).toHaveBeenCalledWith(
Expand All @@ -368,7 +368,7 @@ if message is empty`, () => {
it(`should send message of TonStatusCodes[500], if message is empty`, () => {
const errorEmpty = new Error() as ton.TonError
errorEmpty.statusCode = 600
ton.sendError(mockRes, errorEmpty, { logger: mockLogger })
ton.sendError(mockRes, errorEmpty, undefined, { logger: mockLogger })

expect(mockRes.writeStatus).toHaveBeenCalledTimes(1)
expect(mockRes.writeStatus).toHaveBeenCalledWith(
Expand Down
92 changes: 92 additions & 0 deletions packages/ton/src/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,98 @@ describe('route', () => {
})
})

describe('createRoute', () => {
it('should create route with specific method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const get = ton.createRoute('get')
get(mockApp, '/*', mockHandler)
expect(mockApp.get).toBeCalledTimes(1)
expect((mockApp.get as jest.Mock).mock.calls[0][0]).toBe('/*')
})
})

describe('routes', () => {
it('should create route with any method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const any = ton.createRoute('any')
any(mockApp, '/*', mockHandler)
expect(mockApp.any).toBeCalledTimes(1)
expect((mockApp.any as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with connect method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const connect = ton.createRoute('connect')
connect(mockApp, '/*', mockHandler)
expect(mockApp.connect).toBeCalledTimes(1)
expect((mockApp.connect as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with del method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const del = ton.createRoute('del')
del(mockApp, '/*', mockHandler)
expect(mockApp.del).toBeCalledTimes(1)
expect((mockApp.del as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with get method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const get = ton.createRoute('get')
get(mockApp, '/*', mockHandler)
expect(mockApp.get).toBeCalledTimes(1)
expect((mockApp.get as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with head method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const head = ton.createRoute('head')
head(mockApp, '/*', mockHandler)
expect(mockApp.head).toBeCalledTimes(1)
expect((mockApp.head as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with options method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const options = ton.createRoute('options')
options(mockApp, '/*', mockHandler)
expect(mockApp.options).toBeCalledTimes(1)
expect((mockApp.options as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with patch method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const patch = ton.createRoute('patch')
patch(mockApp, '/*', mockHandler)
expect(mockApp.patch).toBeCalledTimes(1)
expect((mockApp.patch as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with post method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const post = ton.createRoute('post')
post(mockApp, '/*', mockHandler)
expect(mockApp.post).toBeCalledTimes(1)
expect((mockApp.post as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with put method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const put = ton.createRoute('put')
put(mockApp, '/*', mockHandler)
expect(mockApp.put).toBeCalledTimes(1)
expect((mockApp.put as jest.Mock).mock.calls[0][0]).toBe('/*')
})

it('should create route with trace method', () => {
const mockHandler: ton.TonHandler = jest.fn()
const trace = ton.createRoute('trace')
trace(mockApp, '/*', mockHandler)
expect(mockApp.trace).toBeCalledTimes(1)
expect((mockApp.trace as jest.Mock).mock.calls[0][0]).toBe('/*')
})
})

describe('createApp', () => {
it('should create the app', () => {
const app = ton.createApp()
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": "@alljoint-next/ts-config",
"compilerOptions": {
"types": ["jest", "node", "reflect-metadata"]
"types": ["jest", "node"]
}
}
12 changes: 0 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1621,13 +1621,6 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f"
integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==

"@types/reflect-metadata@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@types/reflect-metadata/-/reflect-metadata-0.1.0.tgz#592805bdf6d63dd7229773218afeba37ac2eab16"
integrity sha512-bXltFLY3qhzCnVYP5iUpeSICagQ8rc9K2liS+8M0lBcz54BHs3O6W5UvqespVSuebo1BXLi+/y9ioELAW9SC2A==
dependencies:
reflect-metadata "*"

"@types/stack-utils@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
Expand Down Expand Up @@ -6731,11 +6724,6 @@ redent@^2.0.0:
indent-string "^3.0.0"
strip-indent "^2.0.0"

reflect-metadata@*, reflect-metadata@^0.1.13:
version "0.1.13"
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==

regenerator-runtime@^0.10.5:
version "0.10.5"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
Expand Down

0 comments on commit 159a0c4

Please sign in to comment.