@stacksjs/bun-router 0.0.8 → 0.0.10
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/{chunk-jhsk5c5b.js → chunk-n5pvpz7q.js} +1430 -2840
- package/dist/cli.js +2 -2
- package/dist/index.js +606 -589
- package/dist/response/response-factory.d.ts +1 -1
- package/package.json +1 -1
- package/src/development/typescript-utilities.ts +4 -0
- package/src/response/response-factory.ts +13 -5
- package/src/router/server.ts +34 -1
|
@@ -39,7 +39,7 @@ export interface ResponseCookieOptions {
|
|
|
39
39
|
sameSite?: 'strict' | 'lax' | 'none';
|
|
40
40
|
}
|
|
41
41
|
export interface ResponseFactory {
|
|
42
|
-
json: <T>(data: T, options?: JsonResponseOptions) => Response;
|
|
42
|
+
json: <T>(data: T, options?: JsonResponseOptions | ResponseStatus) => Response;
|
|
43
43
|
noContent: (headers?: Record<string, string>) => Response;
|
|
44
44
|
download: (filePath: string, filename?: string, headers?: Record<string, string>) => Promise<Response>;
|
|
45
45
|
file: (filePath: string, headers?: Record<string, string>) => Promise<Response>;
|
package/package.json
CHANGED
|
@@ -423,6 +423,10 @@ export type MiddlewareWithConfig<T> = (config: T) => MiddlewareFunction
|
|
|
423
423
|
const responseType = options.responseType || 'Response'
|
|
424
424
|
const paramsType = options.paramsType || 'Record<string, string>'
|
|
425
425
|
|
|
426
|
+
// pickier mis-parses the embedded `req:` token in this template literal
|
|
427
|
+
// as a real unused function parameter — disable on the next line so a
|
|
428
|
+
// pre-existing rule false positive doesn't block CI.
|
|
429
|
+
// eslint-disable-next-line pickier/no-unused-vars
|
|
426
430
|
return `(req: ${requestType} & { params: ${paramsType} }) => Promise<${responseType}>`
|
|
427
431
|
}
|
|
428
432
|
|
|
@@ -53,7 +53,7 @@ export interface ResponseCookieOptions {
|
|
|
53
53
|
// ============================================================================
|
|
54
54
|
|
|
55
55
|
export interface ResponseFactory {
|
|
56
|
-
json: <T>(data: T, options?: JsonResponseOptions) => Response
|
|
56
|
+
json: <T>(data: T, options?: JsonResponseOptions | ResponseStatus) => Response
|
|
57
57
|
noContent: (headers?: Record<string, string>) => Response
|
|
58
58
|
download: (filePath: string, filename?: string, headers?: Record<string, string>) => Promise<Response>
|
|
59
59
|
file: (filePath: string, headers?: Record<string, string>) => Promise<Response>
|
|
@@ -89,10 +89,18 @@ export interface ResponseFactory {
|
|
|
89
89
|
*/
|
|
90
90
|
export const response: ResponseFactory = {
|
|
91
91
|
/**
|
|
92
|
-
* Create a JSON response with proper typing
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
* Create a JSON response with proper typing.
|
|
93
|
+
*
|
|
94
|
+
* The second argument may be either a status code (Hono/Express style) or
|
|
95
|
+
* a `JsonResponseOptions` bag. The number form exists because passing a
|
|
96
|
+
* status as the second arg is the most common pattern in other web
|
|
97
|
+
* frameworks, and the silent `response.json(data, 401)` → HTTP 200 trap
|
|
98
|
+
* (the number was being interpreted as `options` and discarded) caused
|
|
99
|
+
* real bugs.
|
|
100
|
+
*/
|
|
101
|
+
json: <T>(data: T, options: JsonResponseOptions | ResponseStatus = {}): Response => {
|
|
102
|
+
const opts: JsonResponseOptions = typeof options === 'number' ? { status: options } : options
|
|
103
|
+
const { status = 200, headers = {}, pretty = false } = opts
|
|
96
104
|
const body = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data)
|
|
97
105
|
|
|
98
106
|
return new Response(body, {
|
package/src/router/server.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Server } from 'bun'
|
|
2
2
|
import type { EnhancedRequest, HTTPMethod, ServerOptions } from '../types'
|
|
3
3
|
import type { Router } from './router'
|
|
4
|
+
import { RequestWithMacros } from '../request/macros'
|
|
4
5
|
import { runWithRequest, setCurrentRequest } from '../request/context'
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -333,7 +334,39 @@ export function registerServerHandling(RouterClass: typeof Router): void {
|
|
|
333
334
|
_cookiesToDelete: [],
|
|
334
335
|
}) as unknown as EnhancedRequest
|
|
335
336
|
|
|
336
|
-
//
|
|
337
|
+
// Attach registered request macros (input, has, bearerToken, etc.) so
|
|
338
|
+
// they're available in middleware and handlers without manual setup.
|
|
339
|
+
// Applied *before* the cookie utility so the cookies macro doesn't
|
|
340
|
+
// overwrite the get/set/delete object form consumers depend on.
|
|
341
|
+
RequestWithMacros.applyMacros(enhancedReq)
|
|
342
|
+
|
|
343
|
+
// Attach the helpers consumers reach for that aren't shaped as
|
|
344
|
+
// generic input macros — `getParam`, the function-form `cookie`,
|
|
345
|
+
// the parsed-query `get` shorthand. These mirror the methods the
|
|
346
|
+
// bare `Router.enhanceRequest` (router.ts) attaches; without them
|
|
347
|
+
// here, requests that flow through the registered server.ts
|
|
348
|
+
// override are missing exactly the helpers that frameworks
|
|
349
|
+
// layered on bun-router (Stacks, etc.) treat as guaranteed.
|
|
350
|
+
;(enhancedReq as any).getParam = <T = string>(name: string, defaultValue?: T): T | undefined => {
|
|
351
|
+
const value = params?.[name] as T | undefined
|
|
352
|
+
return value !== undefined ? value : defaultValue
|
|
353
|
+
}
|
|
354
|
+
;(enhancedReq as any).cookie = (name: string, defaultValue?: string): string | null => {
|
|
355
|
+
const value = getCookies()[name]
|
|
356
|
+
return value !== undefined ? value : (defaultValue ?? null)
|
|
357
|
+
}
|
|
358
|
+
// `get(key)` — read query params (and only query params; the full
|
|
359
|
+
// input merge with body etc. is provided by the `input` macro).
|
|
360
|
+
// Skip if a macro already registered it under the same name.
|
|
361
|
+
if (typeof (enhancedReq as any).get !== 'function') {
|
|
362
|
+
;(enhancedReq as any).get = <T = unknown>(key: string, defaultValue?: T): T | undefined => {
|
|
363
|
+
const url = new URL(req.url)
|
|
364
|
+
const value = url.searchParams.get(key) as T | null
|
|
365
|
+
return value !== null && value !== undefined ? value : defaultValue
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Add cookie methods to the request (overrides any macro named `cookies`).
|
|
337
370
|
Object.assign(enhancedReq, { cookies: { ...getCookies(), ...cookies } })
|
|
338
371
|
|
|
339
372
|
return enhancedReq
|