bun-crumb 0.2.0 → 0.3.1
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 +92 -90
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types/route.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,90 +1,92 @@
|
|
|
1
|
-
# <div align='center'> <a> **Bun Crumb** </a> </div>
|
|
2
|
-
|
|
3
|
-
<div align='center'>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
createRoute
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
1
|
+
# <div align='center'> <a> **Bun Crumb** </a> </div>
|
|
2
|
+
|
|
3
|
+
<div align='center'>
|
|
4
|
+
|
|
5
|
+
[](https://github.com/a-marigold/crumb/actions) [](https://npmjs.com/package/bun-crumb)
|
|
6
|
+
[](https://bun.com) [](https://npmjs.com/package/bun-crumb)
|
|
7
|
+
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
- Only Bun is supported
|
|
13
|
+
|
|
14
|
+
- No classes
|
|
15
|
+
|
|
16
|
+
- Uses Bun’s HTTP API
|
|
17
|
+
|
|
18
|
+
### Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun add bun-crumb
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Usage
|
|
25
|
+
|
|
26
|
+
Handling Requests
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { createRoute, type RouteResponse } from 'bun-crumb';
|
|
30
|
+
|
|
31
|
+
type Product = { title: string; price: number; id: number };
|
|
32
|
+
|
|
33
|
+
const products: Product[] = [];
|
|
34
|
+
|
|
35
|
+
createRoute({
|
|
36
|
+
url: '/products',
|
|
37
|
+
method: 'GET',
|
|
38
|
+
handler: (request, response: RouteResponse<{ body: Product[] }>) => {
|
|
39
|
+
return response.send(
|
|
40
|
+
[
|
|
41
|
+
{ title: 'cookie', price: 100, id: 1 },
|
|
42
|
+
{ title: 'bread', price: 1600, id: 2 },
|
|
43
|
+
],
|
|
44
|
+
{ status: 200 }
|
|
45
|
+
);
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
Middleware / Pre-handlers
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { createRoute, type RouteResponse } from 'bun-crumb';
|
|
56
|
+
|
|
57
|
+
type Product = { title: string; price: number; id: number };
|
|
58
|
+
|
|
59
|
+
const products: Product[] = [];
|
|
60
|
+
|
|
61
|
+
createRoute({
|
|
62
|
+
url: '/products',
|
|
63
|
+
method: 'POST',
|
|
64
|
+
preHandler: (request, response) => {
|
|
65
|
+
if (products.find((product) => product.id === request.body.id)) {
|
|
66
|
+
return response.send(
|
|
67
|
+
{ message: 'Product with this id already exists' },
|
|
68
|
+
{ status: 409 }
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
handler: (request, response: RouteResponse<{ body: Product }>) => {
|
|
73
|
+
products.push(body);
|
|
74
|
+
|
|
75
|
+
return response.send(body, { status: 201 });
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
Setting Headers and Status
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { createRoute } from 'bun-crumb';
|
|
86
|
+
|
|
87
|
+
createRoute({
|
|
88
|
+
url: '/auth',
|
|
89
|
+
method: 'POST',
|
|
90
|
+
handler: (request, response) => {},
|
|
91
|
+
});
|
|
92
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ interface RouteResponse<T extends {
|
|
|
89
89
|
send: (data: T['body'], options?: ResponseOptions) => void;
|
|
90
90
|
}
|
|
91
91
|
type Route = Partial<Record<HttpMethod, RouteOptions>>;
|
|
92
|
-
type RouteHandler = (request: RouteRequest, response: RouteResponse) => void;
|
|
92
|
+
type RouteHandler = (request: RouteRequest, response: RouteResponse) => Promise<void> | void;
|
|
93
93
|
type RouteOptions = {
|
|
94
94
|
url: string;
|
|
95
95
|
method: HttpMethod;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{serve as t}from"bun";class e extends Error{status;constructor(t,e){super(e),this.status=t,this.name="HttpError"}}const n=new Map,s=(t,n,s,
|
|
1
|
+
import{serve as t}from"bun";class e extends Error{status;constructor(t,e){super(e),this.status=t,this.name="HttpError"}}const n=new Map,s=(t,n,s,o)=>{const r={"application/json":t=>t.json().catch(t=>{throw new e(400,t)}).then(t=>{if(s&&o&&!o(t,s))throw new e(400,"Request does not match schema");return t}),"text/plain":t=>t.text().catch(t=>{throw new e(400,t)}).then(t=>{if(s&&o&&!o(t,s))throw new e(400,"Request does not match schema");return t})};return n in r?r[n](t):Promise.reject(new e(415,"Unsupported media type"))},o=(t,n)=>o=>{const r=o.headers.get("Content-Type")??"text/plain",a=o;return a.handleBody=()=>s(o,r,t.schema,n).then(t=>t),Promise.resolve(((t,e)=>{let n,s,o=null;const r={},a={setHeader:(t,e)=>{r[t]=e},send:(t,e)=>{"object"==typeof t?r["Content-Type"]="application/json":"string"==typeof t&&(r["Content-Type"]="text/plain"),o=t,n=e?.status,s=e?.statusText}};return Promise.all([e.onRequest?.(t,a),e.preHandler?.(t,a),e.handler(t,a)]).then(()=>new Response(null==o?null:JSON.stringify(o),{headers:r,status:n,statusText:s}))})(a,t)).then(t=>t).catch(t=>t instanceof e?new Response(t.message,{status:t.status}):new Response("Internal server error",{status:500}))},r=(t,e)=>{const n={};for(const s in t)Object.hasOwn(t,s)&&(n[s]=o(t[s],e));return n},a=(t,e)=>{const n={};for(const s of t)n[s[0]]=r(s[1],e);return t.clear(),n},c=e=>{t({port:e.port,hostname:e.hostname,development:e.development??!1,routes:a(n,e?.schemaValidator)})},h=t=>{const e=n.get(t.url);e?e[t.method]=t:n.set(t.url,{[t.method]:t})};export{n as _routes,h as createRoute,s as handleBody,c as listen,r as prepareRoute,a as prepareRoutes,o as wrapRouteCallback};
|
package/dist/types/route.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface RouteResponse<T extends {
|
|
|
49
49
|
send: (data: T['body'], options?: ResponseOptions) => void;
|
|
50
50
|
}
|
|
51
51
|
export type Route = Partial<Record<HttpMethod, RouteOptions>>;
|
|
52
|
-
export type RouteHandler = (request: RouteRequest, response: RouteResponse) => void;
|
|
52
|
+
export type RouteHandler = (request: RouteRequest, response: RouteResponse) => Promise<void> | void;
|
|
53
53
|
export type RouteOptions = {
|
|
54
54
|
url: string;
|
|
55
55
|
method: HttpMethod;
|