bun-crumb 0.3.1 → 0.6.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
@@ -2,7 +2,7 @@
2
2
 
3
3
  <div align='center'>
4
4
 
5
- [![CI](https://github.com/a-marigold/crumb/actions/workflows/ci.yaml/badge.svg)](https://github.com/a-marigold/crumb/actions) [![Status](https://img.shields.io/badge/BETA-darkgreen?style=for-the-badge)](https://npmjs.com/package/bun-crumb)
5
+ [![CI](https://github.com/a-marigold/crumb/actions/workflows/ci.yaml/badge.svg)](https://github.com/a-marigold/bun-crumb/actions) [![Status](https://img.shields.io/badge/BETA-darkgreen?style=for-the-badge)](https://npmjs.com/package/bun-crumb)
6
6
  [![bun](https://img.shields.io/badge/Bun-000?logo=bun&logoColor=fff)](https://bun.com) [![npm](https://img.shields.io/npm/v/bun-crumb)](https://npmjs.com/package/bun-crumb)
7
7
 
8
8
  </div>
package/dist/index.d.ts CHANGED
@@ -94,11 +94,14 @@ type RouteOptions = {
94
94
  url: string;
95
95
  method: HttpMethod;
96
96
  schema?: SchemaData;
97
- onRequest?: RouteHandler;
98
- preHandler?: RouteHandler;
99
97
  handler: RouteHandler;
100
98
  };
101
99
 
100
+ /**
101
+ *
102
+ *
103
+ * Type of `options` parameter in `listen` function
104
+ */
102
105
  interface ListenOptions {
103
106
  /**
104
107
  * Server port to listen
@@ -106,7 +109,6 @@ interface ListenOptions {
106
109
  port?: number | string;
107
110
  /**
108
111
  * Server hostname to listen
109
- *
110
112
  * @example `localhost`, `0.0.0.0`
111
113
  *
112
114
  */
@@ -123,90 +125,6 @@ interface ListenOptions {
123
125
  schemaValidator?: Validate;
124
126
  }
125
127
 
126
- type PreparedRoute = Partial<Record<HttpMethod, WrappedRouteCallback>>;
127
- type WrappedRouteCallback = (request: BunRequest) => Promise<Response>;
128
- /**
129
- * Used straight as Bun.serve `routes` object.
130
- */
131
- type PreparedRoutes = Record<RouteOptions['url'], PreparedRoute>;
132
- type Routes = Map<RouteOptions['url'], Route>;
133
- /**
134
- * An internal Map with routes of app. Do not use it in user code to prevent undefined errors
135
- */
136
- declare const _routes: Routes;
137
- /**
138
- * Runtime function that used in request.
139
- * Parses body to supported content type (json, plain text) and validates it with route schema.
140
- *
141
- * @param {BunRequest} request incoming bun request.
142
- * @param {string} contentType request `Content-Type` header value.
143
- * @param {Schema} schema json or any schema with declared `Schema` type.
144
- * @param {Validate} schemaValidator schema validator function that receives `data` and `schema` arguments.
145
- *
146
- * @returns {Promise<unknown>} Promise with body
147
- */
148
- declare const handleBody: (request: BunRequest, contentType: string, schema?: SchemaData, schemaValidator?: Validate) => Promise<unknown>;
149
- /**
150
- * Internal `server` function.
151
- * Creates a function with handler and all route hooks.
152
- *
153
- * The created function can be used as a callback for route in Bun.serve `routes` object.
154
- *
155
- *
156
- *
157
- *
158
- *
159
- * @param routeOptions options of route
160
- * @returns {WrappedRouteCallback} Function that is ready to be used in Bun.serve `routes`
161
- */
162
- declare const wrapRouteCallback: (routeOptions: RouteOptions, schemaValidator?: Validate) => WrappedRouteCallback;
163
- /**
164
- * Internal `server` function.
165
- * Prepares a route to be used in Bun.serve `routes` object.
166
- *
167
- * @param {Route} route
168
- *
169
- * @returns {PreparedRoute} Route object with `GET` or other http method keys with wrapped route callbacks.
170
- *
171
- * @example
172
- *
173
- * ```typescript
174
- * prepareRoute({
175
- * GET: {
176
- * url: '/products',
177
- * method: 'GET',
178
- * handler: (request, response) => {},
179
- * },
180
- * POST: {
181
- * url: '/products/:id',
182
- * method: 'POST',
183
- * handler: (request, response) => {},
184
- * },
185
- * });
186
- * // Output will be:
187
- * ({
188
- * GET: (request: BunRequest) => {
189
- * // ...code
190
- * return new Response();
191
- * },
192
- * POST: (request: BunRequest) => {
193
- * // ...code
194
- * return new Response();
195
- * },
196
- * })
197
- * ```
198
- *
199
- */
200
- declare const prepareRoute: (route: Route, schemaValidator?: Validate) => PreparedRoute;
201
- /**
202
- * Internal server function.
203
- * Calls `prepareRoute` for every route of `routes` Map and returns prepared routes to use in Bun.serve `routes`.
204
- *
205
- * @param {Routes} routes Map with routes to prepare.
206
- *
207
- * @returns {PreparedRoutes} An object that is used straight in Bun.serve `routes` object.
208
- */
209
- declare const prepareRoutes: (routes: Routes, schemaValidator?: Validate) => PreparedRoutes;
210
128
  /**
211
129
  * Starts serving http server.
212
130
  *
@@ -282,5 +200,5 @@ declare const listen: (options: ListenOptions) => void;
282
200
  */
283
201
  declare const createRoute: (routeOptions: RouteOptions) => void;
284
202
 
285
- export { _routes, createRoute, handleBody, listen, prepareRoute, prepareRoutes, wrapRouteCallback };
286
- export type { Header, Headers, HttpMethod, ListenOptions, ResponseOptions, Route, RouteHandler, RouteOptions, RouteRequest, RouteResponse, Routes, Schema, SchemaData, Validate, WrappedRouteCallback };
203
+ export { createRoute, listen };
204
+ export type { Header, Headers, HttpMethod, ListenOptions, ResponseOptions, Route, RouteHandler, RouteOptions, RouteRequest, RouteResponse, Schema, SchemaData, Validate };
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,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};
1
+ import{serve as t}from"bun";class e extends Error{status;constructor(t,e){super(e),this.status=t,this.name="HttpError"}}const s=new Map,n=(t,s)=>n=>{const o=n.headers.get("Content-Type")??"text/plain",r=n;return r.handleBody=()=>((t,s,n,o)=>{const r={"application/json":t=>t.json().catch(()=>{throw new e(400,"Bad Request")}).then(t=>{if(n&&o&&!o(t,n))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(n&&o&&!o(t,n))throw new e(400,"Request does not match schema");return t})};return s in r?r[s](t):Promise.reject(new e(415,"Unsupported media type"))})(n,o,t.schema,s),Promise.resolve(((t,e)=>{let s=200,n="",o="";const r={},a={setHeader:(t,e)=>{r[t]=e},send:(t,e)=>{"object"==typeof t?(r["Content-Type"]="application/json",o=JSON.stringify(t)):"string"==typeof t&&(r["Content-Type"]="text/plain",o=t),e&&(s=e.status,n=e.statusText)}};return Promise.resolve(e.handler(t,a)).then(()=>new Response(o,{headers:r,status:s,statusText:n}))})(r,t)).then(t=>t).catch(t=>t instanceof e?new Response(t.message,{status:t.status}):new Response("Internal server error",{status:500}))},o=(t,e)=>{const s={};for(const o in t)Object.hasOwn(t,o)&&(s[o]=n(t[o],e));return s},r=(t,e)=>{const s={};for(const n of t)s[n[0]]=o(n[1],e);return t.clear(),s},a=e=>{t({port:e.port,hostname:e.hostname,development:e.development??!1,routes:r(s,e?.schemaValidator)})},c=t=>{const e=s.get(t.url);e?e[t.method]=t:s.set(t.url,{[t.method]:t})};export{c as createRoute,a as listen};
@@ -54,7 +54,5 @@ export type RouteOptions = {
54
54
  url: string;
55
55
  method: HttpMethod;
56
56
  schema?: SchemaData;
57
- onRequest?: RouteHandler;
58
- preHandler?: RouteHandler;
59
57
  handler: RouteHandler;
60
58
  };
@@ -1,4 +1,9 @@
1
1
  import type { Validate } from './schema';
2
+ /**
3
+ *
4
+ *
5
+ * Type of `options` parameter in `listen` function
6
+ */
2
7
  export interface ListenOptions {
3
8
  /**
4
9
  * Server port to listen
@@ -6,7 +11,6 @@ export interface ListenOptions {
6
11
  port?: number | string;
7
12
  /**
8
13
  * Server hostname to listen
9
- *
10
14
  * @example `localhost`, `0.0.0.0`
11
15
  *
12
16
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bun-crumb",
3
- "version": "0.3.1",
3
+ "version": "0.6.0",
4
4
  "author": "marigold",
5
5
  "module": "dist/index.js",
6
6
  "license": "UNLICENSED",