bun-router 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.7"
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,16 +0,0 @@
1
- import { router, html, json } from '..';
2
-
3
- const r = router();
4
-
5
- const aliens = '👽'.repeat(30);
6
-
7
- r.add('/', 'GET', (req) => {
8
- const message = {
9
- page: 'home',
10
- space: 'home',
11
- body: 'ok'
12
- };
13
- return json(message);
14
- });
15
-
16
- 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
-