Skip to content

Commit b6daa66

Browse files
committed
feat: ctx Impl
1 parent 79097df commit b6daa66

File tree

9 files changed

+238
-113
lines changed

9 files changed

+238
-113
lines changed

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

src/Context/Response/SecResponse.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.end(JSON.stringify(data))
27+
}
28+
29+
status(code: number): this {
30+
this.vanillaResponse.statusCode = code
31+
32+
return this
33+
}
34+
35+
header(header: string, value: any): this {
36+
this.vanillaResponse.setHeader(header, value)
37+
38+
return this
39+
}
40+
41+
safeHeader(header: string, value: any): this {
42+
this.vanillaResponse.setHeader(header, value)
43+
44+
return this
45+
}
46+
47+
removeHeader(header: string): this {
48+
this.vanillaResponse.removeHeader(header)
49+
50+
return this
51+
}
52+
}

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: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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 { InternalRouteContract, SecHandlerContract } from '@secjs/contracts'
7+
import { createServer, IncomingMessage, Server, ServerResponse } from 'http'
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+
return JSON.parse(Buffer.concat(buffers).toString())
22+
}
23+
24+
private getRoute(url: string, method: string) {
25+
return (
26+
this.routes.find(
27+
route =>
28+
route.matcher.test(this.routeUtils.removeQueryParams(url)) &&
29+
route.method === method,
30+
) || constants.DEFAULT_ROUTE
31+
)
32+
}
33+
34+
private createRouteHandler(
35+
path: string,
36+
method: string,
37+
secHandler: SecHandlerContract,
38+
): void {
39+
this.routes.push({
40+
path,
41+
method: method.toUpperCase(),
42+
handler: secHandler,
43+
params: this.routeUtils.getParamsName(path),
44+
matcher: this.routeUtils.createMatcher(path),
45+
})
46+
}
47+
48+
listen(port?: number, cb?: () => void): void {
49+
this.nodeServer = createServer(
50+
async (request: IncomingMessage, response: ServerResponse) => {
51+
const { url, method } = request
52+
53+
response.writeHead(200, {
54+
Accept: 'application/json',
55+
'Content-Type': 'application/json',
56+
})
57+
58+
const route = this.getRoute(url, method)
59+
60+
return route.handler({
61+
next: () => console.log('next'),
62+
request: new SecRequest(this.getBody(request), route, request),
63+
response: new SecResponse(response),
64+
})
65+
},
66+
)
67+
68+
this.nodeServer.listen(port || constants.PORT, cb)
69+
}
70+
71+
close(cb?: (err?: Error) => void): void {
72+
this.nodeServer.close(cb)
73+
}
74+
75+
get(route: string, secHandler: SecHandlerContract): void {
76+
this.createRouteHandler(route, this.get.name, secHandler)
77+
}
78+
79+
post(route: string, secHandler: SecHandlerContract): void {
80+
this.createRouteHandler(route, this.post.name, secHandler)
81+
}
82+
83+
put(route: string, secHandler: SecHandlerContract): void {
84+
this.createRouteHandler(route, this.put.name, secHandler)
85+
}
86+
87+
delete(route: string, secHandler: SecHandlerContract): void {
88+
this.createRouteHandler(route, this.delete.name, secHandler)
89+
}
90+
}

src/constants.ts

Lines changed: 5 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,10 @@ 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
17+
.status(404)
18+
.json(JSON.stringify({ message: 'Not found!' }))
2119
},
2220
},
2321
}

src/server.ts

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

yarn.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -565,15 +565,15 @@
565565
resolved "https://registry.yarnpkg.com/@secjs/contracts/-/contracts-1.0.4.tgz#79d8127afd3e42454f281ad4b4a58a1d2e49b44a"
566566
integrity sha512-yXzC2bCk5o+7EQUye79k8mB4fkzBsOvQYkhDAJtqjy04tR14znbp6gBqAOvU3OHkJ6DlbwWGmsVEfk98qVo+0w==
567567

568-
"@secjs/contracts@^1.0.7":
569-
version "1.0.7"
570-
resolved "https://registry.yarnpkg.com/@secjs/contracts/-/contracts-1.0.7.tgz#d4ec704d6f5f6886635f7f1523c6ccae4ca44f8f"
571-
integrity sha512-HFOKPRaPH0qJtfZXy7sci3fTzY0Akt7ySlJcp1wO4rBBy+OXgKnjpUucobRzIQfaM97WaaNr3QXcACQI/DHiVw==
568+
"@secjs/contracts@^1.1.0":
569+
version "1.1.0"
570+
resolved "https://registry.yarnpkg.com/@secjs/contracts/-/contracts-1.1.0.tgz#f8edebad79086eabff847ff39a1e74256155ece3"
571+
integrity sha512-7YIzAQ1H5tYKHCuoynLGMuOajJnypiXbtB9/AXnwBxwg3auew41eczXbObqBYlolYww9jHvEsWief+/QHMMH6Q==
572572

573-
"@secjs/utils@^1.3.0":
574-
version "1.3.0"
575-
resolved "https://registry.yarnpkg.com/@secjs/utils/-/utils-1.3.0.tgz#29aa1f7b15c740cf4f34a5a74eb959c2238e1c53"
576-
integrity sha512-axuwtU6KM9Dk5pIA+00tVAgFhru7V9BXpdpaA0v2z0igte6NeIZkT1oKAJARYtXRKsAYDYZXru4xuSb1kZE/WQ==
573+
"@secjs/utils@^1.3.2":
574+
version "1.3.2"
575+
resolved "https://registry.yarnpkg.com/@secjs/utils/-/utils-1.3.2.tgz#be8b7457dbc39420456d97fc918423fd7306878d"
576+
integrity sha512-IHkcoJTa2UC8J8u/CWs+Pkco6eNX23CFSMMzbmngT2qknJpNHbrRWUq620RX4zC1iGu/si/rjEnZv7C7RK6etA==
577577
dependencies:
578578
"@secjs/contracts" "^1.0.4"
579579
uuid "^8.3.2"

0 commit comments

Comments
 (0)