bun-router 0.2.8 → 0.3.0

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
@@ -3,96 +3,55 @@
3
3
  I needed a router for `Bun`, so I made one. It's simple, naive, and hardly anything is abstracted.
4
4
 
5
5
  ### Usage
6
- Import the `router`.
7
6
  ```typescript
8
7
  import { router } from 'bun-router';
9
- ```
10
-
11
- Create the `router`.
12
- ```typescript
13
- const r = router(3000)
14
- ```
15
-
16
- Add routes to the `router`.
17
- ```typescript
18
- r.add('/', 'GET', req => new Response('Hello World'));
19
- ```
20
-
21
- The `req` parameter is of type `HttpRequest` which is just a type that contains both `Response` and `Params` for URL parameters.
22
-
23
- Start the server.
24
- ```typescript
25
- r.serve()
26
- ```
27
-
28
- Some overly-simple examples:
29
- ```typescript
30
- import { router, json } from '..';
31
8
 
32
9
  const r = router();
33
10
 
34
- const pets = {
35
- dogs: ['Joey', 'Benny', 'Max'],
36
- cats: ['Charles', 'Arya', 'Binx'],
37
- }
38
-
39
- const foods = {
40
- apple: '🍎', banana: '🍌', strawberry: '🍓', pear: '🍐',
41
- }
42
-
43
- r.add('/pets/:type', 'GET', req => {
44
- const petType = req.params.get('type') as keyof typeof pets;
45
- return json(pets[petType] ?? 'not found');
46
- });
47
- r.add('/grocery/:food', 'GET', req => {
48
- const food = req.params.get('food') as keyof typeof foods
49
- return json(foods[food] ?? 'not found')
50
- });
11
+ r.add('/', 'GET', (ctx) => new Response('Hello World'));
51
12
 
52
13
  r.serve();
53
14
  ```
54
-
15
+ #### Static Files
55
16
  ```typescript
56
- import { router, json } from "..";
17
+ import { router } from 'bun-router';
57
18
 
58
19
  const r = router();
59
20
 
21
+ r.static('/', './pages');
60
22
 
61
- const cacher = () => {
62
- const cache = new Map();
63
- return {
64
- set: (key: string, value: string) => {
65
- cache.set(key, value);
66
- },
67
- get: (key: string) => cache.get(key)!,
68
- }
69
- }
23
+ r.serve();
24
+ ```
70
25
 
