Comparing version 0.9.0 to 0.9.1
@@ -17,4 +17,7 @@ export { default as Context } from './src/Context/Context'; | ||
export { serveFiles } from './src/middleware/serveFiles/serveFiles'; | ||
export { Router as HttpRouter }; | ||
import HttpRouter from './src/HttpRouter/HttpRouter'; | ||
const Router = HttpRouter; | ||
export default HttpRouter; |
{ | ||
"name": "bunshine", | ||
"version": "0.9.0", | ||
"version": "0.9.1", | ||
"module": "server/server.ts", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -1,5 +0,5 @@ | ||
<img alt="Bunshine Logo" src="https://github.com/kensnyder/bunshine/raw/main/assets/bunshine-logo.png?v=0.9.0" width="200" height="187" /> | ||
<img alt="Bunshine Logo" src="https://github.com/kensnyder/bunshine/raw/main/assets/bunshine-logo.png?v=0.9.1" width="200" height="187" /> | ||
[](https://npmjs.com/package/bunshine) | ||
[](https://opensource.org/licenses/ISC) | ||
[](https://npmjs.com/package/bunshine) | ||
[](https://opensource.org/licenses/ISC) | ||
@@ -76,3 +76,3 @@ # Bunshine | ||
app.on404(c => { | ||
// called when no other handler matches | ||
// called when no handlers match the requested path | ||
console.log('404'); | ||
@@ -194,3 +194,3 @@ return c.json({ error: 'Not found' }, { status: 404 }); | ||
// WebSocket routes | ||
app.socket.at('/games/rooms/:room', { | ||
app.socket.at<{ user: string }>('/games/rooms/:room', { | ||
// Optional. Allows you to specify arbitrary data to attach to ws.data. | ||
@@ -202,4 +202,8 @@ upgrade: ({ request, params, url }) => { | ||
}, | ||
// Optional. Allows you to deal with errors thrown by handlers. | ||
error: (ws, error) => { | ||
console.log('WebSocket error', error); | ||
}, | ||
// Optional. Called when the client connects | ||
open(ws: ServerWebSocketWithData) { | ||
open(ws) { | ||
const room = ws.data.params.room; | ||
@@ -211,3 +215,3 @@ const user = ws.data.user; | ||
// Optional. Called when the client sends a message | ||
message(ws: ServerWebSocketWithData, message: Buffer) { | ||
message(ws, message) { | ||
const room = ws.data.params.room; | ||
@@ -219,3 +223,3 @@ const user = ws.data.user; | ||
// Optional. Called when the client disconnects | ||
close(ws: ServerWebSocketWithData, code: number, message: string) { | ||
close(ws, code, message) { | ||
const room = ws.data.params.room; | ||
@@ -317,17 +321,17 @@ const user = ws.data.user; | ||
| Path | URL | params | | ||
| -------------------------- | ------------------------- | --------------------------- | | ||
| `'/path'` | `'/path'` | `{}` | | ||
| `'/users/:id'` | `'/users/123'` | `{ id: '123' }` | | ||
| `'/users/:id/groups'` | `'/users/123/groups'` | `{ id: '123' }` | | ||
| `'/users/:id/groups/:gid'` | `'/users/123/groups/abc'` | `{ id: '123', gid: 'abc' }` | | ||
| `'/star/*'` | `'/star/man'` | `{ 0: 'man' }` | | ||
| `'/star/*/can'` | `'/star/man/can'` | `{ 0: 'man' }` | | ||
| `'/users/(\\d+)'` | `'/users/123'` | `{ 0: '123' }` | | ||
| `/users/(\d+)/` | `'/users/123'` | `{ 0: '123' }` | | ||
| `/users/([a-z-]+)/` | `'/users/abc-def'` | `{ 0: 'abc-def' }` | | ||
| `'/(users\|u)/:id'` | `'/users/123'` | `{ id: '123' }` | | ||
| `'/(users\|u)/:id'` | `'/u/123'` | `{ id: '123' }` | | ||
| `'/:a/:b?'` | `'/123'` | `{ a: '123' }` | | ||
| `'/:a/:b?'` | `'/123/abc'` | `{ a: '123', b: 'abc' }` | | ||
| Path | URL | params | | ||
| ---------------------- | --------------------- | ------------------------ | | ||
| `'/path'` | `'/path'` | `{}` | | ||
| `'/users/:id'` | `'/users/123'` | `{ id: '123' }` | | ||
| `'/users/:id/groups'` | `'/users/123/groups'` | `{ id: '123' }` | | ||
| `'/u/:id/groups/:gid'` | `'/u/1/groups/a'` | `{ id: '1', gid: 'a' }` | | ||
| `'/star/*'` | `'/star/man'` | `{ 0: 'man' }` | | ||
| `'/star/*/can'` | `'/star/man/can'` | `{ 0: 'man' }` | | ||
| `'/users/(\\d+)'` | `'/users/123'` | `{ 0: '123' }` | | ||
| `/users/(\d+)/` | `'/users/123'` | `{ 0: '123' }` | | ||
| `/users/([a-z-]+)/` | `'/users/abc-def'` | `{ 0: 'abc-def' }` | | ||
| `'/(users\|u)/:id'` | `'/users/123'` | `{ id: '123' }` | | ||
| `'/(users\|u)/:id'` | `'/u/123'` | `{ id: '123' }` | | ||
| `'/:a/:b?'` | `'/123'` | `{ a: '123' }` | | ||
| `'/:a/:b?'` | `'/123/abc'` | `{ a: '123', b: 'abc' }` | | ||
@@ -362,12 +366,13 @@ ## Middleware | ||
- ✅HttpRouter | ||
- ✅WebSocketRouter | ||
- ✅Context | ||
- ✅middlware > serveFiles | ||
- 🔲middlware > cors | ||
- 🔲middlware > devLogger | ||
- 🔲middlware > performanceLogger | ||
- 🔲middlware > prodLogger | ||
- 🔲middlware > securityHeaders | ||
- 🔲examples/server.ts | ||
- ✅ HttpRouter | ||
- ✅ SocketRouter | ||
- ✅ Context | ||
- ✅ middleware > serveFiles | ||
- ✅ middleware > cors | ||
- ✅ middleware > devLogger | ||
- ✅ middleware > prodLogger | ||
- 🔲 middleware > performanceLogger | ||
- 🔲 middleware > securityHeaders | ||
- 🔲 examples/server.ts | ||
- 🔲 GitHub Actions to run tests and coverage | ||
@@ -374,0 +379,0 @@ ## License |
@@ -1,20 +0,22 @@ | ||
import type { Middleware} from "../../HttpRouter/HttpRouter.ts"; | ||
import type { Middleware } from '../../HttpRouter/HttpRouter.ts'; | ||
export const devLogger: Middleware = async (c, next) => { | ||
const start = performance.now(); | ||
const { pathname } = c.url; | ||
const time = new Date().toISOString().slice(11); | ||
// write request | ||
// get response | ||
const resp = await next(); | ||
const range = c.request.headers.get('Range'); | ||
let maybeRange = range ? ` \x1b[37m${range}\x1b[0m` : ''; | ||
// log response status | ||
const ms = (performance.now() - start).toFixed(1); | ||
process.stdout.write( | ||
`\x1b[0m\x1b[37m[${time}]\x1b[0m ${c.request.method} \x1b[92m${pathname}\x1b[0m ` | ||
); | ||
console.log(`\x1b[0m\x1b[96m${resp.status}\x1b[0m${maybeRange} (${ms}ms)`); | ||
// return response | ||
return resp; | ||
}; | ||
export function devLogger(): Middleware { | ||
return async (c, next) => { | ||
const start = performance.now(); | ||
const { pathname } = c.url; | ||
const time = new Date().toISOString().slice(11); | ||
// write request | ||
// get response | ||
const resp = await next(); | ||
const range = c.request.headers.get('Range'); | ||
let maybeRange = range ? ` \x1b[37m${range}\x1b[0m` : ''; | ||
// log response status | ||
const ms = (performance.now() - start).toFixed(1); | ||
process.stdout.write( | ||
`\x1b[0m\x1b[37m[${time}]\x1b[0m ${c.request.method} \x1b[92m${pathname}\x1b[0m ` | ||
); | ||
console.log(`\x1b[0m\x1b[96m${resp.status}\x1b[0m${maybeRange} (${ms}ms)`); | ||
// return response | ||
return resp; | ||
}; | ||
} |
@@ -45,7 +45,8 @@ import Context from '../../Context/Context.ts'; | ||
export function securityHeaders(options: SecurityHeaderOptions): Middleware { | ||
const headers = Object.entries({ ...defaultOptions, ...options }).map( | ||
([name, value]) => { | ||
return [dasherize(name), value]; | ||
} | ||
); | ||
const headers: Array<[string, SecurityHeader]> = Object.entries({ | ||
...defaultOptions, | ||
...options, | ||
}).map(([name, value]) => { | ||
return [dasherize(name), value]; | ||
}); | ||
return async (context, next) => { | ||
@@ -52,0 +53,0 @@ const resp = await next(); |
@@ -139,5 +139,7 @@ import type { Server, ServerWebSocket } from 'bun'; | ||
const error = e as Error; | ||
// @ts-expect-error | ||
if (typeof target?.error === 'function') { | ||
try { | ||
target?.error?.(ws, eventName, error); | ||
// @ts-expect-error | ||
target.error(ws, eventName, error); | ||
} catch (e) { | ||
@@ -144,0 +146,0 @@ const error = e as Error; |
129554
1877
375