Comparing version 3.0.0 to 3.1.0
@@ -63,3 +63,3 @@ // Generated by dts-bundle-generator v9.5.1 | ||
arrayBuffer(): ArrayBufferLike; | ||
readableStream(chunkSize?: number): ReadableStream<Uint8Array>; | ||
readableStream(chunkSize?: number): ReadableStream<Uint8Array<ArrayBufferLike>>; | ||
json(): any; | ||
@@ -149,3 +149,2 @@ } | ||
export type FileResponseOptions = { | ||
range?: string; | ||
chunkSize?: number; | ||
@@ -155,7 +154,5 @@ disposition?: "inline" | "attachment"; | ||
}; | ||
export function file(filenameOrBunFile: string | BunFile, fileOptions?: FileResponseOptions): Promise<Response>; | ||
export type SseSend = (eventName: string, data?: string | object, id?: string, retry?: number) => void | Promise<void>; | ||
export type SseClose = () => void | Promise<void>; | ||
export type SseSetupFunction = (send: SseSend, close: SseClose) => void | (() => void); | ||
export function sse(signal: AbortSignal, setup: SseSetupFunction, init?: ResponseInit): Response; | ||
export declare class Context<ParamsShape extends Record<string, string> = Record<string, string>> { | ||
@@ -278,14 +275,26 @@ /** The raw request object */ | ||
export function ms(expression: string | number): number; | ||
export function buildFileResponse({ file, acceptRanges, chunkSize, rangeHeader, method, }: { | ||
file: BunFile; | ||
acceptRanges: boolean; | ||
chunkSize?: number; | ||
rangeHeader?: string | null; | ||
method: string; | ||
}): Promise<Response>; | ||
export type RangeInformation = { | ||
rangeHeader?: string | null | false; | ||
totalFileSize: number; | ||
defaultChunkSize?: number; | ||
}; | ||
export function parseRangeHeader({ rangeHeader, totalFileSize, defaultChunkSize, }: RangeInformation): { | ||
slice: null; | ||
contentLength: number; | ||
status: number; | ||
} | { | ||
slice: null; | ||
contentLength: null; | ||
status: number; | ||
} | { | ||
slice: { | ||
start: number; | ||
end: number; | ||
}; | ||
contentLength: number; | ||
status: number; | ||
}; | ||
export type Factory = (body: string, init?: ResponseInit) => Response; | ||
export function factory(contentType: string): Factory; | ||
export function json(this: Context, data: any, init?: ResponseInit): Response; | ||
export function redirect(url: string, status?: number): Response; | ||
export {}; |
14
index.ts
@@ -48,16 +48,10 @@ export { default as Context } from './src/Context/Context'; | ||
export { default as ms } from './src/ms/ms'; | ||
export { default as buildFileResponse } from './src/responseFactories/buildFileResponse'; | ||
export { default as factory } from './src/responseFactories/factory'; | ||
export { default as parseRangeHeader } from './src/parseRangeHeader/parseRangeHeader'; | ||
export { default as factory } from './src/responseFactories/factory/factory'; | ||
export { type FileResponseOptions } from './src/responseFactories/file/file'; | ||
export { | ||
default as file, | ||
type FileResponseOptions, | ||
} from './src/responseFactories/file'; | ||
export { default as json } from './src/responseFactories/json'; | ||
export { default as redirect } from './src/responseFactories/redirect'; | ||
export { | ||
default as sse, | ||
type SseClose, | ||
type SseSend, | ||
type SseSetupFunction, | ||
} from './src/responseFactories/sse'; | ||
} from './src/responseFactories/sse/sse'; | ||
export { | ||
@@ -64,0 +58,0 @@ default as SocketRouter, |
{ | ||
"name": "bunshine", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"module": "server/server.ts", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -5,11 +5,10 @@ # Bunshine | ||
<img alt="Bunshine Logo" src="https://github.com/kensnyder/bunshine/raw/main/assets/bunshine-logo.png?v=3.0.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.1.0" 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://www.npmjs.com/package/bunshine?activeTab=dependencies) | ||
 | ||
[](https://deepscan.io/dashboard#view=project&tid=24409&pid=27605&bid=884000) | ||
[](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://www.npmjs.com/package/bunshine?activeTab=dependencies) | ||
 | ||
[](https://opensource.org/licenses/ISC) | ||
@@ -208,2 +207,16 @@ ## Installation | ||
And `c` is destructureable. For example, you can write: | ||
```ts | ||
import { HttpRouter } from 'bunshine'; | ||
const app = new HttpRouter(); | ||
app.get('/', ({ url, text }) => { | ||
return text('Hello at ' + url.pathname); | ||
}); | ||
app.listen({ port: 3100, reusePort: true }); | ||
``` | ||
## Serving static files | ||
@@ -427,3 +440,3 @@ | ||
// Bunshine accepts any number of middleware functions in parameters or arrays | ||
// Bunshine accepts middleware as arguments or arrays, ultimately flattening to one array | ||
// so the following are equivalent | ||
@@ -434,3 +447,3 @@ app.get('/posts', middleware1, middleware2, handler); | ||
// Why might this be useful? | ||
// Why might this flattening behavior be useful? | ||
// You can group multiple middlewares into one array and pass it to route definitions | ||
@@ -1022,3 +1035,3 @@ const adminMiddleware = [getAuthCookie, checkPermissions]; | ||
<img alt="devLogger" src="https://github.com/kensnyder/bunshine/raw/main/assets/devLogger-screenshot.png?v=3.0.0" width="524" height="78" /> | ||
<img alt="devLogger" src="https://github.com/kensnyder/bunshine/raw/main/assets/devLogger-screenshot.png?v=3.1.0" width="524" height="78" /> | ||
@@ -1039,5 +1052,5 @@ `prodLogger` outputs logs in JSON with the following shape: | ||
"runtime": "Bun v1.1.34", | ||
"poweredBy": "Bunshine v3.0.0", | ||
"poweredBy": "Bunshine v3.1.0", | ||
"machine": "server1", | ||
"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", | ||
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.1.0.0 Safari/537.36", | ||
"pid": 123 | ||
@@ -1059,5 +1072,5 @@ } | ||
"runtime": "Bun v1.1.34", | ||
"poweredBy": "Bunshine v3.0.0", | ||
"poweredBy": "Bunshine v3.1.0", | ||
"machine": "server1", | ||
"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", | ||
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.1.0.0 Safari/537.36", | ||
"pid": 123, | ||
@@ -1064,0 +1077,0 @@ "took": 5 |
import type { BunFile, Server } from 'bun'; | ||
import type HttpRouter from '../HttpRouter/HttpRouter'; | ||
import factory from '../responseFactories/factory'; | ||
import file, { type FileResponseOptions } from '../responseFactories/file'; | ||
import json from '../responseFactories/json'; | ||
import redirect from '../responseFactories/redirect'; | ||
import sse, { type SseSetupFunction } from '../responseFactories/sse'; | ||
import factory from '../responseFactories/factory/factory'; | ||
import file, { type FileResponseOptions } from '../responseFactories/file/file'; | ||
import json from '../responseFactories/json/json'; | ||
import redirect from '../responseFactories/redirect/redirect'; | ||
import sse, { type SseSetupFunction } from '../responseFactories/sse/sse'; | ||
@@ -77,3 +77,3 @@ const textPlain = factory('text/plain'); | ||
/** A shorthand for `new Response(null, { headers: { Location: url }, status: 301 })` */ | ||
redirect = (url: string, status = 302) => { | ||
redirect = (url: string, status?: number) => { | ||
return redirect(url, status); | ||
@@ -86,3 +86,3 @@ }; | ||
) => { | ||
return file(filenameOrBunFile, { | ||
return file.call(this, filenameOrBunFile, { | ||
range: this.request.headers.get('Range') || undefined, | ||
@@ -94,4 +94,4 @@ ...fileOptions, | ||
sse = (setup: SseSetupFunction, init: ResponseInit = {}) => { | ||
return sse(this.request.signal, setup, init); | ||
return sse.call(this, this.request.signal, setup, init); | ||
}; | ||
} |
@@ -6,3 +6,3 @@ import { BunFile } from 'bun'; | ||
// So far Bun has all the types you'd expect | ||
return file.type; | ||
return file.type || 'application/octet-stream'; | ||
} |
@@ -229,13 +229,8 @@ import type { ServeOptions, Server } from 'bun'; | ||
try { | ||
let result = handler(context, next); | ||
let result = await handler(context, next); | ||
if (result instanceof Response) { | ||
return result; | ||
} else { | ||
return next(); | ||
} | ||
if (typeof result?.then === 'function') { | ||
result = await result; | ||
if (result instanceof Response) { | ||
return result; | ||
} | ||
} | ||
return next(); | ||
} catch (e) { | ||
@@ -242,0 +237,0 @@ return errorHandler(e as Error); |
@@ -38,3 +38,6 @@ import type { ZlibCompressionOptions } from 'bun'; | ||
const resp = await next(); | ||
if (!isCompressibleMime(resp.headers.get('Content-Type'))) { | ||
if ( | ||
context.request.method === 'HEAD' || | ||
!isCompressibleMime(resp.headers.get('Content-Type')) | ||
) { | ||
return resp; | ||
@@ -41,0 +44,0 @@ } |
import path from 'path'; | ||
import type { Middleware } from '../../HttpRouter/HttpRouter'; | ||
import ms from '../../ms/ms'; | ||
import buildFileResponse from '../../responseFactories/buildFileResponse'; | ||
@@ -52,9 +51,6 @@ // see https://expressjs.com/en/4x/api.html#express.static | ||
} | ||
// get file path | ||
// get full file path | ||
const filePath = path.join(directory, filename); | ||
// init file | ||
let file = Bun.file(filePath); | ||
// handle existence | ||
let exists = await file.exists(); | ||
// console.log('----------=========------- exists?', { exists, filePath }); | ||
// handle index files | ||
@@ -72,2 +68,3 @@ if (!exists && index.length > 0) { | ||
} | ||
// otherwise truly cannot find it | ||
if (!exists) { | ||
@@ -79,17 +76,5 @@ if (fallthrough) { | ||
} | ||
const rangeHeader = c.request.headers.get('range'); | ||
const response = await buildFileResponse({ | ||
file, | ||
const response = await c.file(file, { | ||
acceptRanges, | ||
chunkSize: 0, | ||
rangeHeader, | ||
method: c.request.method, | ||
}); | ||
// add last modified | ||
if (lastModified) { | ||
response.headers.set( | ||
'Last-Modified', | ||
new Date(file.lastModified).toUTCString() | ||
); | ||
} | ||
// add Cache-Control header | ||
@@ -99,2 +84,5 @@ if (cacheControlHeader) { | ||
} | ||
if (lastModified === false) { | ||
response.headers.delete('Last-Modified'); | ||
} | ||
return response; | ||
@@ -101,0 +89,0 @@ }; |
@@ -141,3 +141,6 @@ import { Server, ServerWebSocket, ServerWebSocketSendStatus } from 'bun'; | ||
buffer() { | ||
return Buffer.from(this._rawMessage); | ||
if (typeof this._rawMessage === 'string') { | ||
return Buffer.from(this._rawMessage); | ||
} | ||
return this._rawMessage; | ||
} | ||
@@ -144,0 +147,0 @@ arrayBuffer() { |
Sorry, the diff of this file is not supported yet
819536
91
2286
1411