bun-router 0.3.1 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,8 +29,6 @@ import {router, html, json } from 'bun-router';
29
29
 
30
30
  const r = router(3001);
31
31
 
32
- r.static('/assets', './assets');
33
-
34
32
  r.add('/', (ctx) => html('<h1>Hello World</h1>'));
35
33
 
36
34
  r.add('/greeting/:name', 'GET', (ctx) => {
@@ -0,0 +1,16 @@
1
+ import { router, logger, json, html } from '..';
2
+
3
+ const r = router();
4
+ const log = logger();
5
+
6
+ r.add('/:foo', 'GET', (ctx) => {
7
+ const url = new URL(ctx.request.url);
8
+ const foo = ctx.params.get('foo');
9
+ if (!foo) {
10
+ log.error(500, url.pathname, ctx.request.method, new Error('undefined'));
11
+ return json({status: 500, text: 'Foo is undefined'});
12
+ }
13
+ return html(`<h4 style='font-family: sans-serif;'>Oh hello, ${foo}</h4>`)
14
+ });
15
+
16
+ r.serve();
Binary file
package/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './lib/router/router';
2
- export * from './lib/fs/fsys';
2
+ export * from './lib/fs/fsys';
3
+ export * from './lib/logger/logger';
@@ -0,0 +1,36 @@
1
+ const Colors: Record<string,string> = {
2
+ reset: "\x1b[0m",
3
+
4
+ // foreground
5
+ black: "\x1b[30m",
6
+ red: "\x1b[31m",
7
+ green: "\x1b[32m",
8
+ yellow: "\x1b[33m",
9
+ blue: "\x1b[34m",
10
+ magenta: "\x1b[35m",
11
+ cyan: "\x1b[36m",
12
+ white: "\x1b[37m",
13
+
14
+ // background
15
+ bgBlack: "\x1b[40m",
16
+ bgRed: "\x1b[41m",
17
+ bgGreen: "\x1b[42m",
18
+ bgYellow: "\x1b[43m",
19
+ bgBlue: "\x1b[44m",
20
+ bgMagenta: "\x1b[45m",
21
+ bgCyan: "\x1b[46m",
22
+ bgWhite: "\x1b[47m",
23
+ };
24
+
25
+
26
+ const color = (c: string, bkg: string, msg: string) => {
27
+ const foreground = Colors[c];
28
+ const background = Colors[bkg];
29
+ const reset = Colors.reset;
30
+
31
+ return `${foreground}${background}${msg}${reset}`;
32
+ };
33
+
34
+
35
+
36
+ export { color }
@@ -0,0 +1,8 @@
1
+ type Logger = {
2
+ start: (port: number | string) => void,
3
+ info: (statusCode: number, routePath: string, method: string, message?: string) => void,
4
+ error: (statusCode: number, routePath: string, method: string, error: Error) => void,
5
+ warn: (msg: string) => void,
6
+ }
7
+
8
+ export { Logger }
@@ -0,0 +1,80 @@
1
+ import { color } from './color';
2
+ import {Logger} from './logger.d';
3
+
4
+ const pad = (n: number) => String(n).padStart(2, '0');
5
+
6
+ const timestamp = (date: Date) => {
7
+ const month = pad(date.getMonth());
8
+ const day = pad(date.getDate());
9
+ const hour = pad(date.getHours());
10
+ const minute = pad(date.getMinutes());
11
+ const seconds = pad(date.getSeconds());
12
+ const stamp = `${hour}:${minute}:${seconds}`;
13
+
14
+ return {month, day, hour, minute, stamp};
15
+ }
16
+
17
+ const colorCode = (n: number, text?:string): string => {
18
+ const s = ` [${String(n)}${text ?? ''}] `;
19
+ if (n < 100) return color('black', 'bgYellow', s);
20
+ else if (n >= 100 && n < 200) return color('black', 'bgCyan', s);
21
+ else if (n >= 200 && n < 300) return color('black', 'bgGreen', s);
22
+ else if (n >= 300 && n < 400) return color('black', 'bgRed', s);
23
+ else if (n >= 400 && n < 500) return color('black', 'bgRed', s);
24
+ else if (n >= 500) return color('white', 'bgRed', s);
25
+ return color('white', 'bgBlack', `[${s}]`).trim();
26
+ }
27
+
28
+ const clean = (s: string) => s.replace(/\x1B\[\d{1,2}(;\d{1,2}){0,2}m/g, '');
29
+
30
+ const format = (statusCode: number, routePath: string, method: string, message?: string): string => {
31
+ const { stamp } = timestamp((new Date(Date.now())));
32
+ const source = color('green', 'bgBlack', `[bun-router ${stamp}]`);
33
+ const rp = color('white', 'bgBlack', routePath);
34
+
35
+ return `${source} : ${colorCode(statusCode)} : ${rp} ${(method === 'GET') ? '->' : '<-'} ${method}\n`
36
+ }
37
+
38
+ const logger = (): Logger => {
39
+ const messages: string[] = [];
40
+ const errors: string[] = [];
41
+ return {
42
+ start: async (port: number | string) => {
43
+ const { stamp } = timestamp((new Date(Date.now())));
44
+ const source = color('green', 'bgBlack', `[bun-router ${stamp}]`)
45
+ const portColor = color('green', 'bgBlack', String(port));
46
+ const msg = `${source}: Starting Server on :${portColor}\n`;
47
+
48
+ await Bun.write(Bun.stdout, msg);
49
+ },
50
+ info: async (statusCode: number, routePath: string, method: string, message?: string) => {
51
+ const { stamp } = timestamp((new Date(Date.now())));
52
+ const source = color('green', 'bgBlack', `[bun-router ${stamp}]`);
53
+ const rp = color('white', 'bgBlack', routePath);
54
+ const msg = `${source}: ${colorCode(statusCode)}: ${rp} ${(method === 'GET') ? '->' : '<-'} ${method}\n`
55
+
56
+ await Bun.write(Bun.stdout, msg);
57
+
58
+ messages.push(clean(msg));
59
+ },
60
+ error: async (statusCode: number, routePath: string, method: string, error: Error) => {
61
+ const { stamp } = timestamp((new Date(Date.now())));
62
+ const source = color('black', 'bgRed', `[error ${stamp}]`);
63
+ const rp = color('white', 'bgBlack', routePath);
64
+ const msg = `${source}: ${colorCode(statusCode)}: ${rp} ${(method === 'GET') ? '->' : '<-'} ${error.message}\n`;
65
+
66
+ await Bun.write(Bun.stdout, msg);
67
+
68
+ errors.push(clean(msg));
69
+ },
70
+ warn: async (msg: string) => {
71
+ const { stamp } = timestamp((new Date(Date.now())));
72
+ const source = color('black', 'bgYellow', `[warning ${stamp}]`);
73
+ const msgColor = color('yellow', 'bgBlack', msg);
74
+ msg = `${source} : ${msgColor}\n`;
75
+ await Bun.write(Bun.stdout, msg);
76
+ }
77
+ }
78
+ }
79
+
80
+ export { logger }
@@ -1,5 +1,6 @@
1
1
  import { Route, Router, Context, Options } from './router.d';
2
2
  import { readDir } from '../fs/fsys';
3
+ import { logger } from '../logger/logger';
3
4
  import path from 'path';
4
5
 
5
6
  const notFound = async (): Promise<Response> => {
@@ -14,6 +15,17 @@ const notFound = async (): Promise<Response> => {
14
15
  });
15
16
  }
16
17
 
18
+ const noContent = async (): Promise<Response> => {
19
+ const response = new Response('no content', {
20
+ status: 204,
21
+ statusText: 'no content',
22
+ });
23
+
24
+ return new Promise((resolve) => {
25
+ resolve(response);
26
+ });
27
+ }
28
+
17
29
  const file = async (filepath: string): Promise<Response> => {
18
30
  const file = Bun.file(filepath);
19
31
  const exists = await file.exists();
@@ -93,6 +105,7 @@ const match = (route: Route, ctx: Context): boolean => {
93
105
  const router: Router = (port?: number | string, options?: Options) => {
94
106
  const routes: Array<Route> = new Array();
95
107
  const paths: { [key: string]: string } = {};
108
+ const lgr = logger();
96
109
 
97
110
  return {
98
111
  add: (pattern: string, method: string, callback: (ctx: Context) => Response | Promise<Response>) => {
@@ -129,11 +142,12 @@ const router: Router = (port?: number | string, options?: Options) => {
129
142
  });
130
143
  },
131
144
  serve: () => {
132
- console.log(`[bun-router]: Listening on port -> :${port ?? 3000}`)
145
+ lgr.start(port ?? 3000);
133
146
  Bun.serve({
134
147
  port: port ?? 3000,
135
148
  ...options,
136
149
  fetch(req) {
150
+ const url = new URL(req.url);
137
151
  for (const route of routes) {
138
152
  const ctx: Context = {
139
153
  request: req,
@@ -145,9 +159,14 @@ const router: Router = (port?: number | string, options?: Options) => {
145
159
 
146
160
  extractor?.params();
147
161
 
148
- if (match(route, ctx))
162
+ if (url.pathname === '/favicon.ico') return noContent();
163
+
164
+ if (match(route, ctx)) {
165
+ lgr.info(200, route.pattern, route.method)
149
166
  return route.callback(ctx);
167
+ }
150
168
  }
169
+ lgr.info(404, url.pathname, req.method, 'not found');
151
170
  return new Response('not found');
152
171
  }
153
172
  });
package/package.json CHANGED
@@ -8,5 +8,5 @@
8
8
  "peerDependencies": {
9
9
  "typescript": "^5.0.0"
10
10
  },
11
- "version": "0.3.1"
11
+ "version": "0.3.4"
12
12
  }
@@ -1,6 +1,8 @@
1
1
  import { describe, test, expect } from 'bun:test';
2
2
  import { router, extract } from '..';
3
3
  import { Context, Route } from '../lib/router/router.d';
4
+ import { logger } from '../lib/logger/logger';
5
+ import { color } from '../lib/logger/color';
4
6
 
5
7
  describe('URL Params', () => {
6
8
  test('/user/:name', () => {
@@ -98,4 +100,4 @@ describe('Router', () => {
98
100
 
99
101
  proc.kill(0);
100
102
  });
101
- });
103
+ });
@@ -46,7 +46,10 @@ function run_test() {
46
46
  echo "Failed: $url returned $actual | expected: $expected"
47
47
  fi
48
48
 
49
- rm "$name"
49
+ if does_exist "$name"; then
50
+ rm "$name"
51
+ fi
52
+
50
53
  }
51
54
 
52
55
  for expected in "${!test_cases[@]}"; do