Skip to content

Commit caa048b

Browse files
authored
Merge pull request #8 from SecJS/feat/len-ctx-impl
Feat/len ctx impl
2 parents 79097df + 84a7e13 commit caa048b

File tree

12 files changed

+267
-160
lines changed

12 files changed

+267
-160
lines changed

README.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,18 @@ yarn add @secjs/http
2929

3030
## Usage
3131

32-
### Sec
32+
### SecJS
3333

34-
> Use Sec to create the Http server and map all your routes with handlers
34+
> Use SecJS to create the Http server and map all your routes with handlers
3535
3636
```ts
37-
import { Sec, Context } from '@secjs/http'
37+
import { SecJS } from '@secjs/http'
38+
import { SecContextContract } from '@secjs/contracts'
3839

39-
const server = new Sec()
40+
const server = new SecJS()
4041

41-
server.get('/', (ctx: Context) => {
42-
ctx.response.writeHead(200, { 'Content-Type': 'application/json' })
43-
44-
ctx.response.write(JSON.stringify({ hello: 'world!' }))
45-
46-
ctx.response.end()
42+
server.get('/', (ctx: SecContextContract) => {
43+
ctx.response.status(200).json({ hello: 'world!' })
4744
})
4845

4946
server.listen(4040, () => console.log('Server running!'))

index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export * from './src/server'
1+
export * from './src/SecJS'
22

3-
export * from './src/Contracts/RouteContract'
4-
export * from './src/Contracts/HandlerContract'
3+
export * from './src/Context/Request/SecRequest'
4+
export * from './src/Context/Response/SecResponse'

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@secjs/http",
3-
"version": "0.0.5",
3+
"version": "0.0.7",
44
"description": "",
55
"scripts": {
66
"build": "tsc",
@@ -16,8 +16,8 @@
1616
"author": "João Lenon <lenonsec7@gmail.com>",
1717
"license": "MIT",
1818
"dependencies": {
19-
"@secjs/contracts": "^1.0.7",
20-
"@secjs/utils": "^1.3.0"
19+
"@secjs/contracts": "^1.1.0",
20+
"@secjs/utils": "^1.3.2"
2121
},
2222
"files": [
2323
"src/*.d.ts",

src/Context/Request/SecRequest.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { SecRequestContract } from '@secjs/contracts'
2+
import { Route } from '@secjs/utils/src/Classes/Route'
3+
4+
export class SecRequest implements SecRequestContract {
5+
private _ip = ''
6+
private _body = ''
7+
private _method = ''
8+
private _params = {}
9+
private _queries = {}
10+
private _headers = {}
11+
private _fullUrl = ''
12+
private _baseUrl = ''
13+
private _originalUrl = ''
14+
private routeUtils = new Route()
15+
16+
constructor(request: any) {
17+
this._body = request.body
18+
this._method = request.method
19+
this._originalUrl = request.url
20+
this._headers = request.headers
21+
this._baseUrl = request.route.path
22+
this._ip = request.socket.remoteAddress
23+
this._fullUrl = this.routeUtils.removeQueryParams(request.url)
24+
this._queries = this.routeUtils.getQueryParamsValue(request.url) || {}
25+
this._params =
26+
this.routeUtils.getParamsValue(request.route.path, request.url) || {}
27+
}
28+
29+
payload(payload: string, defaultValue?: string): any {
30+
return this.body[payload] || defaultValue
31+
}
32+
33+
param(param: string, defaultValue?: string): string {
34+
return this.params[param] || defaultValue
35+
}
36+
37+
query(query: string, defaultValue?: string): string {
38+
return this.queries[query] || defaultValue
39+
}
40+
41+
header(header: string, defaultValue?: string): string {
42+
return this._headers[header] || defaultValue
43+
}
44+
45+
get ip(): string {
46+
return this._ip
47+
}
48+
49+
get body(): any {
50+
return this._body
51+
}
52+
53+
get params(): any {
54+
return this._params
55+
}
56+
57+
get queries(): any {
58+
return this._queries
59+
}
60+
61+
get method(): string {
62+
return this._method
63+
}
64+
65+
get fullUrl(): string {
66+
return this._fullUrl
67+
}
68+
69+
get baseUrl(): string {
70+
return this._baseUrl
71+
}
72+
73+
get originalUrl(): string {
74+
return this._originalUrl
75+
}
76+
}

src/Context/Response/SecResponse.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { ServerResponse } from 'http'
2+
import { SecResponseContract } from '@secjs/contracts'
3+
4+
export class SecResponse implements SecResponseContract {
5+
private vanillaResponse: ServerResponse
6+
7+
constructor(response: ServerResponse) {
8+
this.secResponseBuilder(response)
9+
}
10+
11+
private secResponseBuilder(response: ServerResponse): void {
12+
this.vanillaResponse = response
13+
}
14+
15+
end(): void {
16+
this.vanillaResponse.end()
17+
}
18+
19+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
20+
send(data?: any): void {
21+
this.vanillaResponse.end(data)
22+
}
23+
24+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
25+
json(data?: any): void {
26+
this.vanillaResponse.setHeader('Accept', 'application/json')
27+
this.vanillaResponse.setHeader('Content-Type', 'application/json')
28+
29+
this.vanillaResponse.end(JSON.stringify(data))
30+
}
31+
32+
status(code: number): this {
33+
this.vanillaResponse.statusCode = code
34+
35+
return this
36+
}
37+
38+
header(header: string, value: any): this {
39+
this.vanillaResponse.setHeader(header, value)
40+
41+
return this
42+
}
43+
44+
safeHeader(header: string, value: any): this {
45+
this.vanillaResponse.setHeader(header, value)
46+
47+
return this
48+
}
49+
50+
removeHeader(header: string): this {
51+
this.vanillaResponse.removeHeader(header)
52+
53+
return this
54+
}
55+
}

src/Contracts/HandlerContract.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/Contracts/RouteContract.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/SecJS.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import constants from './constants'
2+
3+
import { Route } from '@secjs/utils/src/Classes/Route'
4+
import { SecRequest } from './Context/Request/SecRequest'
5+
import { SecResponse } from './Context/Response/SecResponse'
6+
import { createServer, IncomingMessage, Server } from 'http'
7+
import { InternalRouteContract, SecHandlerContract } from '@secjs/contracts'
8+
9+
export class SecJS {
10+
private nodeServer: Server
11+
private routeUtils = new Route()
12+
private routes: InternalRouteContract[] = []
13+
14+
private async getBody(request: IncomingMessage): Promise<any> {
15+
const buffers = []
16+
17+
for await (const chunk of request) {
18+
buffers.push(chunk)
19+
}
20+
21+
if (!buffers.length) return {}
22+
23+
return JSON.parse(Buffer.concat(buffers).toString())
24+
}
25+
26+
private getRoute(url: string, method: string) {
27+
return (
28+
this.routes.find(
29+
route =>
30+
route.matcher.test(this.routeUtils.removeQueryParams(url)) &&
31+
route.method === method,
32+
) || constants.DEFAULT_ROUTE
33+
)
34+
}
35+
36+
private createRouteHandler(
37+
path: string,
38+
method: string,
39+
secHandler: SecHandlerContract,
40+
): void {
41+
this.routes.push({
42+
path,
43+
method: method.toUpperCase(),
44+
handler: secHandler,
45+
params: this.routeUtils.getParamsName(path),
46+
matcher: this.routeUtils.createMatcher(path),
47+
})
48+
}
49+
50+
listen(port?: number, cb?: () => void): void {
51+
this.nodeServer = createServer(async (request: any, response: any) => {
52+
const { url, method } = request
53+
54+
const route = this.getRoute(url, method)
55+
56+
request.route = route
57+
request.body = await this.getBody(request)
58+
59+
return route.handler({
60+
next: () => console.log('next'),
61+
request: new SecRequest(request),
62+
response: new SecResponse(response),
63+
})
64+
})
65+
66+
this.nodeServer.listen(port || constants.PORT, cb)
67+
}
68+
69+
close(cb?: (err?: Error) => void): void {
70+
this.nodeServer.close(cb)
71+
}
72+
73+
get(route: string, secHandler: SecHandlerContract): void {
74+
this.createRouteHandler(route, this.get.name, secHandler)
75+
}
76+
77+
post(route: string, secHandler: SecHandlerContract): void {
78+
this.createRouteHandler(route, this.post.name, secHandler)
79+
}
80+
81+
put(route: string, secHandler: SecHandlerContract): void {
82+
this.createRouteHandler(route, this.put.name, secHandler)
83+
}
84+
85+
delete(route: string, secHandler: SecHandlerContract): void {
86+
this.createRouteHandler(route, this.delete.name, secHandler)
87+
}
88+
}

src/constants.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Context } from './Contracts/HandlerContract'
1+
import { SecContextContract } from '@secjs/contracts'
22

33
export default {
44
PORT: 4040,
@@ -12,12 +12,8 @@ export default {
1212
method: 'ALL',
1313
params: [],
1414
matcher: /\//,
15-
handler: (ctx: Context): any => {
16-
ctx.response.writeHead(404, { 'Content-Type': 'application/json' })
17-
18-
ctx.response.write(JSON.stringify({ message: 'Not found!' }))
19-
20-
ctx.response.end()
15+
handler: ({ response }: SecContextContract): any => {
16+
return response.status(404).json({ message: 'Not found!' })
2117
},
2218
},
2319
}

src/server.ts

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)