Comparing version 3.2.0 to 3.2.1
# Changelog | ||
## v3.2.0 - Nov xx, 2024 | ||
## v3.2.1 - Dec 2, 2024 | ||
- Auto-detect file mime type with c.file() | ||
- Update dependencies to allow minor version changes | ||
- Docs improvements | ||
- Align `Handler` and `Middleware` type definitions | ||
## v3.2.0 - Nov 29, 2024 | ||
- Auto-detect file mime type with `c.file()` | ||
- Properly match fixed paths | ||
- Fix TypeScript types for HTTPS configuration | ||
- Support If-Modified-Since header | ||
- Support `If-Modified-Since` header | ||
- Tweaks to range header handling | ||
@@ -14,7 +20,7 @@ | ||
- Change default range chunk size 3MB => 1MB | ||
- Support passing headers to c.file() | ||
- Support passing headers to `c.file()` | ||
## v3.1.1 - Nov 23, 2024 | ||
- Fix Content-Range header when file size is 0 | ||
- Fix `Content-Range` header when file size is 0 | ||
@@ -21,0 +27,0 @@ ## v3.1.0 - Nov 23, 2024 |
// Generated by dts-bundle-generator v9.5.1 | ||
import { BunFile, ServeOptions, Server, ServerWebSocket, ServerWebSocketSendStatus, ZlibCompressionOptions } from 'bun'; | ||
import { Server, ServerWebSocket, ServerWebSocketSendStatus, TLSServeOptions, ZlibCompressionOptions } from 'bun'; | ||
import { LRUCache } from 'lru-cache'; | ||
@@ -104,5 +104,5 @@ import { BrotliOptions } from 'node:zlib'; | ||
export type SingleHandler<ParamsShape extends Record<string, string> = Record<string, string>> = (context: Context<ParamsShape>, next: NextFunction) => Response | void | Promise<Response | void>; | ||
export type Middleware<ParamsShape extends Record<string, string> = Record<string, string>> = SingleHandler<ParamsShape>; | ||
export type Handler<ParamsShape extends Record<string, string> = Record<string, string>> = SingleHandler<ParamsShape> | Handler<ParamsShape>[]; | ||
export type ListenOptions = Omit<ServeOptions, "fetch" | "websocket"> | number; | ||
export type Middleware<ParamsShape extends Record<string, string> = Record<string, string>> = SingleHandler<ParamsShape> | Handler<ParamsShape>[]; | ||
export type ListenOptions = Omit<TLSServeOptions, "fetch" | "websocket"> | number; | ||
export type HttpMethods = "ALL" | "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE"; | ||
@@ -130,3 +130,3 @@ export type HttpRouterOptions = { | ||
emitUrl({ verbose, to, date, }?: EmitUrlOptions): void; | ||
getExport(options?: Omit<ServeOptions, "fetch" | "websocket">): ServeOptions; | ||
getExport(options?: Omit<TLSServeOptions, "fetch" | "websocket">): TLSServeOptions; | ||
get socket(): SocketRouter; | ||
@@ -144,11 +144,14 @@ on<ParamsShape extends Record<string, string> = Record<string, string>>(verbOrVerbs: HttpMethods | HttpMethods[], path: string | RegExp, ...handlers: Handler<ParamsShape>[]): this; | ||
headGet<ParamsShape extends Record<string, string> = Record<string, string>>(path: string | RegExp, ...handlers: Handler<ParamsShape>[]): this; | ||
use(...handlers: Handler<{}>[]): this; | ||
on404(...handlers: SingleHandler<Record<string, string>>[]): this; | ||
on500(...handlers: SingleHandler<Record<string, string>>[]): this; | ||
use: (...handlers: Handler[]) => this; | ||
on404: (...handlers: Handler[]) => this; | ||
on500: (...handlers: Handler[]) => this; | ||
fetch: (request: Request, server: Server) => Promise<Response>; | ||
} | ||
export type FileLike = string | Blob | Uint8Array | ArrayBuffer; | ||
export type FileResponseOptions = { | ||
chunkSize?: number; | ||
disposition?: "inline" | "attachment"; | ||
disposition?: "inline" | "attachment" | "form-data"; | ||
acceptRanges?: boolean; | ||
sendLastModified?: boolean; | ||
headers?: HeadersInit; | ||
}; | ||
@@ -201,3 +204,3 @@ export type SseSend = (eventName: string, data?: string | object, id?: string, retry?: number) => void | Promise<void>; | ||
/** A shorthand for `new Response(bunFile, fileHeaders)` plus range features */ | ||
file: (filenameOrBunFile: string | BunFile, fileOptions?: FileResponseOptions) => Promise<Response>; | ||
file: (pathOrData: FileLike, fileOptions?: FileResponseOptions) => Promise<Response>; | ||
/** A shorthand for `new Response({ headers: { 'Content-type': 'text/event-stream' } })` */ | ||
@@ -209,3 +212,3 @@ sse: (setup: SseSetupFunction, init?: ResponseInit) => Response; | ||
responseCondition?: (c: Context, resp: Response) => Promise<boolean> | boolean; | ||
handler: SingleHandler; | ||
handler: Handler; | ||
}; | ||
@@ -212,0 +215,0 @@ export declare function applyHandlerIf(conditions: ApplyHandlerIfArgs): Middleware; |
{ | ||
"name": "bunshine", | ||
"version": "3.2.0", | ||
"version": "3.2.1", | ||
"module": "index.ts", | ||
@@ -48,15 +48,15 @@ "type": "module", | ||
"dependencies": { | ||
"file-type": "19.6.0", | ||
"lru-cache": "11.0.2" | ||
"file-type": "^19.6.0", | ||
"lru-cache": "^11.0.2" | ||
}, | ||
"devDependencies": { | ||
"@types/bun": "1.1.14", | ||
"eventsource": "2.0.2", | ||
"prettier": "3.4.1", | ||
"prettier-plugin-organize-imports": "4.1.0", | ||
"redos-detector": "5.1.3", | ||
"tinybench": "3.0.6", | ||
"type-fest": "4.29.0", | ||
"typescript": "5.7.2" | ||
"@types/bun": "^1.1.14", | ||
"eventsource": "^2.0.2", | ||
"prettier": "^3.4.1", | ||
"prettier-plugin-organize-imports": "^4.1.0", | ||
"redos-detector": "^5.1.3", | ||
"tinybench": "^3.0.6", | ||
"type-fest": "^4.29.0", | ||
"typescript": "^5.7.2" | ||
} | ||
} |
@@ -5,9 +5,9 @@ # Bunshine | ||
<img alt="Bunshine Logo" src="https://github.com/kensnyder/bunshine/raw/main/packages/bunshine/assets/bunshine-logo.png?v=3.2.0" width="200" height="187" /> | ||
<img alt="Bunshine Logo" src="https://github.com/kensnyder/bunshine/raw/main/packages/bunshine/assets/bunshine-logo.png?v=3.2.1" width="200" height="187" /> | ||
[](https://npmjs.com/package/bunshine) | ||
[](https://github.com/search?q=repo:kensnyder/bunshine++language:TypeScript&type=code) | ||
[](https://codecov.io/gh/kensnyder/bunshine) | ||
 | ||
[](https://opensource.org/licenses/ISC) | ||
[](https://npmjs.com/package/bunshine) | ||
[](https://github.com/search?q=repo:kensnyder/bunshine++language:TypeScript&type=code) | ||
[](https://codecov.io/gh/kensnyder/bunshine) | ||
 | ||
[](https://opensource.org/licenses/ISC) | ||
@@ -281,3 +281,3 @@ ## Installation | ||
return c.file(filePath); | ||
// Bun will set Content-Type based on the string file extension | ||
// Bunshine will set Content-Type based on the file contents or string file extension | ||
}); | ||
@@ -287,15 +287,12 @@ | ||
const hash = c.params.hash; | ||
const filePath = `${import.meta.dir}/assets/${name}.png`; | ||
// you can pass a BunFile | ||
return c.file( | ||
Bun.file(filePath, { | ||
// Bunshine will automatically set Content-Type based on the file bytes | ||
// but you can set it or override it for non-standard mime types | ||
headers: { 'Content-type': 'application/json' }, | ||
}) | ||
); | ||
const filePath = `${import.meta.dir}/assets/${name}.mystuff`; | ||
// or you can pass a BunFile | ||
return c.file(Bun.file(filePath), { | ||
// You can override Content-type for non-standard mime types | ||
headers: { 'Content-type': 'application/json' }, | ||
}); | ||
}); | ||
app.get('/profile/*.jpg', async c => { | ||
// you can pass a Buffer or Uint8Array | ||
// or you can pass a Buffer or Uint8Array | ||
const intArray = getBytesFromExternal(c.params[0]); | ||
@@ -306,8 +303,8 @@ return c.file(bytes); | ||
app.get('/files/*', async c => { | ||
// c.file() accepts 4 options: | ||
// c.file() accepts some options: | ||
return c.file(path, { | ||
disposition, // Use a Content-Disposition header with "inline" or "attachment" | ||
disposition, // Use a Content-Disposition header with "inline", "attachment" or "form-data" | ||
headers, // additional headers to add | ||
sendLastModified, // unless false, will report file modification date (For paths or BunFile objects) | ||
acceptRanges, // unless false, will support partial (ranged) downloads | ||
sendLastModified, // unless false, will report file modification date (For paths or BunFile objects) | ||
chunkSize, // Size for ranged downloads when client doesn't specify chunk size. Defaults to 1MB | ||
@@ -1211,3 +1208,3 @@ }); | ||
<img alt="devLogger" src="https://github.com/kensnyder/bunshine/raw/main/assets/devLogger-screenshot.png?v=3.2.0" width="524" height="78" /> | ||
<img alt="devLogger" src="https://github.com/kensnyder/bunshine/raw/main/assets/devLogger-screenshot.png?v=3.2.1" width="524" height="78" /> | ||
@@ -1228,3 +1225,3 @@ `prodLogger` outputs logs in JSON with the following shape: | ||
"runtime": "Bun v1.1.34", | ||
"poweredBy": "Bunshine v3.2.0", | ||
"poweredBy": "Bunshine v3.2.1", | ||
"machine": "server1", | ||
@@ -1248,3 +1245,3 @@ "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", | ||
"runtime": "Bun v1.1.34", | ||
"poweredBy": "Bunshine v3.2.0", | ||
"poweredBy": "Bunshine v3.2.1", | ||
"machine": "server1", | ||
@@ -1251,0 +1248,0 @@ "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", |
@@ -19,7 +19,7 @@ import { Server, TLSServeOptions } from 'bun'; | ||
export type Middleware< | ||
export type Handler< | ||
ParamsShape extends Record<string, string> = Record<string, string>, | ||
> = SingleHandler<ParamsShape>; | ||
> = SingleHandler<ParamsShape> | Handler<ParamsShape>[]; | ||
export type Handler< | ||
export type Middleware< | ||
ParamsShape extends Record<string, string> = Record<string, string>, | ||
@@ -200,11 +200,11 @@ > = SingleHandler<ParamsShape> | Handler<ParamsShape>[]; | ||
} | ||
use = (...handlers: Handler<{}>[]) => { | ||
use = (...handlers: Handler[]) => { | ||
return this.all('*', handlers); | ||
}; | ||
on404 = (...handlers: SingleHandler<Record<string, string>>[]) => { | ||
this._on404Handlers.push(...handlers.flat(9)); | ||
on404 = (...handlers: Handler[]) => { | ||
this._on404Handlers.push(...(handlers.flat(9) as SingleHandler[])); | ||
return this; | ||
}; | ||
on500 = (...handlers: SingleHandler<Record<string, string>>[]) => { | ||
this._on500Handlers.push(...handlers.flat(9)); | ||
on500 = (...handlers: Handler[]) => { | ||
this._on500Handlers.push(...(handlers.flat(9) as SingleHandler[])); | ||
return this; | ||
@@ -211,0 +211,0 @@ }; |
import Context from '../../Context/Context'; | ||
import { Middleware, SingleHandler } from '../../HttpRouter/HttpRouter'; | ||
import { | ||
Handler, | ||
Middleware, | ||
SingleHandler, | ||
} from '../../HttpRouter/HttpRouter'; | ||
@@ -10,3 +14,3 @@ export type ApplyHandlerIfArgs = { | ||
) => Promise<boolean> | boolean; | ||
handler: SingleHandler; | ||
handler: Handler; | ||
}; | ||
@@ -22,2 +26,3 @@ | ||
} | ||
const handlers = [conditions.handler].flat(9) as SingleHandler[]; | ||
return async (c, next) => { | ||
@@ -33,5 +38,10 @@ if (await conditions.requestCondition!(c)) { | ||
}; | ||
return conditions.handler(c, conditionalNext); | ||
for (const handler of handlers) { | ||
const resp = await handler(c, conditionalNext); | ||
if (resp instanceof Response) { | ||
return resp; | ||
} | ||
} | ||
} | ||
}; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2203742
2517
1599
Updatedfile-type@^19.6.0
Updatedlru-cache@^11.0.2