71
- const cache = cacher();
26
+ ##### Example
27
+ ```typescript
28
+ import {router, html, json } from 'bun-router';
72
29
 
73
- const rand = (max: number) => Math.floor(Math.random() * max);
30
+ const r = router(3001);
74
31
 
75
- r.add('/set', 'POST', req => {
76
- const url = new URL(req.request.url);
77
- const query = url.searchParams;
32
+ r.static('/assets', './assets');
78
33
 
79
- const name = query.get('name')!;
34
+ r.add('/', (ctx) => html('<h1>Hello World</h1>'));
80
35
 
81
- cache.set(name, `${rand(1000)}`)
36
+ r.add('/greeting/:name', 'GET', (ctx) => {
37
+ const name = ctx.params.get('name');
38
+ if (!name) return new Response('invalid url parameters', {status: 400});
82
39
 
83
- return new Response('thank you for joining\n');
40
+ return html(`<h4>Greetings, ${name}!</h4>`);
84
41
  });
85
42
 
86
- r.add('/get/:key', 'GET', req => {
87
- const name = req.params.get('key')
88
- const result = cache.get(name ?? '');
43
+ const store: Map<string, string> = new Map();
89
44
 
90
- if (!result) return new Response('not found')
45
+ r.add('/user/:id', 'GET', (ctx) => {
46
+ const id = ctx.params.get('id');
47
+ if (!id) return new Response('user not found', {status: 404});
91
48
 
92
- return json(`Welcome user ID: ${result}`)
49
+ const user = store.get(id);
93
50
 
51
+ if (!user) return new Response('user not found', { status: 404 });
52
+
53
+ return json(user);
94
54
  });
95
55
 
96
56
  r.serve();
97
- ```
98
-
57
+ ```
@@ -0,0 +1,18 @@
1
+ import { router, html, json } from '..';
2
+
3
+ const r = router();
4
+
5
+ r.add('/', 'GET', () => json('ok'));
6
+
7
+ r.add('/user/:name', 'GET', (ctx) => {
8
+ const name = ctx.params.get('name');
9
+ return json(name);
10
+ });
11
+
12
+ r.add('/user/:name/:id', 'GET', (ctx) => {
13
+ const name = ctx.params.get('name');
14
+ const id = ctx.params.get('id');
15
+ return json({name: name, id: id});
16
+ });
17
+
18
+ r.serve();
Binary file
Binary file
@@ -0,0 +1,6 @@
1
+ import { router } from '..';
2
+
3
+ const r = router(3001);
4
+
5
+ r.static('/', './examples/pages');
6
+ r.serve();
package/index.ts CHANGED
@@ -1 +1,2 @@
1
- export * from './lib/router/router';
1
+ export * from './lib/router/router';
2
+ export * from './lib/fs/fsys';
package/lib/fs/fsys.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { BunFile } from "bun";
2
+ import fs from 'node:fs/promises';
3
+ import path from 'path';
4
+
5
+ const isDir = async (fp: string): Promise<boolean> => (await fs.lstat(fp)).isDirectory();
6
+
7
+ const readDir = async (dirpath: string, handler: (filepath: string, entry: BunFile) => void) => {
8
+ try {
9
+ const files = await fs.readdir(dirpath);
10
+
11
+ for (const file of files) {
12
+ const bunFile = Bun.file(file);
13
+ const fp = path.join(dirpath, bunFile.name!);
14
+ const isdir = await isDir(fp);
15
+
16
+ if (isdir) await readDir(fp, handler);
17
+ else handler(fp, bunFile);
18
+ }
19
+ } catch (err) {
20
+ console.error(err);
21
+ }
22
+ }
23
+
24
+ export { readDir }
@@ -1,15 +1,17 @@
1
1
  import { TLSOptions, TLSWebSocketServeOptions, WebSocketServeOptions, ServeOptions, TLSServeOptions } from 'bun';
2
2
 
3
3
 
4
- type HttpRequest = {
4
+ type Context = {
5
5
  request: Request,
6
6
  params: Map<string, string>,
7
+ fs: Map<string, string>,
8
+ token?: string,
7
9
  }
8
10
 
9
11
  type Route = {
10
12
  pattern: string,
11
13
  method: string,
12
- callback: (req: HttpRequest) => Response | Promise<Response>
14
+ callback: (req: Context) => Response | Promise<Response>
13
15
  }
14
16
 
15
17
  type Options = ServeOptions
@@ -20,9 +22,10 @@ type Options = ServeOptions
20
22
 
21
23
 
22
24
  type Router = (port?: number | string, options?: Options) => {
23
- add: (pattern: string, method: string, callback: (req: HttpRequest) => Response | Promise<Response>) => void,
25
+ add: (pattern: string, method: string, callback: (req: Context) => Response | Promise<Response>) => void,
26
+ static: (pattern: string, root: string) => void,
24
27
  serve: () => void,
25
28
  }
26
29
 
27
30
 
28
- export { HttpRequest, Route, Router, Options }
31
+ export { Context , Route, Router, Options }
@@ -1,4 +1,6 @@
1
- import { Route, Router, HttpRequest, Options } from './router.d';
1
+ import { Route, Router, Context, Options } from './router.d';
2
+ import { readDir } from '../fs/fsys';
3
+ import path from 'path';
2
4
 
3
5
  const notFound = async (): Promise<Response> => {
4
6
  const response = new Response('not found', {
@@ -19,14 +21,20 @@ const file = async (filepath: string): Promise<Response> => {
19
21
  if (!exists)
20
22
  return notFound();
21
23
 
22
- const content = await file.text();
23
- if (content === '')
24
+ const content = await file.arrayBuffer();
25
+ if (!content)
24
26
  return notFound();
25
27
 
28
+ let contentType = 'text/html; charset=utf-8';
29
+
30
+ if (file.type.includes('image')) {
31
+ contentType = file.type + '; charset=utf-8';
32
+ }
33
+
26
34
  const response = new Response(content, {
27
35
  status: 200,
28
36
  statusText: 'ok',
29
- headers: { 'Content-Type': 'text/html; charset=utf-8' },
37
+ headers: { 'Content-Type': contentType },
30
38
  });
31
39
 
32
40
  return new Promise<Response>((resolve) => {
@@ -38,8 +46,9 @@ const html = async (content: string): Promise<Response> => {
38
46
  const response = new Response(content, {
39
47
  status: 200,
40
48
  statusText: 'ok',
41
- headers: {'Content-Type': 'text/html; charset=utf-8'},
49
+ headers: { 'Content-Type': 'text/html; charset=utf-8' },
42
50
  });
51
+ content = Bun.escapeHTML(content);
43
52
 
44
53
  return new Promise<Response>((resolve) => {
45
54
  resolve(response);
@@ -55,57 +64,94 @@ const json = (data: any): Response => {
55
64
  return res
56
65
  }
57
66
 
58
- const extractParams = (route: Route, req: HttpRequest) => {
59
- const url = new URL(req.request.url);
67
+ const extract = (route: Route, ctx: Context) => {
68
+ const url = new URL(ctx.request.url);
60
69
  const pathSegments = route.pattern.split('/');
61
70
  const urlSegments = url.pathname.split('/');
62
71
 
63
72
  if (pathSegments.length !== urlSegments.length) return
64
73
 
65
- for (let i = 0; i < pathSegments.length; i++) {
66
- if ((pathSegments[i][0] === ':') && (pathSegments[i - 1] === urlSegments[i - 1])) {
67
- const k = pathSegments[i].replace(':', '');
68
- const v = urlSegments[i];
69
- req.params.set(k, v);
74
+
75
+ return {
76
+ params: () => {
77
+ for (let i = 0; i < pathSegments.length; i++) {
78
+ if ((pathSegments[i][0] === ':')) {
79
+ const k = pathSegments[i].replace(':', '');
80
+ const v = urlSegments[i];
81
+ ctx.params.set(k, v);
82
+ }
83
+ }
70
84
  }
71
85
  }
86
+
72
87
  }
73
88
 
74
- const match = (route: Route, req: HttpRequest): boolean => {
75
- return req.params.size !== 0 || route.pattern === (new URL(req.request.url)).pathname
89
+ const match = (route: Route, ctx: Context): boolean => {
90
+ return ctx.params.size !== 0 || route.pattern === (new URL(ctx.request.url)).pathname
76
91
  }
77
92
 
78
93
  const router: Router = (port?: number | string, options?: Options) => {
79
94
  const routes: Array<Route> = new Array();
95
+ const paths: { [key: string]: string } = {};
80
96
 
81
97
  return {
82
- add: (pattern: string, method: string, callback: (req: HttpRequest) => Response | Promise<Response>) => {
98
+ add: (pattern: string, method: string, callback: (ctx: Context) => Response | Promise<Response>) => {
83
99
  routes.push({
84
100
  pattern: pattern,
85
101
  method: method,
86
102
  callback: callback,
87
103
  })
88
104
  },
105
+ static: async (pattern: string, root: string) => {
106
+ await readDir(root, async (fp, _) => {
107
+ const pure = path.join('.', fp);
108
+ const ext = path.extname(pure);
109
+
110
+ let base = path.basename(pure);
111
+
112
+ if (ext === '.html') {
113
+ base = base.replace(ext, '');
114
+
115
+ }
116
+
117
+ console.log((pattern[0] != '/'))
118
+ if (pattern[0] !== '/') pattern = '/' + pattern;
119
+
120
+ let patternPath = pattern + base;
121
+
122
+ if (base === 'index') patternPath = pattern;
123
+
124
+ console.log(patternPath);
125
+
126
+ const route: Route = {
127
+ pattern: patternPath,
128
+ method: 'GET',
129
+ callback: async () => await file(pure),
130
+ };
131
+ routes.push(route);
132
+ });
133
+ console.log(routes.length);
134
+
135
+ },
89
136
  serve: () => {
90
- console.log(`[bun-router]: Listening on port -> :${ port ?? 3000 }`)
137
+ console.log(`[bun-router]: Listening on port -> :${port ?? 3000}`)
91
138
  Bun.serve({
92
139
  port: port ?? 3000,
93
140
  ...options,
94
141
  fetch(req) {
95
- const url = new URL(req.url);
96
142
  for (const route of routes) {
97
- const httpRequest: HttpRequest = {
143
+ const ctx: Context = {
98
144
  request: req,
99
145
  params: new Map(),
146
+ fs: new Map(),
100
147
  };
101
148
 
102
- extractParams(route, httpRequest);
103
-
104
- if (match(route, httpRequest))
105
- return route.callback(httpRequest);
149
+ const extractor = extract(route, ctx);
106
150
 
151
+ extractor?.params();
107
152
 
108
- if (match(route, httpRequest)) return route.callback(httpRequest);
153
+ if (match(route, ctx))
154
+ return route.callback(ctx);
109
155
  }
110
156
  return new Response('not found');
111
157
  }
@@ -114,4 +160,4 @@ const router: Router = (port?: number | string, options?: Options) => {
114
160
  }
115
161
  }
116
162
 
117
- export { router, json, file, extractParams, html }
163
+ export { router, json, file, extract, html }
package/package.json CHANGED
@@ -8,5 +8,5 @@
8
8
  "peerDependencies": {
9
9
  "typescript": "^5.0.0"
10
10
  },
11
- "version": "0.2.8"
11
+ "version": "0.3.0"
12
12
  }
@@ -1,47 +1,101 @@
1
1
  import { describe, test, expect } from 'bun:test';
2
- import { file, json, extractParams } from '..';
3
- import { HttpRequest, Route } from '../lib/router/router.d';
4
-
5
- describe('Helpers', async () => {
6
- test('html', async () => {
7
- const fp = './examples/pages/index.html';
8
- const res = await file(fp);
9
- const contentType = res.headers.get('Content-Type');
10
-
11
- expect(contentType).toBe('text/html; charset=utf-8');
12
- expect(res.status).toBe(200);
13
- });
2
+ import { router, extract } from '..';
3
+ import { Context, Route } from '../lib/router/router.d';
14
4
 
15
- test('json', async () => {
16
- const test = { message: 'ok' }
17
- const res = await json(test);
18
- const jsn = await res.json();
5
+ describe('URL Params', () => {
6
+ test('/user/:name', () => {
7
+ const route: Route = {
8
+ pattern: '/user/:name',
9
+ method: 'GET',
10
+ callback: () => new Response('ok'),
11
+ };
12
+
13
+ const ctx: Context = {
14
+ request: new Request('http://localhost:3000/user/foo'),
15
+ params: new Map(),
16
+ fs: new Map(),
17
+ };
19
18
 
20
- expect(jsn).toStrictEqual({ message: 'ok' })
19
+ const extractor = extract(route, ctx);
21
20
 
21
+ extractor?.params();
22
+
23
+ const name = ctx.params.get('name');
24
+ expect(name).toBe('foo');
22
25
  });
23
26
 
24
- test('extract params 1', () => {
25
- const route: Route = {pattern: '/:name', method: 'GET', callback: (req) => new Response('ok')};
26
- const httpRequest: HttpRequest = {
27
- request: new Request('http://localhost:3000/foo'),
27
+ test('/user/:name/:id', () => {
28
+ const route: Route = {
29
+ pattern: '/user/:name/:id',
30
+ method: 'GET',
31
+ callback: () => new Response('ok'),
32
+ };
33
+
34
+ const ctx: Context = {
35
+ request: new Request('http://localhost:3000/user/foo/123'),
28
36
  params: new Map(),
29
- }
37
+ fs: new Map(),
38
+ };
39
+
40
+ const extractor = extract(route, ctx);
41
+
42
+ extractor?.params();
43
+
44
+ const name = ctx.params.get('name');
45
+ const id = ctx.params.get('id');
30
46
 
31
- extractParams(route, httpRequest);
32
- const name = httpRequest.params.get('name');
33
47
  expect(name).toBe('foo');
48
+ expect(id).toBe('123');
34
49
  });
35
50
 
36
- test('extract params 2', () =>{
37
- const route: Route = {pattern: '/foo/:name', method: 'GET', callback: (req) => new Response('ok')};
38
- const httpRequest: HttpRequest = {
39
- request: new Request('http://localhost:3000/foo/bar'),
51
+ test('/foo', () => {
52
+ const route: Route = {
53
+ pattern: '/foo',
54
+ method: 'GET',
55
+ callback: () => new Response('ok'),
56
+ }
57
+
58
+ const ctx: Context = {
59
+ request: new Request('http://localhost:3000/foo'),
40
60
  params: new Map(),
61
+ fs: new Map(),
41
62
  }
42
63
 
43
- extractParams(route, httpRequest);
44
- const name = httpRequest.params.get('name');
45
- expect(name).toBe('bar');
64
+ const url = new URL(ctx.request.url);
65
+
66
+ expect(url.pathname).toBe(route.pattern);
67
+ });
68
+ });
69
+
70
+ describe('Router', () => {
71
+ test('Serve', async () => {
72
+ const proc = Bun.spawn(['./tests/serve.test.sh'], {
73
+ onExit: (proc, exitCode, signalCode , error) => {
74
+ if (error) console.error(error);
75
+ },
76
+ });
77
+
78
+ const text = await new Response(proc.stdout).text();
79
+
80
+ const hasFailed = text.includes('Failed');
81
+
82
+ if (hasFailed) console.log(text);
83
+
84
+ expect(hasFailed).toBe(false);
85
+
86
+ proc.kill(0);
87
+ })
88
+
89
+ test('Static', async() => {
90
+ const proc = Bun.spawn(['./tests/static.test.sh']);
91
+
92
+ const text = await new Response(proc.stdout).text();
93
+
94
+ const hasFailed = text.includes('Failed');
95
+ if (hasFailed) console.log(text);
96
+
97
+ expect(hasFailed).toBe(false);
98
+
99
+ proc.kill(0);
46
100
  });
47
101
  });
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+
3
+ bun run ./examples/basic.ts &
4
+ SERVER_PID=$!
5
+
6
+ function stop_server {
7
+ kill $SERVER_PID
8
+ }
9
+
10
+ trap stop_server EXIT
11
+
12
+ sleep .1
13
+
14
+ declare -A test_cases
15
+ test_cases['"ok"']="http://localhost:3000/"
16
+ test_cases['"baz"']="http://localhost:3000/user/baz"
17
+
18
+ function run_test() {
19
+ local expected_response="$1"
20
+ local url="$2"
21
+
22
+ actual_response=$(curl -sS "$url")
23
+
24
+ if [[ "$actual_response" == "$expected_response" ]]; then
25
+ echo "Passed."
26
+ else
27
+ echo "Failed: $url returned $actual_response : $expected_response"
28
+ fi
29
+ }
30
+
31
+ for expected in "${!test_cases[@]}"; do
32
+ url="${test_cases[$expected]}"
33
+ run_test "$expected" "$url"
34
+ done
35
+
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+
3
+ bun run ./examples/static.ts &
4
+ SERVER_PID=$!
5
+
6
+ function stop_server {
7
+ kill $SERVER_PID
8
+ }
9
+
10
+ trap stop_server EXIT
11
+
12
+ sleep .1
13
+
14
+ index=$(<./examples/pages/index.html)
15
+ vader=$(md5sum ./examples/pages/vader.jpg | awk '{print $1}')
16
+ gopher=$(md5sum ./examples/pages/gopher.png | awk '{print $1}')
17
+
18
+ declare -A test_cases
19
+ test_cases["$index"]="http://localhost:3001/"
20
+ test_cases["$vader"]="http://localhost:3001/vader.jpg"
21
+ test_cases["$gopher"]="http://localhost:3001/gopher.png"
22
+
23
+ function does_exist() {
24
+ if [ ! -f "$1" ]; then
25
+ echo "Error: File '$1' not found."
26
+ exit 1
27
+ fi
28
+ }
29
+
30
+ function run_test() {
31
+ local expected="$1"
32
+ local url="$2"
33
+ local actual=""
34
+
35
+ if [[ "$url" == *".jpg"* ]] || [[ "$url" == *".png"* ]]; then
36
+ name="${url//[^[:alnum:]. ]}"
37
+ curl -sSo "$name" "$url"
38
+ actual=$(md5sum "$name" | awk '{print $1}')
39
+ else
40
+ actual=$(curl -sS "$url")
41
+ fi
42
+
43
+ if [ "$actual" == "$expected" ]; then
44
+ echo "Passed."
45
+ else
46
+ echo "Failed: $url returned $actual | expected: $expected"
47
+ fi
48
+
49
+ rm "$name"
50
+ }
51
+
52
+ for expected in "${!test_cases[@]}"; do
53
+ url="${test_cases[$expected]}"
54
+ run_test "$expected" "$url"
55
+ done
package/examples/cache.ts DELETED
@@ -1,41 +0,0 @@
1
- import { router, json } from "..";
2
-
3
- const r = router();
4
-
5
-
6
- const cacher = () => {
7
- const cache = new Map();
8
- return {
9
- set: (key: string, value: string) => {
10
- cache.set(key, value);
11
- },
12
- get: (key: string) => cache.get(key)!,
13
- }
14
- }
15
-
16
- const cache = cacher();
17
-
18
- const rand = (max: number) => Math.floor(Math.random() * max);
19
-
20
- r.add('/set', 'POST', req => {
21
- const url = new URL(req.request.url);
22
- const query = url.searchParams;
23
-
24
- const name = query.get('name')!;
25
-
26
- cache.set(name, `${rand(1000)}`)
27
-
28
- return new Response('thank you for joining\n');
29
- });
30
-
31
- r.add('/get/:key', 'GET', req => {
32
- const name = req.params.get('key')
33
- const result = cache.get(name ?? '');
34
-
35
- if (!result) return new Response('not found')
36
-
37
- return json(`Welcome user ID: ${result}`)
38
-
39
- });
40
-
41
- r.serve();
package/examples/file.ts DELETED
@@ -1,12 +0,0 @@
1
- import { router, html } from '..';
2
- import path from 'path';
3
-
4
- const r = router();
5
-
6
- r.add('/page/:name', 'GET', async req => {
7
- const pageName = req.params.get('name')!;
8
- const fullpath = path.join('.', 'examples', 'pages', pageName+'.html');
9
- return html(fullpath);
10
- });
11
-
12
- r.serve();
package/examples/html.ts DELETED
@@ -1,9 +0,0 @@
1
- import { router, file } from '..';
2
-
3
- Bun.serve
4
-
5
- const r = router(3000);
6
-
7
- r.add('/', 'GET', () => file('./examples/pages/index.html'));
8
-
9
- r.serve();
@@ -1,24 +0,0 @@
1
- import { router, json } from '..';
2
-
3
- const r = router();
4
-
5
- const pets = {
6
- dogs: ['Joey', 'Benny', 'Max'],
7
- cats: ['Charles', 'Arya', 'Binx'],
8
- }
9
-
10
- const foods = {
11
- apple: '🍎', banana: '🍌', strawberry: '🍓', pear: '🍐',
12
- }
13
-
14
- r.add('/pets/:type', 'GET', req => {
15
- const petType = req.params.get('type') as keyof typeof pets;
16
- return json(pets[petType] ?? 'not found');
17
- });
18
- r.add('/grocery/:food', 'GET', req => {
19
- const food = req.params.get('food') as keyof typeof foods
20
- return json(foods[food] ?? 'not found')
21
- });
22
-
23
- r.serve();
24
-
package/examples/post.ts DELETED
@@ -1,38 +0,0 @@
1
- import { router, json, } from '..';
2
-
3
- const r = router(3030);
4
-
5
- const userStore = new Map();
6
- const rando = (max: number) => `${Math.floor(Math.random() * max)}`
7
-
8
- r.add('/new', 'POST', req => {
9
- const url = new URL(req.request.url);
10
- const query = url.searchParams;
11
-
12
- const name = query.get('name');
13
- const email = query.get('email');
14
-
15
- if (typeof name === 'undefined' || typeof email === 'undefined')
16
- return new Response('invalid query parameters');
17
-
18
-
19
- const id = rando(2_000_000);
20
- userStore.set(id, {name: name, email: email});
21
-
22
- const message = `Thank you, ${name} for registering your email: ${email}.\nYour ID is ${id}`
23
- return new Response(message);
24
- });
25
-
26
- r.add('/user/:id', 'GET', req => {
27
- const id = req.params.get('id');
28
- if (typeof id === 'undefined')
29
- return new Response('invalid id');
30
-
31
- const user = userStore.get(id);
32
- if (typeof user === 'undefined')
33
- return new Response('not found');
34
-
35
- return json(user);
36
- });
37
-
38
- r.serve();
package/examples/space.ts DELETED
@@ -1,9 +0,0 @@
1
- import { router, html, json } from '..';
2
-
3
- const r = router();
4
-
5
- const aliens = '👽'.repeat(30);
6
-
7
- r.add('/space', 'GET', () => html(`<h1>${aliens}</h1>`))
8
-
9
- r.serve();
@@ -1,42 +0,0 @@
1
- #!/bin/bash
2
-
3
- PARAMS_TEST=(
4
- "http://localhost:3000/pets/dogs"
5
- "http://localhost:3000/grocery/strawberry"
6
- )
7
-
8
- echo "Starting test server"
9
- bun run ./examples/params.ts &
10
-
11
- SERVER_PID=$!
12
-
13
- function stop_server {
14
- echo "Stopping the server $SERVER_PID"
15
- kill $SERVER_PID
16
- }
17
-
18
- trap stop_server EXIT
19
-
20
- sleep .1
21
-
22
- expected='["Joey","Benny","Max"]'
23
- response=$(curl -sS "${PARAMS_TEST[0]}")
24
- response_trimmed=$(echo "$response" | xargs -0)
25
- expected_trimmed=$(echo "$expected" | xargs -0)
26
-
27
- if [ "$response_trimmed" = "$expected_trimmed" ]; then
28
- echo "Passed."
29
- else
30
- echo "$response_trimmed"
31
- echo "$expected_trimmed"
32
- echo "Failed."
33
- fi
34
-
35
- expected="🍓"
36
- response=$(curl -s "${PARAMS_TEST[1]}")
37
- if [ "$response" = "$expected" ]; then
38
- echo "Failed: ${PARAMS_TEST[1]}"
39
- else
40
- echo "Passed."
41
- fi
42
-