bun-router 0.5.8 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- package/examples/basic.ts +3 -3
- package/examples/cookies.ts +15 -0
- package/examples/dynamic.ts +6 -6
- package/examples/logger.ts +2 -2
- package/examples/sqlite.ts +2 -2
- package/examples/todo.ts +3 -3
- package/lib/http/generic-methods.ts +10 -11
- package/lib/router/router.d.ts +10 -5
- package/lib/router/router.ts +20 -5
- package/package.json +1 -1
package/examples/basic.ts
CHANGED
@@ -2,17 +2,17 @@ import { router, http } from '..';
|
|
2
2
|
|
3
3
|
const r = router();
|
4
4
|
|
5
|
-
r.add('/', 'GET', () => http.json('ok'));
|
5
|
+
r.add('/', 'GET', () => http.json(200, 'ok'));
|
6
6
|
|
7
7
|
r.add('/user/:name', 'GET', (ctx) => {
|
8
8
|
const name = ctx.params.get('name');
|
9
|
-
return http.json(name);
|
9
|
+
return http.json(200, name);
|
10
10
|
});
|
11
11
|
|
12
12
|
r.add('/user/:name/:id', 'GET', (ctx) => {
|
13
13
|
const name = ctx.params.get('name');
|
14
14
|
const id = ctx.params.get('id');
|
15
|
-
return http.json({name: name, id: id});
|
15
|
+
return http.json(200, {name: name, id: id});
|
16
16
|
});
|
17
17
|
|
18
18
|
r.serve();
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { router } from '..';
|
2
|
+
|
3
|
+
const r = router();
|
4
|
+
|
5
|
+
r.add('/set-cookie', 'GET', ctx => {
|
6
|
+
ctx.cookies.set('domain', 'localhost');
|
7
|
+
ctx.cookies.set('path', '/set-cookie');
|
8
|
+
|
9
|
+
ctx.logger.message(ctx.token ?? 'no token provided');
|
10
|
+
|
11
|
+
return ctx.json( 200, {message: 'cookie stored'});
|
12
|
+
});
|
13
|
+
|
14
|
+
|
15
|
+
r.serve();
|
package/examples/dynamic.ts
CHANGED
@@ -3,20 +3,20 @@ import { Context } from '../lib/router/router.d';
|
|
3
3
|
|
4
4
|
const handler = (ctx: Context) => {
|
5
5
|
const name = ctx.params.get('name');
|
6
|
-
if (typeof name === 'undefined' || name === '') return http.html('<h6 style="color: red">User Undefined</h6>');
|
7
|
-
return http.html(`<h4>Hello, ${name}!</h4>`);
|
6
|
+
if (typeof name === 'undefined' || name === '') return http.html(500, '<h6 style="color: red">User Undefined</h6>');
|
7
|
+
return http.html(200, `<h4>Hello, ${name}!</h4>`);
|
8
8
|
}
|
9
9
|
|
10
10
|
const space = (ctx: Context) => {
|
11
11
|
const name = ctx.params.get('name');
|
12
|
-
if (typeof name === 'undefined' || name === '') return http.html(`<h6 style="color: red">Space [${name}] Not Found</h6>`);
|
13
|
-
return http.html(`<h4>Welcome to ${name}!`)
|
12
|
+
if (typeof name === 'undefined' || name === '') return http.html(404, `<h6 style="color: red">Space [${name}] Not Found</h6>`);
|
13
|
+
return http.html(200, `<h4>Welcome to ${name}!`)
|
14
14
|
}
|
15
15
|
|
16
16
|
const handleSettings = (ctx: Context) => {
|
17
17
|
const name = ctx.params.get('name');
|
18
|
-
if (typeof name === 'undefined' || name === '') return http.html(`<h6 style="color: red">User Not Found</h6>`);
|
19
|
-
return http.html(`<h4>Settings for ${name}</h4>`)
|
18
|
+
if (typeof name === 'undefined' || name === '') return http.html(404, `<h6 style="color: red">User Not Found</h6>`);
|
19
|
+
return http.html(200, `<h4>Settings for ${name}</h4>`)
|
20
20
|
}
|
21
21
|
|
22
22
|
const r = router();
|
package/examples/logger.ts
CHANGED
@@ -8,9 +8,9 @@ r.add('/:foo', 'GET', (ctx) => {
|
|
8
8
|
const foo = ctx.params.get('foo');
|
9
9
|
if (!foo) {
|
10
10
|
log.error(500, url.pathname, ctx.request.method, new Error('undefined'));
|
11
|
-
return http.json(
|
11
|
+
return http.json(500,{text: 'Foo is undefined'});
|
12
12
|
}
|
13
|
-
return http.html(`<h4 style='font-family: sans-serif;'>Oh hello, ${foo}</h4>`)
|
13
|
+
return http.html(200, `<h4 style='font-family: sans-serif;'>Oh hello, ${foo}</h4>`)
|
14
14
|
});
|
15
15
|
|
16
16
|
r.serve();
|
package/examples/sqlite.ts
CHANGED
@@ -8,7 +8,7 @@ r.add('/u/new/:name', 'GET', (ctx) => {
|
|
8
8
|
|
9
9
|
ctx.db.run(`INSERT INTO test VALUES(${rando}, "${name}")`);
|
10
10
|
|
11
|
-
return http.json({message: 'ok'});
|
11
|
+
return http.json(200, {message: 'ok'});
|
12
12
|
});
|
13
13
|
|
14
14
|
r.add('/u/:name', 'GET', (ctx) => {
|
@@ -16,7 +16,7 @@ r.add('/u/:name', 'GET', (ctx) => {
|
|
16
16
|
const data = ctx.db.query(`SELECT * FROM test WHERE name = "${name}";`).get();
|
17
17
|
const d = data as {id: number, name: string};
|
18
18
|
|
19
|
-
return d ? http.json(d) : new Response('not found', {status: 404});
|
19
|
+
return d ? http.json(200, d) : new Response('not found', {status: 404});
|
20
20
|
});
|
21
21
|
|
22
22
|
r.serve();
|
package/examples/todo.ts
CHANGED
@@ -26,7 +26,7 @@ r.add('/api/new', 'POST', ctx => {
|
|
26
26
|
ctx.logger.message(`Adding ${key} with ${content}`);
|
27
27
|
todo.add(key, content);
|
28
28
|
|
29
|
-
return ctx.json({ message: 'ok' });
|
29
|
+
return ctx.json(200, { message: 'ok' });
|
30
30
|
});
|
31
31
|
|
32
32
|
r.add('/api/todo/:key', 'GET', ctx => {
|
@@ -36,11 +36,11 @@ r.add('/api/todo/:key', 'GET', ctx => {
|
|
36
36
|
const content = todo.get(key);
|
37
37
|
if (!content) return http.notFound();
|
38
38
|
|
39
|
-
return ctx.json({key: key, content: content});
|
39
|
+
return ctx.json(200, {key: key, content: content});
|
40
40
|
});
|
41
41
|
|
42
42
|
r.add('/api/get/all', 'GET', ctx => {
|
43
|
-
return ctx.json(todo.export());
|
43
|
+
return ctx.json(200, todo.export());
|
44
44
|
});
|
45
45
|
|
46
46
|
r.serve();
|
@@ -1,23 +1,23 @@
|
|
1
1
|
import { httpStatusCodes } from "./status";
|
2
2
|
|
3
3
|
const http = {
|
4
|
-
json: async (data: any): Promise<Response> => {
|
4
|
+
json: async (statusCode: number, data: any): Promise<Response> => {
|
5
5
|
const jsonString = JSON.stringify(data);
|
6
6
|
return Promise.resolve(new Response(jsonString, {
|
7
|
-
status:
|
8
|
-
statusText: httpStatusCodes[
|
7
|
+
status: statusCode,
|
8
|
+
statusText: httpStatusCodes[statusCode],
|
9
9
|
headers: {'Content-Type': 'application/json'},
|
10
10
|
}));
|
11
11
|
},
|
12
|
-
html: async (content: string): Promise<Response> => {
|
12
|
+
html: async (statusCode: number, content: string): Promise<Response> => {
|
13
13
|
content = Bun.escapeHTML(content);
|
14
14
|
return Promise.resolve(new Response(Bun.escapeHTML(content), {
|
15
|
-
status:
|
16
|
-
statusText: httpStatusCodes[
|
15
|
+
status: statusCode,
|
16
|
+
statusText: httpStatusCodes[statusCode],
|
17
17
|
headers: {'Content-Type': 'text/html; charset=utf-8'}
|
18
18
|
}));
|
19
19
|
},
|
20
|
-
file: async (fp: string): Promise<Response> => {
|
20
|
+
file: async (statusCode: number, fp: string): Promise<Response> => {
|
21
21
|
const file = Bun.file(fp);
|
22
22
|
const exists = await file.exists();
|
23
23
|
|
@@ -32,8 +32,8 @@ const http = {
|
|
32
32
|
contentType = file.type + '; charset=utf-8';
|
33
33
|
|
34
34
|
return Promise.resolve(new Response(content, {
|
35
|
-
status:
|
36
|
-
statusText: httpStatusCodes[
|
35
|
+
status: statusCode,
|
36
|
+
statusText: httpStatusCodes[statusCode],
|
37
37
|
headers: { 'Content-Type': contentType}
|
38
38
|
}));
|
39
39
|
},
|
@@ -57,8 +57,7 @@ const http = {
|
|
57
57
|
headers: {'Content-Type': 'text/html; charset-utf-8'},
|
58
58
|
});
|
59
59
|
return Promise.resolve(response)
|
60
|
-
}
|
61
|
-
|
60
|
+
},
|
62
61
|
}
|
63
62
|
|
64
63
|
export { http }
|
package/lib/router/router.d.ts
CHANGED
@@ -4,14 +4,18 @@ import { Database } from 'bun:sqlite';
|
|
4
4
|
|
5
5
|
|
6
6
|
type Context = {
|
7
|
+
cookies: Map<string, string>,
|
8
|
+
db: Database,
|
9
|
+
formData: FormData | Promise<FormData> | undefined,
|
10
|
+
json: (statusCode: number, data: any) => Response | Promise<Response>,
|
11
|
+
logger: Logger,
|
12
|
+
params: Map<string, string>,
|
13
|
+
query: URLSearchParams,
|
7
14
|
request: Request,
|
8
15
|
route: Route,
|
9
|
-
params: Map<string, string>,
|
10
16
|
token?: string,
|
11
|
-
|
12
|
-
|
13
|
-
json: (data: any) => Response | Promise<Response>,
|
14
|
-
}
|
17
|
+
};
|
18
|
+
|
15
19
|
|
16
20
|
type Route = {
|
17
21
|
pattern: string,
|
@@ -39,4 +43,5 @@ type Router = (port?: number | string, options?: RouterOptions) => {
|
|
39
43
|
}
|
40
44
|
|
41
45
|
|
46
|
+
|
42
47
|
export { Context , Route, Router, RouterOptions, Options }
|
package/lib/router/router.ts
CHANGED
@@ -48,20 +48,24 @@ const match = (route: Route, ctx: Context): boolean => {
|
|
48
48
|
|
49
49
|
// set the context for the reuest
|
50
50
|
const setContext = (req: Request, lgr: Logger, opts: Options, route: Route): Context => {
|
51
|
+
const token = req.headers.get('Authorization');
|
51
52
|
return {
|
53
|
+
token: token ?? '',
|
54
|
+
cookies: new Map(),
|
55
|
+
formData: req.formData(),
|
52
56
|
request: req,
|
53
57
|
params: new Map(),
|
58
|
+
query: new URL(req.url).searchParams,
|
54
59
|
db: new Database(opts.db ?? ':memory:'),
|
55
60
|
logger: lgr,
|
56
61
|
route: route,
|
57
|
-
json: (data: any) => http.json(data),
|
62
|
+
json: (statusCode: number, data: any) => http.json(statusCode, data),
|
58
63
|
}
|
59
64
|
}
|
60
65
|
|
61
66
|
const router: Router = (port?: number | string, options?: RouterOptions<Options>) => {
|
62
67
|
const routes: Array<Route> = new Array();
|
63
68
|
const lgr = logger();
|
64
|
-
let dbConn = '';
|
65
69
|
|
66
70
|
return {
|
67
71
|
// add a new route
|
@@ -105,7 +109,7 @@ const router: Router = (port?: number | string, options?: RouterOptions<Options>
|
|
105
109
|
const route: Route = {
|
106
110
|
pattern: patternPath,
|
107
111
|
method: 'GET',
|
108
|
-
callback: async () => await http.file(pure),
|
112
|
+
callback: async () => await http.file(200, pure),
|
109
113
|
};
|
110
114
|
|
111
115
|
routes.push(route);
|
@@ -135,18 +139,29 @@ const router: Router = (port?: number | string, options?: RouterOptions<Options>
|
|
135
139
|
if (match(route, ctx) || route.pattern === url.pathname) {
|
136
140
|
if (route.method === ctx.request.method) {
|
137
141
|
const res = await route.callback(ctx);
|
142
|
+
|
143
|
+
let cookieValue: string[] = [];
|
144
|
+
if (ctx.cookies.size !== 0) {
|
145
|
+
for (const [key, value] of ctx.cookies) {
|
146
|
+
cookieValue.push(`${key}=${value}`);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
res.headers.set('Set-Cookie', cookieValue.join('; '));
|
151
|
+
|
138
152
|
statusCode = res.status;
|
153
|
+
|
139
154
|
lgr.info(res.status, route.pattern, req.method, httpStatusCodes[res.status]);
|
140
155
|
return Promise.resolve(res);
|
141
156
|
} else {
|
142
157
|
const res = new Response(httpStatusCodes[405], {
|
143
158
|
status: 405,
|
144
|
-
statusText: httpStatusCodes[
|
159
|
+
statusText: httpStatusCodes[405]
|
145
160
|
});
|
146
161
|
lgr.info(405, route.pattern, req.method, httpStatusCodes[405])
|
147
162
|
return Promise.resolve(res);
|
148
163
|
}
|
149
|
-
}
|
164
|
+
}
|
150
165
|
}
|
151
166
|
|
152
167
|
lgr.info(statusCode, url.pathname, req.method, httpStatusCodes[statusCode]);
|
package/package.json
CHANGED