bun-crumb 0.8.0 → 0.10.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/dist/index.d.ts +59 -14
- package/dist/index.js +1 -1
- package/dist/server.d.ts +4 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/route.d.ts +52 -26
- package/dist/types/utils.d.ts +18 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BunRequest } from 'bun';
|
|
1
|
+
import { BunRequest, CookieInit } from 'bun';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The global Schema type that reflects schema type in `Validate` function
|
|
@@ -43,13 +43,14 @@ type Validate = (data: unknown, schema: SchemaData) => boolean;
|
|
|
43
43
|
/**
|
|
44
44
|
* HTTP Method primitive.
|
|
45
45
|
*
|
|
46
|
+
*
|
|
46
47
|
* @example
|
|
47
48
|
* ```typescript
|
|
48
49
|
* const method: HttpMethod = 'GET';
|
|
49
50
|
* ```
|
|
50
51
|
*/
|
|
51
52
|
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
|
|
52
|
-
type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | 307 | 308;
|
|
53
|
+
type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;
|
|
53
54
|
/**
|
|
54
55
|
* HTTP Header struct.
|
|
55
56
|
*/
|
|
@@ -57,7 +58,11 @@ type Header = {
|
|
|
57
58
|
name: string;
|
|
58
59
|
value: string;
|
|
59
60
|
};
|
|
60
|
-
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* Type of Request search parameters
|
|
65
|
+
*/
|
|
61
66
|
type RouteRequestParams<T extends string | undefined = undefined> = [
|
|
62
67
|
T
|
|
63
68
|
] extends [string] ? {
|
|
@@ -66,21 +71,16 @@ type RouteRequestParams<T extends string | undefined = undefined> = [
|
|
|
66
71
|
[key: string]: string | undefined;
|
|
67
72
|
};
|
|
68
73
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
74
|
* Type of RouteRequest generic
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
75
|
*/
|
|
78
76
|
interface RouteRequestGeneric {
|
|
79
77
|
body?: unknown;
|
|
80
78
|
params?: string;
|
|
81
79
|
}
|
|
82
80
|
/**
|
|
83
|
-
*
|
|
81
|
+
*
|
|
82
|
+
*
|
|
83
|
+
* Type of route handler `request` parameter
|
|
84
84
|
*/
|
|
85
85
|
interface RouteRequest<T extends RouteRequestGeneric = RouteRequestGeneric> extends Omit<BunRequest, 'params'> {
|
|
86
86
|
params: RouteRequestParams<T['params']>;
|
|
@@ -117,9 +117,53 @@ interface RouteResponse<T extends {
|
|
|
117
117
|
} = {
|
|
118
118
|
body: unknown;
|
|
119
119
|
}> {
|
|
120
|
-
setHeader: (name: Header['name'], value: Header['value']) => void;
|
|
121
120
|
send: (data: T['body'], options?: ResponseOptions) => void;
|
|
122
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Sets `Location` header to provided `url` and `response.status` to provided `status`
|
|
123
|
+
*
|
|
124
|
+
*
|
|
125
|
+
*
|
|
126
|
+
* @param url `Location` to redirect
|
|
127
|
+
*
|
|
128
|
+
* @param status redirect http code (`3xx`)
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
*
|
|
132
|
+
*
|
|
133
|
+
* ```typescript
|
|
134
|
+
* return response.redirect('https://bun-crumb.vercel.app', 302);
|
|
135
|
+
* ```
|
|
136
|
+
* The same behaviour is
|
|
137
|
+
* ```typescript
|
|
138
|
+
* response.setHeader('Location', 'https://bun-crumb.vercel.app');
|
|
139
|
+
* return response.send('', {status: 302});
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
redirect: (url: string, status?: RedirectStatusCode | (number & {})) => void;
|
|
143
|
+
/**
|
|
144
|
+
* Sets the response header.
|
|
145
|
+
*
|
|
146
|
+
*
|
|
147
|
+
*
|
|
148
|
+
*
|
|
149
|
+
* Overrides header if it already exists.
|
|
150
|
+
*
|
|
151
|
+
* Case of `name` is not important. Names 'content-type', 'Content-Type', 'CoNteNt=TYPE' are the same.
|
|
152
|
+
*
|
|
153
|
+
*
|
|
154
|
+
* @param name header name
|
|
155
|
+
* @param value header value
|
|
156
|
+
*
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* response.setHeader('Access-Control-Allow-Origin', '*');
|
|
161
|
+
* // The code below will override the header above
|
|
162
|
+
* response.setHeader('access-control-allow-origin', 'https://bun-crumb.vercel.app');
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
setHeader: (name: Header['name'], value: Header['value']) => void;
|
|
166
|
+
setCookie: (options: CookieInit) => void;
|
|
123
167
|
}
|
|
124
168
|
type Route = Partial<Record<HttpMethod, RouteOptions>>;
|
|
125
169
|
type RouteHandler = (request: RouteRequest, response: RouteResponse) => Promise<void> | void;
|
|
@@ -166,6 +210,7 @@ interface ListenOptions {
|
|
|
166
210
|
*
|
|
167
211
|
*
|
|
168
212
|
*
|
|
213
|
+
*
|
|
169
214
|
* @example
|
|
170
215
|
*
|
|
171
216
|
* ```typescript
|
|
@@ -234,4 +279,4 @@ declare const listen: (options?: ListenOptions) => void;
|
|
|
234
279
|
declare const createRoute: (routeOptions: RouteOptions) => void;
|
|
235
280
|
|
|
236
281
|
export { createRoute, listen };
|
|
237
|
-
export type { Header,
|
|
282
|
+
export type { Header, HttpMethod, ListenOptions, RedirectStatusCode, ResponseOptions, Route, RouteHandler, RouteOptions, RouteRequest, RouteRequestGeneric, RouteRequestParams, RouteResponse, Schema, SchemaData, Validate };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{serve as t}from"bun";class
|
|
1
|
+
import{serve as e,Cookie as t}from"bun";class s extends Error{status;constructor(e,t){super(t),this.status=e,this.name="HttpError"}}const n=new Map,o=(e,n)=>o=>{const r=o.headers.get("Content-Type")??"text/plain",a=o;return a.handleBody=()=>((e,t,n,o)=>{const r={"application/json":e=>e.json().catch(()=>{throw new s(400,"Bad Request")}).then(e=>{if(n&&o&&!o(e,n))throw new s(400,"Request does not match schema");return e}),"text/plain":e=>e.text().catch(e=>{throw new s(400,e)}).then(e=>{if(n&&o&&!o(e,n))throw new s(400,"Request does not match schema");return e})};return t in r?r[t](e):Promise.reject(new s(415,"Unsupported media type"))})(o,r,e.schema,n),a.query=new URLSearchParams(o.url.split("?")[1]||""),Promise.resolve(((e,s)=>{let n=200,o="",r="";const a=new Headers,c={send:(e,t)=>{"object"==typeof e?(a.has("Content-Type")||a.set("Content-Type","application/json"),r=JSON.stringify(e)):"string"==typeof e?(a.has("Content-Type")||a.set("Content-Type","text/plain"),r=e):r=e,t&&(n=t.status,o=t.statusText)},redirect:(e,t)=>{r="",n=t||302,a.set("Location",e)},setHeader:(e,t)=>{a.set(e,t)},setCookie:e=>{a.append("Set-Cookie",new t(e).toString())}};return Promise.resolve(s.handler(e,c)).then(()=>new Response(r,{headers:a,status:n,statusText:o}))})(a,e)).then(e=>e).catch(e=>e instanceof s?new Response(e.message,{status:e.status}):new Response("Internal server error",{status:500}))},r=(e,t)=>{const s={};for(const n in e)Object.hasOwn(e,n)&&(s[n]=o(e[n],t));return s},a=(e,t)=>{const s={};for(const n of e)s[n[0]]=r(n[1],t);return e.clear(),s},c=t=>{e({port:t?.port,hostname:t?.hostname,development:t?.development??!1,routes:a(n,t?.schemaValidator)})},p=e=>{const t=n.get(e.url);t?t[e.method]=e:n.set(e.url,{[e.method]:e})};export{p as createRoute,c as listen};
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BunRequest } from 'bun';
|
|
2
|
-
import type { Route, RouteOptions, HttpMethod } from './types
|
|
2
|
+
import type { Route, RouteOptions, HttpMethod } from './types';
|
|
3
3
|
import type { SchemaData, Validate } from './types';
|
|
4
4
|
import type { ListenOptions } from './types';
|
|
5
5
|
type PreparedRoute = Partial<Record<HttpMethod, WrappedRouteCallback>>;
|
|
@@ -14,6 +14,7 @@ export type Routes = Map<RouteOptions['url'], Route>;
|
|
|
14
14
|
*/
|
|
15
15
|
export declare const _routes: Routes;
|
|
16
16
|
/**
|
|
17
|
+
*
|
|
17
18
|
* Runtime function that used in request.
|
|
18
19
|
* Parses body to supported content type (json, plain text) and validates it with route schema.
|
|
19
20
|
*
|
|
@@ -36,6 +37,7 @@ export declare const handleBody: (request: BunRequest, contentType: string, sche
|
|
|
36
37
|
*
|
|
37
38
|
*
|
|
38
39
|
* @param routeOptions options of route
|
|
40
|
+
*
|
|
39
41
|
* @returns {WrappedRouteCallback} Function that is ready to be used in Bun.serve `routes`
|
|
40
42
|
*/
|
|
41
43
|
export declare const wrapRouteCallback: (routeOptions: RouteOptions, schemaValidator?: Validate) => WrappedRouteCallback;
|
|
@@ -94,6 +96,7 @@ export declare const prepareRoutes: (routes: Routes, schemaValidator?: Validate)
|
|
|
94
96
|
*
|
|
95
97
|
*
|
|
96
98
|
*
|
|
99
|
+
*
|
|
97
100
|
* @example
|
|
98
101
|
*
|
|
99
102
|
* ```typescript
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/route.d.ts
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
|
-
import type { BunRequest } from 'bun';
|
|
1
|
+
import type { BunRequest, CookieInit } from 'bun';
|
|
2
2
|
import type { SchemaData } from './schema';
|
|
3
|
+
import type { Header, HttpMethod, RedirectStatusCode } from './utils';
|
|
3
4
|
/**
|
|
4
|
-
* HTTP Method primitive.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* ```typescript
|
|
8
|
-
* const method: HttpMethod = 'GET';
|
|
9
|
-
* ```
|
|
6
|
+
* Type of Request search parameters
|
|
10
7
|
*/
|
|
11
|
-
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
|
|
12
|
-
export type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | 307 | 308;
|
|
13
|
-
/**
|
|
14
|
-
* HTTP Header struct.
|
|
15
|
-
*/
|
|
16
|
-
export type Header = {
|
|
17
|
-
name: string;
|
|
18
|
-
value: string;
|
|
19
|
-
};
|
|
20
|
-
export type Headers = ResponseInit['headers'];
|
|
21
8
|
export type RouteRequestParams<T extends string | undefined = undefined> = [
|
|
22
9
|
T
|
|
23
10
|
] extends [string] ? {
|
|
@@ -26,21 +13,16 @@ export type RouteRequestParams<T extends string | undefined = undefined> = [
|
|
|
26
13
|
[key: string]: string | undefined;
|
|
27
14
|
};
|
|
28
15
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
16
|
* Type of RouteRequest generic
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
17
|
*/
|
|
38
18
|
export interface RouteRequestGeneric {
|
|
39
19
|
body?: unknown;
|
|
40
20
|
params?: string;
|
|
41
21
|
}
|
|
42
22
|
/**
|
|
43
|
-
*
|
|
23
|
+
*
|
|
24
|
+
*
|
|
25
|
+
* Type of route handler `request` parameter
|
|
44
26
|
*/
|
|
45
27
|
export interface RouteRequest<T extends RouteRequestGeneric = RouteRequestGeneric> extends Omit<BunRequest, 'params'> {
|
|
46
28
|
params: RouteRequestParams<T['params']>;
|
|
@@ -77,9 +59,53 @@ export interface RouteResponse<T extends {
|
|
|
77
59
|
} = {
|
|
78
60
|
body: unknown;
|
|
79
61
|
}> {
|
|
80
|
-
setHeader: (name: Header['name'], value: Header['value']) => void;
|
|
81
62
|
send: (data: T['body'], options?: ResponseOptions) => void;
|
|
82
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Sets `Location` header to provided `url` and `response.status` to provided `status`
|
|
65
|
+
*
|
|
66
|
+
*
|
|
67
|
+
*
|
|
68
|
+
* @param url `Location` to redirect
|
|
69
|
+
*
|
|
70
|
+
* @param status redirect http code (`3xx`)
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
*
|
|
74
|
+
*
|
|
75
|
+
* ```typescript
|
|
76
|
+
* return response.redirect('https://bun-crumb.vercel.app', 302);
|
|
77
|
+
* ```
|
|
78
|
+
* The same behaviour is
|
|
79
|
+
* ```typescript
|
|
80
|
+
* response.setHeader('Location', 'https://bun-crumb.vercel.app');
|
|
81
|
+
* return response.send('', {status: 302});
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
redirect: (url: string, status?: RedirectStatusCode | (number & {})) => void;
|
|
85
|
+
/**
|
|
86
|
+
* Sets the response header.
|
|
87
|
+
*
|
|
88
|
+
*
|
|
89
|
+
*
|
|
90
|
+
*
|
|
91
|
+
* Overrides header if it already exists.
|
|
92
|
+
*
|
|
93
|
+
* Case of `name` is not important. Names 'content-type', 'Content-Type', 'CoNteNt=TYPE' are the same.
|
|
94
|
+
*
|
|
95
|
+
*
|
|
96
|
+
* @param name header name
|
|
97
|
+
* @param value header value
|
|
98
|
+
*
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* response.setHeader('Access-Control-Allow-Origin', '*');
|
|
103
|
+
* // The code below will override the header above
|
|
104
|
+
* response.setHeader('access-control-allow-origin', 'https://bun-crumb.vercel.app');
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
setHeader: (name: Header['name'], value: Header['value']) => void;
|
|
108
|
+
setCookie: (options: CookieInit) => void;
|
|
83
109
|
}
|
|
84
110
|
export type Route = Partial<Record<HttpMethod, RouteOptions>>;
|
|
85
111
|
export type RouteHandler = (request: RouteRequest, response: RouteResponse) => Promise<void> | void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Method primitive.
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* const method: HttpMethod = 'GET';
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
|
|
11
|
+
export type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;
|
|
12
|
+
/**
|
|
13
|
+
* HTTP Header struct.
|
|
14
|
+
*/
|
|
15
|
+
export type Header = {
|
|
16
|
+
name: string;
|
|
17
|
+
value: string;
|
|
18
|
+
};
|