@krisanalfa/bunest-adapter 0.0.1
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/LICENSE +21 -0
- package/README.md +866 -0
- package/dist/bun.adapter.d.ts +93 -0
- package/dist/bun.file.interceptor.d.ts +9 -0
- package/dist/bun.request.d.ts +339 -0
- package/dist/bun.response.d.ts +251 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1089 -0
- package/dist/index.js.map +17 -0
- package/package.json +66 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../lib/bun.adapter.ts", "../lib/bun.body-parser.middleware.ts", "../lib/bun.cors.middleware.ts", "../lib/bun.middleware-engine.ts", "../lib/bun.request.ts", "../lib/bun.response.ts", "../lib/bun.version-filter.middleware.ts", "../lib/bun.file.interceptor.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n CorsOptions,\n CorsOptionsDelegate,\n} from '@nestjs/common/interfaces/external/cors-options.interface.js'\nimport {\n ErrorHandler,\n RequestHandler,\n} from '@nestjs/common/interfaces/index.js'\nimport {\n Logger,\n NestApplicationOptions,\n RequestMethod,\n VersioningOptions,\n} from '@nestjs/common'\nimport { BunRequest as NativeRequest, Serve, Server, randomUUIDv7 } from 'bun'\nimport { AbstractHttpAdapter } from '@nestjs/core'\nimport { VersionValue } from '@nestjs/common/interfaces/version-options.interface.js'\n\nimport { BunBodyParserMiddleware } from './bun.body-parser.middleware.js'\nimport { BunCorsMiddleware } from './bun.cors.middleware.js'\nimport { BunMiddlewareEngine } from './bun.middleware-engine.js'\nimport { BunRequest } from './bun.request.js'\nimport { BunResponse } from './bun.response.js'\nimport { BunVersionFilterMiddleware } from './bun.version-filter.middleware.js'\n\n// Static method map - use direct string lookup for hot path\nconst REQUEST_METHOD_STRINGS: readonly string[] = [\n 'GET', // 0\n 'POST', // 1\n 'PUT', // 2\n 'DELETE', // 3\n 'PATCH', // 4\n 'ALL', // 5\n 'OPTIONS', // 6\n 'HEAD', // 7\n 'SEARCH', // 8\n 'PROPFIND', // 9\n 'PROPPATCH', // 10\n 'MKCOL', // 11\n 'COPY', // 12\n 'MOVE', // 13\n 'LOCK', // 14\n 'UNLOCK', // 15\n]\n\ntype PathHandler = Partial<\n Record<\n Serve.HTTPMethod,\n Serve.Handler<NativeRequest, Server<unknown>, Response> | Response\n >\n>\n\nexport class BunAdapter extends AbstractHttpAdapter<\n Server<unknown>,\n BunRequest,\n BunResponse\n> {\n private readonly logger: Logger = new Logger('BunAdapter', { timestamp: true })\n private readonly middlewareEngine = new BunMiddlewareEngine()\n private useVersioning = false\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n private readonly routes: Record<string, PathHandler> = Object.create(null) // Use null prototype for faster lookup\n\n // Store multiple handlers per route/method for version chaining\n private readonly routeHandlers = new Map<\n string,\n RequestHandler<BunRequest, BunResponse>[]\n >()\n\n private notFoundHandler: RequestHandler<BunRequest, BunResponse> = (\n req,\n res,\n ) => {\n res.setStatus(404)\n res.end({ message: 'Not Found' })\n }\n\n constructor(private bunServeOptions: Pick<Serve.Options<unknown>, 'development' | 'maxRequestBodySize' | 'idleTimeout' | 'id' | 'tls'> = {\n development: false,\n id: randomUUIDv7(),\n }) {\n super()\n }\n\n use(middleware: RequestHandler<BunRequest, BunResponse>): void {\n this.middlewareEngine.useGlobal(middleware)\n }\n\n get(handler: RequestHandler<BunRequest, BunResponse>): void\n get(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n get(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n const { path, handler } = this.parseRouteHandler(\n pathOrHandler,\n maybeHandler,\n )\n this.delegateRouteHandler('GET', path, handler)\n }\n\n post(handler: RequestHandler<BunRequest, BunResponse>): void\n post(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n post(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n const { path, handler } = this.parseRouteHandler(\n pathOrHandler,\n maybeHandler,\n )\n this.delegateRouteHandler('POST', path, handler)\n }\n\n put(handler: RequestHandler<BunRequest, BunResponse>): void\n put(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n put(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n const { path, handler } = this.parseRouteHandler(\n pathOrHandler,\n maybeHandler,\n )\n this.delegateRouteHandler('PUT', path, handler)\n }\n\n patch(handler: RequestHandler<BunRequest, BunResponse>): void\n patch(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n patch(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n const { path, handler } = this.parseRouteHandler(\n pathOrHandler,\n maybeHandler,\n )\n this.delegateRouteHandler('PATCH', path, handler)\n }\n\n delete(handler: RequestHandler<BunRequest, BunResponse>): void\n delete(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n delete(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n const { path, handler } = this.parseRouteHandler(\n pathOrHandler,\n maybeHandler,\n )\n this.delegateRouteHandler('DELETE', path, handler)\n }\n\n head(handler: RequestHandler<BunRequest, BunResponse>): void\n head(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n head(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n const { path, handler } = this.parseRouteHandler(\n pathOrHandler,\n maybeHandler,\n )\n this.delegateRouteHandler('HEAD', path, handler)\n }\n\n options(handler: RequestHandler<BunRequest, BunResponse>): void\n options(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n options(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n const { path, handler } = this.parseRouteHandler(\n pathOrHandler,\n maybeHandler,\n )\n this.delegateRouteHandler('OPTIONS', path, handler)\n }\n\n all(handler: RequestHandler<BunRequest, BunResponse>): void\n all(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n all(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n propfind(handler: RequestHandler<BunRequest, BunResponse>): void\n propfind(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n propfind(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n proppatch(handler: RequestHandler<BunRequest, BunResponse>): void\n proppatch(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n proppatch(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n mkcol(handler: RequestHandler<BunRequest, BunResponse>): void\n mkcol(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n mkcol(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n copy(handler: RequestHandler<BunRequest, BunResponse>): void\n copy(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n copy(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n move(handler: RequestHandler<BunRequest, BunResponse>): void\n move(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n move(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n lock(handler: RequestHandler<BunRequest, BunResponse>): void\n lock(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n lock(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n unlock(handler: RequestHandler<BunRequest, BunResponse>): void\n unlock(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n unlock(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n search(handler: RequestHandler<BunRequest, BunResponse>): void\n search(path: unknown, handler: RequestHandler<BunRequest, BunResponse>): void\n search(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n pathOrHandler: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): void {\n throw new Error('Not supported.')\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n useStaticAssets(...args: unknown[]) {\n throw new Error('Not supported.')\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setViewEngine(engine: string) {\n throw new Error('Not supported.')\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n render(response: unknown, view: string, options: unknown) {\n throw new Error('Not supported.')\n }\n\n async close() {\n await this.httpServer.stop()\n }\n\n initHttpServer(options: NestApplicationOptions) {\n // Set dummy server to satisfy AbstractHttpAdapter requirements\n this.setHttpServer({\n once: () => { /* noop: Nest use this to listen for \"error\" event */ },\n address: () => ({ address: '0.0.0.0', port: 0 }),\n removeListener: () => { /* noop: Nest may use this to remove \"error\" listener */ },\n stop: () => { /* noop */ },\n } as unknown as Server<unknown>)\n\n if (options.httpsOptions) {\n this.bunServeOptions.tls = {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n key: options.httpsOptions.key,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n cert: options.httpsOptions.cert,\n passphrase: options.httpsOptions.passphrase,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n ca: options.httpsOptions.ca,\n ciphers: options.httpsOptions.ciphers,\n secureOptions: options.httpsOptions.secureOptions,\n rejectUnauthorized: options.httpsOptions.rejectUnauthorized,\n requestCert: options.httpsOptions.requestCert,\n }\n }\n }\n\n getRequestHostname(request: BunRequest) {\n return request.hostname\n }\n\n getRequestMethod(request: BunRequest) {\n return request.method\n }\n\n getRequestUrl(request: BunRequest) {\n return request.pathname\n }\n\n status(response: BunResponse, statusCode: number) {\n response.setStatus(statusCode)\n }\n\n reply(response: BunResponse, body: unknown, statusCode?: number) {\n if (statusCode) {\n response.setStatus(statusCode)\n }\n\n response.end(body)\n }\n\n end(response: BunResponse, message?: string) {\n response.end(message)\n }\n\n redirect(response: BunResponse, statusCode: number, url: string) {\n response.redirect(url, statusCode)\n }\n\n setErrorHandler(\n handler: ErrorHandler<BunRequest, BunResponse>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n prefix?: string,\n ) {\n this.middlewareEngine.useErrorHandler(handler)\n }\n\n setNotFoundHandler(\n handler: RequestHandler<BunRequest, BunResponse>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n prefix?: string,\n ) {\n this.notFoundHandler = handler\n this.middlewareEngine.useNotFoundHandler(handler)\n }\n\n isHeadersSent(response: BunResponse): boolean {\n return response.isEnded()\n }\n\n getHeader(response: BunResponse, name: string): string | null {\n return response.getHeader(name)\n }\n\n setHeader(response: BunResponse, name: string, value: string) {\n response.setHeader(name, value)\n }\n\n appendHeader(response: BunResponse, name: string, value: string) {\n response.appendHeader(name, value)\n }\n\n registerParserMiddleware(prefix?: string, rawBody?: boolean) {\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n this.logger.log(`Registering Body Parser Middleware with prefix: ${prefix || '/'} and rawBody: ${rawBody ? 'true' : 'false'}`)\n const bodyParser = new BunBodyParserMiddleware({ prefix, rawBody })\n this.middlewareEngine.useGlobal(bodyParser.run.bind(bodyParser))\n }\n\n enableCors(\n options?: CorsOptions | CorsOptionsDelegate<BunRequest>,\n prefix?: string,\n ) {\n this.logger.log(`Enabling CORS Middleware with prefix: ${prefix ?? '/'}`)\n const corsMiddleware = new BunCorsMiddleware({ corsOptions: options, prefix })\n this.middlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware))\n }\n\n createMiddlewareFactory(\n requestMethod: RequestMethod,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n ): (path: string, callback: Function) => void {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n return (path: string, callback: Function) => {\n // Map RequestMethod enum to string method name\n const methodName = this.mapRequestMethodToString(requestMethod)\n\n // Handle wildcard routes (applies to all paths)\n // NestJS uses \"/*\" or \"*\" for wildcard routes\n if (path === '*' || path === '/*') {\n this.middlewareEngine.useWildcard(\n methodName,\n callback as RequestHandler<BunRequest, BunResponse>,\n )\n return\n }\n\n // Normalize path by removing trailing slash (except for root \"/\")\n const normalizedPath = path === '/' ? path : path.replace(/\\/$/, '')\n this.middlewareEngine.useRoute(\n methodName,\n normalizedPath,\n callback as RequestHandler<BunRequest, BunResponse>,\n )\n }\n }\n\n getType(): string {\n return 'bun'\n }\n\n applyVersionFilter(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n handler: Function,\n version: VersionValue,\n versioningOptions: VersioningOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n ): (req: BunRequest, res: BunResponse, next: () => void) => Function {\n this.logger.log(`Applying Version Filter Middleware for version: ${JSON.stringify(version)}`)\n this.useVersioning = true\n return BunVersionFilterMiddleware.createFilter(\n handler as (req: BunRequest, res: BunResponse, next: () => void) => unknown,\n version,\n versioningOptions,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n ) as (req: BunRequest, res: BunResponse, next: () => void) => Function\n }\n\n /**\n * Start listening on the specified port and hostname.\n * @param port The port number or Unix socket path to listen on.\n * @param callback Optional callback to invoke once the server is listening.\n */\n listen(port: string | number, callback?: () => void): void\n /**\n * Start listening on the specified port and hostname.\n * @param port The port number or Unix socket path to listen on.\n * @param hostname The hostname to bind to.\n * @param callback Optional callback to invoke once the server is listening.\n */\n listen(port: string | number, hostname: string, callback?: () => void): void\n /**\n * Start listening on the specified port and hostname.\n * @param port The port number or Unix socket path to listen on.\n * @param hostnameOrCallback The hostname to bind to or the callback function.\n * @param maybeCallback Optional callback to invoke once the server is listening.\n */\n listen(\n port: string | number,\n hostnameOrCallback?: string | (() => void),\n maybeCallback?: () => void,\n ): void {\n const hostname\n = typeof hostnameOrCallback === 'string' ? hostnameOrCallback : 'localhost'\n const callback\n = typeof hostnameOrCallback === 'function'\n ? hostnameOrCallback\n : maybeCallback\n\n // Capture references for closure - avoid 'this' lookup in hot path\n const middlewareEngine = this.middlewareEngine\n const notFoundHandler = this.notFoundHandler\n\n const fetch = async (request: NativeRequest): Promise<Response> => {\n const bunRequest = new BunRequest(request)\n const bunResponse = new BunResponse()\n // Inline property access for hot path\n await middlewareEngine.run({\n req: bunRequest,\n res: bunResponse,\n method: bunRequest.method,\n path: bunRequest.pathname,\n requestHandler: notFoundHandler,\n })\n return bunResponse.res()\n }\n\n const omit = <T extends object, K extends keyof T>(\n obj: T,\n ...keys: K[]\n ): Omit<T, K> => {\n const result = { ...obj }\n for (const key of keys) {\n Reflect.deleteProperty(result, key)\n }\n return result\n }\n\n const server = typeof port === 'number' || !isNaN(Number(port))\n ? Bun.serve<unknown>({\n ...this.bunServeOptions,\n hostname,\n port,\n routes: this.routes,\n fetch,\n })\n : Bun.serve<unknown>({\n ...omit(this.bunServeOptions, 'idleTimeout'),\n unix: port,\n routes: this.routes,\n fetch,\n })\n\n if (typeof port === 'string' && isNaN(Number(port))) {\n this.logger.log(`Bun server listening on unix socket: ${port}`)\n }\n\n callback?.()\n\n // Add `address` method to match Node.js Server interface\n Object.defineProperty(server, 'address', {\n configurable: true,\n enumerable: true,\n get: () => ({ address: server.hostname, port: server.port }),\n })\n\n this.setHttpServer(server)\n }\n\n private delegateRouteHandler(\n method: Serve.HTTPMethod,\n path: string,\n handler: RequestHandler<BunRequest, BunResponse>,\n ): void {\n // Use null prototype object for route if not exists\n if (!(path in this.routes)) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n this.routes[path] = Object.create(null)\n }\n\n const requestHandler = !this.useVersioning\n ? handler\n // Create handler that wraps array + fallback into a single callable\n // This avoids recreating the chained handler on every request\n : this.createChainedHandlerForVersioningResolution(\n this.createVersioningHandlers(method, path, handler),\n this.notFoundHandler,\n )\n\n this.routes[path][method] = async (request: NativeRequest): Promise<Response> => {\n const bunRequest = new BunRequest(request)\n const bunResponse = new BunResponse()\n\n await this.middlewareEngine.run({\n req: bunRequest,\n res: bunResponse,\n method,\n path,\n requestHandler,\n })\n\n return bunResponse.res()\n }\n }\n\n private createVersioningHandlers(\n method: Serve.HTTPMethod,\n path: string,\n handler: RequestHandler<BunRequest, BunResponse>,\n ) {\n // Store handler in the handlers array for chaining (versioning support)\n const routeKey = `${method}:${path}`\n let versioningHandlers = this.routeHandlers.get(routeKey)\n if (!versioningHandlers) {\n versioningHandlers = []\n this.routeHandlers.set(routeKey, versioningHandlers)\n }\n versioningHandlers.push(handler)\n\n return versioningHandlers\n }\n\n private async executeHandlerChain(\n handlers: RequestHandler<BunRequest, BunResponse>[],\n req: BunRequest,\n res: BunResponse,\n ): Promise<void> {\n const handlersLength = handlers.length\n let index = 0\n let shouldContinue = true\n\n while (shouldContinue && index < handlersLength && !res.isEnded()) {\n shouldContinue = false\n const currentIndex = index++\n const result = handlers[currentIndex](req, res, () => {\n shouldContinue = true\n }) as unknown\n if (result instanceof Promise) await result\n }\n }\n\n private createChainedHandlerForVersioningResolution(\n handlers: RequestHandler<BunRequest, BunResponse>[],\n notFoundHandler: RequestHandler<BunRequest, BunResponse>,\n ): RequestHandler<BunRequest, BunResponse> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n return (async (req: BunRequest, res: BunResponse, next?: Function): Promise<void> => {\n // First pass: discovery for versioning\n await this.executeHandlerChain(handlers, req, res)\n\n // Check for custom versioning candidates\n if (!res.isEnded() && BunVersionFilterMiddleware.hasCustomVersioningCandidates(req)) {\n const bestVersion = BunVersionFilterMiddleware.selectBestCustomVersionCandidate(req)\n\n if (bestVersion) {\n BunVersionFilterMiddleware.setCustomVersioningExecutionPhase(req, bestVersion)\n await this.executeHandlerChain(handlers, req, res)\n }\n }\n\n // If still not handled, call not found handler\n if (!res.isEnded()) {\n notFoundHandler(req, res, next)\n }\n }) as RequestHandler<BunRequest, BunResponse>\n }\n\n private mapRequestMethodToString(requestMethod: RequestMethod): string {\n return REQUEST_METHOD_STRINGS[requestMethod] ?? 'ALL'\n }\n\n private parseRouteHandler(handler: RequestHandler<BunRequest, BunResponse>): {\n path: string\n handler: RequestHandler<BunRequest, BunResponse>\n }\n private parseRouteHandler(\n path: unknown,\n handler?: RequestHandler<BunRequest, BunResponse>,\n ): { path: string, handler: RequestHandler<BunRequest, BunResponse> }\n private parseRouteHandler(\n pathOrHandler: unknown,\n maybeHandler?: RequestHandler<BunRequest, BunResponse>,\n ): { path: string, handler: RequestHandler<BunRequest, BunResponse> } {\n const path = typeof pathOrHandler === 'string' ? pathOrHandler : '/'\n const handler\n = typeof pathOrHandler === 'function'\n ? (pathOrHandler as RequestHandler<BunRequest, BunResponse>)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n : maybeHandler!\n return { path, handler }\n }\n}\n",
|
|
6
|
+
"import { BunRequest } from './bun.request.js'\nimport { BunResponse } from './bun.response.js'\n\n// Pre-computed method codes for fast comparison\nconst GET_CODE = 'GET'.charCodeAt(0) // 71\nconst HEAD_CODE = 'HEAD'.charCodeAt(0) // 72\nconst DELETE_CODE = 'DELETE'.charCodeAt(0) // 68\nconst OPTIONS_CODE = 'OPTIONS'.charCodeAt(0) // 79\n\nexport class BunBodyParserMiddleware {\n private readonly prefix: string | null\n private readonly rawBody: boolean\n private readonly prefixLen: number\n\n constructor(options?: { prefix?: string, rawBody?: boolean }) {\n this.prefix = options?.prefix ?? null\n this.prefixLen = this.prefix?.length ?? 0\n this.rawBody = options?.rawBody ?? false\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n async run(req: BunRequest, res: BunResponse, next?: Function): Promise<void> {\n // Fast path: skip body parsing for methods that don't have body\n // Use charCodeAt for fast string comparison\n const methodFirstChar = req.method.charCodeAt(0)\n if (\n methodFirstChar === GET_CODE // Most common case first\n || methodFirstChar === HEAD_CODE\n || methodFirstChar === DELETE_CODE\n || methodFirstChar === OPTIONS_CODE\n ) {\n next?.()\n return\n }\n\n // Check prefix if specified\n if (this.prefix !== null) {\n const pathname = req.pathname\n if (pathname.length < this.prefixLen || !pathname.startsWith(this.prefix)) {\n next?.()\n return\n }\n }\n\n if (this.rawBody) {\n req.setRawBody(await req.arrayBuffer())\n }\n\n await this.parseRequestBody(req)\n next?.()\n }\n\n private async parseRequestBody(req: BunRequest): Promise<void> {\n const contentType = req.headers.get('content-type')\n if (!contentType) {\n return\n }\n\n // Use indexOf for faster content-type checking\n if (contentType.includes('application/json')) {\n req.setBody(await req.json())\n return\n }\n\n if (contentType.includes('text/') || contentType.includes('application/text')) {\n req.setBody(await req.text())\n return\n }\n\n if (contentType.includes('form')) {\n await this.parseFormData(req)\n }\n }\n\n private async parseFormData(req: BunRequest): Promise<void> {\n const formData = await req.formData()\n const body: Record<string, string | File> = Object.create(null) as Record<string, string | File>\n let files: File[] | null = null\n let firstFile: File | null = null\n\n for (const [key, value] of formData.entries()) {\n body[key] = value\n // Fast file detection using 'size' property check\n if (this.isFile(value)) {\n if (firstFile === null) {\n firstFile = value\n files = [value]\n }\n else {\n files?.push(value)\n }\n }\n }\n\n req.setBody(body)\n\n if (firstFile !== null) {\n req.setFile(firstFile)\n }\n\n if (files !== null) {\n req.setFiles(files)\n }\n }\n\n private isFile(value: unknown): value is File {\n return typeof value === 'object' && value !== null && 'size' in value && 'name' in value && 'type' in value\n }\n}\n",
|
|
7
|
+
"import {\n CorsOptionsDelegate,\n CorsOptions as NestCorsOptions,\n} from '@nestjs/common/interfaces/external/cors-options.interface.js'\nimport { IncomingMessage, ServerResponse } from 'node:http'\nimport cors, { CorsOptions } from 'cors'\n\nimport { BunRequest } from './bun.request.js'\nimport { BunResponse } from './bun.response.js'\n\ntype NextFunction = ((err?: Error) => void) | undefined\n\nexport class BunCorsMiddleware {\n private readonly options?: NestCorsOptions | CorsOptionsDelegate<BunRequest>\n private readonly prefix?: string\n\n constructor(options?: {\n corsOptions?: NestCorsOptions | CorsOptionsDelegate<BunRequest>\n prefix?: string\n }) {\n this.options = options?.corsOptions\n this.prefix = options?.prefix\n }\n\n async run(\n req: BunRequest,\n res: BunResponse,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n next: NextFunction | Function,\n ): Promise<void> {\n const nextFn = next as NextFunction\n\n if (this.prefix && !req.pathname.startsWith(this.prefix)) {\n return nextFn?.()\n }\n\n const corsOptions = await this.resolveCorsOptions(req)\n const { nodeReq, nodeRes, isEnded } = this.createNodeAdapters(req, res)\n\n cors(corsOptions)(nodeReq, nodeRes, (err?: Error) => {\n if (err) return nextFn?.(err)\n if (!isEnded()) nextFn?.()\n })\n }\n\n private async resolveCorsOptions(\n req: BunRequest,\n ): Promise<CorsOptions | undefined> {\n const options = this.options\n if (typeof options === 'function') {\n return new Promise((resolve, reject) => {\n options(req, (err: Error | null, opts: NestCorsOptions | undefined) => {\n if (err) reject(err)\n else resolve(opts as CorsOptions)\n })\n })\n }\n if (!options) return undefined\n return {\n origin: options.origin as CorsOptions['origin'],\n methods: options.methods,\n allowedHeaders: options.allowedHeaders,\n exposedHeaders: options.exposedHeaders,\n credentials: options.credentials,\n maxAge: options.maxAge,\n preflightContinue: options.preflightContinue,\n optionsSuccessStatus: options.optionsSuccessStatus,\n }\n }\n\n private createNodeAdapters(req: BunRequest, res: BunResponse) {\n const nodeReq = {\n method: req.method,\n headers: req.headers,\n url: req.pathname,\n } as unknown as IncomingMessage\n\n const nodeRes = {\n get statusCode() { return res.getStatus() },\n set statusCode(code: number) { res.setStatus(code) },\n setHeader: (key: string, value: string) => { res.setHeader(key, value) },\n end: (data?: unknown) => { res.end(data) },\n getHeader: (name: string) => res.getHeader(name),\n removeHeader: (name: string) => { res.removeHeader(name) },\n } as unknown as ServerResponse\n\n return { nodeReq, nodeRes, isEnded: () => res.isEnded() }\n }\n}\n",
|
|
8
|
+
"import { ErrorHandler, RequestHandler } from '@nestjs/common/interfaces/index.js'\nimport { ErrorLike } from 'bun'\n\nimport { BunRequest } from './bun.request.js'\nimport { BunResponse } from './bun.response.js'\n\ntype MiddlewareHandler = RequestHandler<BunRequest, BunResponse>\ninterface MiddlewareRunOptions {\n req: BunRequest\n res: BunResponse\n method: string\n path: string\n requestHandler: MiddlewareHandler\n}\n\n// Shared empty array to avoid allocations\nconst EMPTY_HANDLERS: readonly MiddlewareHandler[] = new Array<MiddlewareHandler>(0)\n\n// Reusable noop function for error handler\nconst noop = (): void => { /* noop */ }\n\nexport class BunMiddlewareEngine {\n private readonly globalMiddlewares: MiddlewareHandler[] = []\n private readonly routeMiddleware = new Map<string, MiddlewareHandler[]>()\n // Group route middleware by method for faster prefix matching\n private readonly routeMiddlewareByMethod = new Map<string, Map<string, MiddlewareHandler[]>>()\n private readonly wildcardMiddleware = new Map<string, MiddlewareHandler[]>()\n private readonly middlewareCache = new Map<string, MiddlewareHandler[]>()\n private errorHandler: ErrorHandler<BunRequest, BunResponse> | null = null\n private notFoundHandler: MiddlewareHandler | null = null\n\n useGlobal(middleware: MiddlewareHandler): void {\n this.globalMiddlewares.push(middleware)\n }\n\n useRoute(method: string, path: string, middleware: MiddlewareHandler): void {\n const key = `${method}:${path}`;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n (this.routeMiddleware.get(key) ?? (this.routeMiddleware.set(key, []).get(key)!)).push(middleware);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n (this.routeMiddlewareByMethod.get(method) ?? this.routeMiddlewareByMethod.set(method, new Map()).get(method)!)\n .set(path, ((this.routeMiddlewareByMethod.get(method)?.get(path)) ?? []))\n .get(path)!\n .push(middleware)\n }\n\n useWildcard(method: string, middleware: MiddlewareHandler): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n (this.wildcardMiddleware.get(method) ?? this.wildcardMiddleware.set(method, []).get(method)!).push(middleware)\n }\n\n useErrorHandler(handler: ErrorHandler<BunRequest, BunResponse>): void {\n this.errorHandler = handler\n }\n\n useNotFoundHandler(handler: MiddlewareHandler): void {\n this.notFoundHandler = handler\n }\n\n async run(options: MiddlewareRunOptions): Promise<BunResponse> {\n try {\n const middlewares = this.getMiddlewareChain(options.method, options.path)\n await this.executeChain(middlewares, options.requestHandler, options.req, options.res)\n return options.res\n }\n catch (error) {\n return this.handleError(error, options.req, options.res)\n }\n }\n\n private getMiddlewareChain(method: string, path: string): MiddlewareHandler[] {\n const cacheKey = `${method}:${path}`\n let cached = this.middlewareCache.get(cacheKey)\n if (cached !== undefined) return cached\n\n cached = this.buildMiddlewareChain(method, path, cacheKey)\n this.middlewareCache.set(cacheKey, cached)\n return cached\n }\n\n private buildMiddlewareChain(\n method: string,\n path: string,\n cacheKey: string,\n ): MiddlewareHandler[] {\n // Minimize array operations and allocations\n const global = this.globalMiddlewares\n const globalLen = global.length\n const wildcardAll = this.wildcardMiddleware.get('ALL')\n const wildcardMethod = this.wildcardMiddleware.get(method)\n const routeMiddleware = this.findRouteMiddleware(method, path, cacheKey)\n\n const wildcardAllLen = wildcardAll?.length ?? 0\n const wildcardMethodLen = wildcardMethod?.length ?? 0\n const routeLen = routeMiddleware.length\n\n const totalLen = globalLen + wildcardAllLen + wildcardMethodLen + routeLen\n if (totalLen === 0) return EMPTY_HANDLERS as MiddlewareHandler[]\n\n // Avoid iterator overhead from for...of loops\n const chain = new Array<MiddlewareHandler>(totalLen)\n let idx = 0\n\n // Global middlewares\n for (let i = 0; i < globalLen; i++) chain[idx++] = global[i]\n // Wildcard middlewares\n if (wildcardAll) for (let i = 0; i < wildcardAllLen; i++) chain[idx++] = wildcardAll[i]\n // Method-specific wildcard middlewares\n if (wildcardMethod) for (let i = 0; i < wildcardMethodLen; i++) chain[idx++] = wildcardMethod[i]\n // Route-specific middlewares\n for (let i = 0; i < routeLen; i++) chain[idx++] = routeMiddleware[i]\n\n return chain\n }\n\n private findRouteMiddleware(\n method: string,\n path: string,\n cacheKey: string,\n ): readonly MiddlewareHandler[] {\n const exactMiddleware = this.routeMiddleware.get(cacheKey)\n if (exactMiddleware !== undefined) return exactMiddleware\n return this.findBestPrefixMatch(method, path)\n }\n\n private findBestPrefixMatch(\n method: string,\n path: string,\n ): readonly MiddlewareHandler[] {\n const methodMap = this.routeMiddlewareByMethod.get(method)\n if (!methodMap) return EMPTY_HANDLERS\n\n let bestMatch: MiddlewareHandler[] | null = null\n let bestMatchLength = 0\n const pathLen = path.length\n\n for (const [keyPath, middleware] of methodMap) {\n const keyPathLen = keyPath.length\n if (keyPathLen <= bestMatchLength || middleware.length === 0) continue\n\n // Fast path check: exact match or prefix match with /\n if (path === keyPath || (pathLen > keyPathLen && path.charCodeAt(keyPathLen) === 47 /* '/' */ && path.startsWith(keyPath))) {\n bestMatch = middleware\n bestMatchLength = keyPathLen\n }\n }\n\n return bestMatch ?? EMPTY_HANDLERS\n }\n\n private async executeChain(\n chain: MiddlewareHandler[],\n requestHandler: MiddlewareHandler,\n req: BunRequest,\n res: BunResponse,\n ): Promise<void> {\n const chainLength = chain.length\n let index = 0\n\n const next = async (err?: ErrorLike): Promise<void> => {\n if (err) throw err\n\n // Process middleware chain\n if (index < chainLength) {\n const handler = chain[index++]\n const result = handler(req, res, next) as unknown\n if (result instanceof Promise) await result\n return\n }\n\n // Process request handler at the end\n if (index === chainLength) {\n index++\n const result = requestHandler(req, res, next) as unknown\n if (result instanceof Promise) await result\n\n // If after the handler next is called again, throw not found\n if (index > chainLength) {\n const result = this.notFoundHandler?.(req, res, noop) as unknown\n if (result instanceof Promise) await result\n }\n }\n }\n\n await next()\n }\n\n private async handleError(\n error: unknown,\n req: BunRequest,\n res: BunResponse,\n ): Promise<BunResponse> {\n if (this.errorHandler !== null) {\n const result = this.errorHandler(error, req, res, noop) as unknown\n if (result instanceof Promise) await result\n return res\n }\n throw error\n }\n}\n",
|
|
9
|
+
"/* eslint-disable sonarjs/no-nested-assignment */\nimport { CookieMap, BunRequest as NativeRequest } from 'bun'\nimport { ParsedQs, parse } from 'qs'\n\n// Optimized headers type - use native Headers for hot-path .get()\ntype HeadersProxy = Record<string, string> & {\n get: (key: string) => string | null\n}\n\n// Pre-allocated empty object for Object.create(null) pattern\nconst NULL_PROTO = Object.getPrototypeOf(Object.create(null)) as object\n\n/**\n * A high-performance request wrapper for Bun's native request object.\n * Provides lazy parsing and caching for optimal performance in NestJS applications.\n *\n * @example\n * ```typescript\n * const bunRequest = new BunRequest(nativeRequest);\n * const pathname = bunRequest.pathname; // Lazily parsed\n * const query = bunRequest.query; // Parsed only when accessed\n * ```\n */\nexport class BunRequest {\n private _nativeHeaders: Headers\n private _headers: HeadersProxy | null = null\n private _hostname: string | null = null\n private _pathname: string | null = null\n private _query: ParsedQs | null = null\n private _body: unknown = null\n private _rawBody: ArrayBuffer | null = null\n private _file: File | null = null\n private _files: File[] | null = null\n private _settings: Map<string, unknown> | null = null\n\n // Cache URL parts at construction time for hot-path access\n private readonly _url: string\n private readonly _parsedUrl: URL\n readonly method: string\n readonly params: Record<string, string>\n\n constructor(private readonly nativeRequest: NativeRequest) {\n this._url = nativeRequest.url\n this._parsedUrl = new URL(this._url)\n this._nativeHeaders = nativeRequest.headers\n this.method = nativeRequest.method\n this.params = nativeRequest.params\n }\n\n /**\n * Gets the full URL of the request.\n *\n * @returns The complete URL string\n * @example\n * ```typescript\n * const url = request.url; // \"http://localhost:3000/api/users?page=1\"\n * ```\n */\n get url(): string { return this._url }\n\n /**\n * Gets the pathname portion of the URL.\n * Uses lazy parsing for optimal performance - the pathname is only extracted when first accessed.\n *\n * @returns The pathname component of the URL\n * @example\n * ```typescript\n * // For URL \"http://localhost:3000/api/users?page=1\"\n * const pathname = request.pathname; // \"/api/users\"\n * ```\n */\n get pathname(): string {\n return this._pathname ??= this._parsedUrl.pathname\n }\n\n /**\n * Gets the hostname portion of the URL.\n * Uses lazy parsing - the hostname is only extracted when first accessed.\n *\n * @returns The hostname component of the URL (without port)\n * @example\n * ```typescript\n * // For URL \"http://localhost:3000/api/users\"\n * const hostname = request.hostname; // \"localhost\"\n * ```\n */\n get hostname(): string {\n return this._hostname ??= this.headers.get('x-forwarded-host') ?? this._parsedUrl.hostname\n }\n\n /**\n * Gets all request headers as a key-value object.\n * Uses lazy parsing - headers are materialized only when first accessed.\n * All header keys are normalized to lowercase.\n *\n * @returns An object containing all headers with a .get() method for efficient lookups\n * @example\n * ```typescript\n * const headers = request.headers;\n * const contentType = headers['content-type']; // Direct access\n * const auth = headers.get('Authorization'); // Using .get() method\n * ```\n */\n get headers(): HeadersProxy {\n if (this._headers !== null) return this._headers\n const native = this._nativeHeaders\n // Create proxy that uses native .get() and materializes properties lazily\n const proxy = Object.create(NULL_PROTO) as HeadersProxy\n // Materialize all headers for NestJS decorators that iterate over keys\n native.forEach((value: string, key: string) => {\n proxy[key.toLowerCase()] = value\n })\n proxy.get = (key: string) => native.get(key)\n return this._headers = proxy\n }\n\n /**\n * Gets the parsed query parameters from the URL.\n * Uses lazy parsing - query string is only parsed when first accessed.\n *\n * @returns Parsed query parameters as an object\n * @example\n * ```typescript\n * // For URL \"http://localhost:3000/api/users?page=1&limit=10\"\n * const query = request.query;\n * console.log(query.page); // \"1\"\n * console.log(query.limit); // \"10\"\n * ```\n */\n get query(): ParsedQs {\n return this._query ??= parse(this._parsedUrl.searchParams.toString())\n }\n\n /**\n * Gets the parsed request body.\n *\n * @returns The parsed body content (could be JSON, form data, etc.)\n * @example\n * ```typescript\n * const body = request.body;\n * console.log(body); // { name: \"John\", email: \"john@example.com\" }\n * ```\n */\n get body(): unknown { return this._body }\n\n /**\n * Sets the parsed request body.\n * Typically used by body parser middleware.\n *\n * @param body - The parsed body content to set\n * @example\n * ```typescript\n * request.setBody({ name: \"John\", email: \"john@example.com\" });\n * ```\n */\n setBody(body: unknown): void { this._body = body }\n\n /**\n * Gets the raw request body as an ArrayBuffer.\n *\n * @returns The raw body data or null if not set\n * @example\n * ```typescript\n * const rawBody = request.rawBody;\n * if (rawBody) {\n * const text = new TextDecoder().decode(rawBody);\n * }\n * ```\n */\n get rawBody(): ArrayBuffer | null { return this._rawBody }\n\n /**\n * Sets the raw request body as an ArrayBuffer.\n *\n * @param rawBody - The raw body data to set\n * @example\n * ```typescript\n * const buffer = await request.arrayBuffer();\n * request.setRawBody(buffer);\n * ```\n */\n setRawBody(rawBody: ArrayBuffer): void { this._rawBody = rawBody }\n\n /**\n * Gets the uploaded file from the request.\n * Used for single file uploads.\n *\n * @returns The uploaded file or null if no file was uploaded\n * @example\n * ```typescript\n * const file = request.file;\n * if (file) {\n * console.log(file.name); // \"avatar.png\"\n * console.log(file.size); // 2048\n * }\n * ```\n */\n get file(): File | null { return this._file }\n\n /**\n * Sets the uploaded file in the request.\n * Typically used by file upload middleware.\n *\n * @param file - The file to set\n * @example\n * ```typescript\n * const formData = await request.formData();\n * const file = formData.get('avatar') as File;\n * request.setFile(file);\n * ```\n */\n setFile(file: File): void { this._file = file }\n\n /**\n * Gets all uploaded files from the request.\n * Used for multiple file uploads.\n *\n * @returns Array of uploaded files or null if no files were uploaded\n * @example\n * ```typescript\n * const files = request.files;\n * if (files) {\n * files.forEach(file => {\n * console.log(file.name, file.size);\n * });\n * }\n * ```\n */\n get files(): File[] | null { return this._files }\n\n /**\n * Sets multiple uploaded files in the request.\n * Typically used by file upload middleware.\n *\n * @param files - Array of files to set\n * @example\n * ```typescript\n * const formData = await request.formData();\n * const files = formData.getAll('attachments') as File[];\n * request.setFiles(files);\n * ```\n */\n setFiles(files: File[]): void { this._files = files }\n\n /**\n * Gets a custom setting/property stored in the request.\n * Useful for passing data between middleware and handlers.\n *\n * @param key - The setting key to retrieve\n * @returns The stored value or undefined if not found\n * @example\n * ```typescript\n * // In middleware\n * request.set('user', { id: 1, name: 'John' });\n *\n * // In handler\n * const user = request.get('user');\n * console.log(user); // { id: 1, name: 'John' }\n * ```\n */\n get(key: string): unknown { return this._settings?.get(key) }\n\n /**\n * Sets a custom setting/property in the request.\n * Useful for passing data between middleware and handlers.\n *\n * @param key - The setting key to store\n * @param value - The value to store\n * @example\n * ```typescript\n * request.set('user', { id: 1, name: 'John' });\n * request.set('startTime', Date.now());\n * ```\n */\n set(key: string, value: unknown): void {\n (this._settings ??= new Map()).set(key, value)\n }\n\n /**\n * Gets the AbortSignal for the request.\n * Can be used to detect if the request has been cancelled.\n *\n * @returns The request's AbortSignal\n * @example\n * ```typescript\n * const signal = request.signal;\n * signal.addEventListener('abort', () => {\n * console.log('Request was cancelled');\n * });\n * ```\n */\n get signal(): AbortSignal { return this.nativeRequest.signal }\n\n /**\n * Gets the cookies from the request.\n *\n * @returns A Map-like object containing all cookies\n * @example\n * ```typescript\n * const cookies = request.cookies;\n * const sessionId = cookies.get('sessionId');\n * console.log(sessionId?.value);\n * ```\n */\n get cookies(): CookieMap { return this.nativeRequest.cookies }\n\n /**\n * Parses the request body as JSON.\n *\n * @returns Promise that resolves to the parsed JSON data\n * @example\n * ```typescript\n * const data = await request.json();\n * console.log(data); // { name: \"John\", email: \"john@example.com\" }\n * ```\n */\n json(): Promise<unknown> { return this.nativeRequest.json() }\n\n /**\n * Reads the request body as text.\n *\n * @returns Promise that resolves to the body text\n * @example\n * ```typescript\n * const text = await request.text();\n * console.log(text); // \"Hello, World!\"\n * ```\n */\n text(): Promise<string> { return this.nativeRequest.text() }\n\n /**\n * Parses the request body as FormData.\n *\n * @returns Promise that resolves to the parsed FormData\n * @example\n * ```typescript\n * const formData = await request.formData();\n * const name = formData.get('name');\n * console.log(name); // \"John\"\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated, sonarjs/deprecation\n formData(): Promise<FormData> { return this.nativeRequest.formData() as unknown as Promise<FormData> }\n\n /**\n * Reads the request body as an ArrayBuffer.\n *\n * @returns Promise that resolves to the body as ArrayBuffer\n * @example\n * ```typescript\n * const buffer = await request.arrayBuffer();\n * console.log(buffer.byteLength); // 1024\n * ```\n */\n arrayBuffer(): Promise<ArrayBuffer> { return this.nativeRequest.arrayBuffer() }\n\n /**\n * Reads the request body as a Blob.\n *\n * @returns Promise that resolves to the body as Blob\n * @example\n * ```typescript\n * const blob = await request.blob();\n * console.log(blob.type); // \"image/png\"\n * ```\n */\n blob(): Promise<Blob> { return this.nativeRequest.blob() }\n\n /**\n * Reads the request body as a Uint8Array.\n *\n * @returns Promise that resolves to the body as Uint8Array\n * @example\n * ```typescript\n * const bytes = await request.bytes();\n * console.log(bytes.length); // 1024\n * ```\n */\n bytes(): Promise<Uint8Array> { return this.nativeRequest.bytes() }\n\n /**\n * Creates a deep clone of the request.\n * Clones both the native request and all cached properties.\n *\n * @returns A new BunRequest instance with cloned data\n * @example\n * ```typescript\n * const originalRequest = new BunRequest(nativeRequest);\n * const clonedRequest = originalRequest.clone();\n *\n * // Modifications to clone don't affect original\n * clonedRequest.set('user', { id: 1 });\n * console.log(originalRequest.get('user')); // undefined\n * ```\n */\n clone(): BunRequest {\n const cloned = new BunRequest(this.nativeRequest.clone())\n cloned._pathname = this._pathname\n cloned._body = this._body\n cloned._rawBody = this._rawBody\n cloned._file = this._file\n cloned._files = this._files\n cloned._headers = this._headers\n cloned._query = this._query\n cloned._settings = this._settings\n return cloned\n }\n}\n",
|
|
10
|
+
"/* eslint-disable sonarjs/no-nested-assignment */\nimport { BodyInit, Cookie, CookieInit, CookieMap, CookieStoreDeleteOptions } from 'bun'\nimport { StreamableFile } from '@nestjs/common'\n\n// Pre-allocated JSON content type header\nconst JSON_CONTENT_TYPE = 'application/json'\n\n/**\n * A high-performance response builder for Bun's native Response object.\n * Provides methods to build responses with headers, cookies, and various body types.\n * Uses lazy initialization and optimized response building for maximum performance.\n *\n * @example\n * ```typescript\n * const response = new BunResponse();\n * response.setStatus(200);\n * response.setHeader('Content-Type', 'application/json');\n * response.cookie('sessionId', 'abc123');\n * response.end({ message: 'Success' });\n * ```\n */\nexport class BunResponse {\n private resolve!: (value: Response) => void\n private readonly response: Promise<Response>\n private readonly cookieMap = new CookieMap()\n\n // Use Map for O(1) header operations - faster than Headers for small sets\n private _headers: Map<string, string> | null = null\n private statusCode = 200\n private ended = false\n // Cache for cookie headers to avoid repeated string operations\n private _cookieHeaderCache: string | null = null\n\n constructor() {\n // Keep constructor minimal to reduce allocation overhead\n this.response = new Promise<Response>((r) => {\n this.resolve = r\n })\n }\n\n // Lazy headers initialization\n private get headersMap(): Map<string, string> {\n return this._headers ??= new Map()\n }\n\n /**\n * Sets a cookie in the response.\n * Can be called with either a cookie options object or name-value pair.\n *\n * @param options - Cookie configuration object\n * @example\n * ```typescript\n * // Using name-value pair\n * response.cookie('sessionId', 'abc123');\n *\n * // Using options object\n * response.cookie({\n * name: 'sessionId',\n * value: 'abc123',\n * httpOnly: true,\n * secure: true,\n * maxAge: 3600\n * });\n * ```\n */\n cookie(options: CookieInit | Cookie): void\n /**\n * Sets a cookie in the response using name and value.\n *\n * @param name - The cookie name\n * @param value - The cookie value\n */\n cookie(name: string, value: string): void\n cookie(...args: unknown[]): void {\n // Invalidate cookie header cache when cookies change\n this._cookieHeaderCache = null\n if (args.length === 1) {\n this.cookieMap.set(args[0] as CookieInit | Cookie)\n }\n else {\n this.cookieMap.set(\n args[0] as string,\n args[1] as string,\n )\n }\n }\n\n /**\n * Deletes a cookie from the response.\n *\n * @param optionsOrName - Cookie name or delete options\n * @example\n * ```typescript\n * // Delete by name\n * response.deleteCookie('sessionId');\n *\n * // Delete with options\n * response.deleteCookie({\n * name: 'sessionId',\n * path: '/',\n * domain: 'example.com'\n * });\n * ```\n */\n deleteCookie(optionsOrName: CookieStoreDeleteOptions | string): void\n /**\n * Deletes a cookie from the response with additional options.\n *\n * @param optionsOrName - Cookie name\n * @param options - Additional delete options (path, domain, etc.)\n */\n deleteCookie(optionsOrName: string, options: Omit<CookieStoreDeleteOptions, 'name'>): void\n deleteCookie(optionsOrName: CookieStoreDeleteOptions | string, options?: Omit<CookieStoreDeleteOptions, 'name'>): void {\n if (typeof optionsOrName === 'string') {\n this.cookieMap.delete(optionsOrName, options as unknown as Omit<CookieStoreDeleteOptions, 'name'>)\n }\n else {\n this.cookieMap.delete(optionsOrName)\n }\n }\n\n /**\n * Sends a redirect response to the specified URL.\n * Ends the response after calling this method.\n *\n * @param url - The URL to redirect to\n * @param statusCode - HTTP status code for the redirect (default: 302)\n * @example\n * ```typescript\n * // Temporary redirect (302)\n * response.redirect('/login');\n *\n * // Permanent redirect (301)\n * response.redirect('/new-page', 301);\n *\n * // See Other (303)\n * response.redirect('/success', 303);\n * ```\n */\n redirect(url: string, statusCode = 302): void {\n if (this.ended) return\n this.ended = true\n this.resolve(Response.redirect(url, statusCode))\n }\n\n /**\n * Ends the response and sends the body to the client.\n * Automatically handles JSON serialization, streams, and binary data.\n * Can only be called once per response.\n *\n * @param body - The response body (JSON, string, Uint8Array, StreamableFile, or undefined)\n * @example\n * ```typescript\n * // Send JSON response\n * response.end({ message: 'Success', data: { id: 1 } });\n *\n * // Send empty response\n * response.setStatus(204);\n * response.end();\n *\n * // Send binary data\n * const buffer = new Uint8Array([1, 2, 3]);\n * response.end(buffer);\n *\n * // Send file stream\n * const file = new StreamableFile(stream);\n * response.end(file);\n * ```\n */\n end(body?: unknown): void {\n if (this.ended) return\n this.ended = true\n /**\n * According to RFC 6265, multiple Set-Cookie attributes should be separated by semicolons.\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#syntax\n * @see https://bun.com/docs/runtime/cookies#tosetcookieheaders-:-string[]\n */\n this._cookieHeaderCache ??= this.cookieMap.toSetCookieHeaders().join('; ')\n if (this._cookieHeaderCache.length > 0) {\n this.setHeader('set-cookie', this._cookieHeaderCache)\n }\n\n // Fast path: check for most common case first (plain objects/arrays for JSON)\n // Avoid expensive instanceof checks when possible\n if (body !== null && typeof body === 'object') {\n // Check special types first with early returns\n if (body instanceof Uint8Array || body instanceof Blob) {\n this.resolve(this.createResponse(body))\n return\n }\n if (body instanceof StreamableFile) {\n this.resolve(this.buildStreamableResponse(body))\n return\n }\n // Default: treat as JSON-serializable object\n this.resolve(this.buildJsonResponse(body))\n return\n }\n\n if (!body) {\n this.resolve(this.createResponse(null))\n return\n }\n\n // String or primitive\n this.resolve(this.buildJsonResponse(body))\n }\n\n /**\n * Sets a response header.\n * Header names are automatically normalized to lowercase.\n *\n * @param name - The header name\n * @param value - The header value\n * @example\n * ```typescript\n * response.setHeader('Content-Type', 'application/json');\n * response.setHeader('Cache-Control', 'no-cache');\n * response.setHeader('X-Custom-Header', 'custom-value');\n * ```\n */\n setHeader(name: string, value: string): void {\n this.headersMap.set(name.toLowerCase(), value)\n }\n\n /**\n * Gets the value of a response header.\n * Header lookup is case-insensitive.\n *\n * @param name - The header name to retrieve\n * @returns The header value or null if not set\n * @example\n * ```typescript\n * response.setHeader('Content-Type', 'application/json');\n * const contentType = response.getHeader('content-type');\n * console.log(contentType); // \"application/json\"\n *\n * const missing = response.getHeader('X-Missing');\n * console.log(missing); // null\n * ```\n */\n getHeader(name: string): string | null {\n return this._headers?.get(name.toLowerCase()) ?? null\n }\n\n /**\n * Appends a value to an existing response header.\n * If the header doesn't exist, it will be created.\n * Multiple values are joined with a comma as per RFC 9110.\n *\n * @param name - The header name\n * @param value - The value to append\n * @example\n * ```typescript\n * response.setHeader('Cache-Control', 'no-cache');\n * response.appendHeader('Cache-Control', 'no-store');\n * // Results in: \"Cache-Control: no-cache, no-store\"\n *\n * response.appendHeader('X-Custom', 'value1');\n * response.appendHeader('X-Custom', 'value2');\n * // Results in: \"X-Custom: value1, value2\"\n * ```\n */\n appendHeader(name: string, value: string): void {\n const key = name.toLowerCase()\n const headers = this.headersMap\n const existing = headers.get(key)\n /**\n * According to RFC 9110, multiple header values should be concatenated with a comma.\n * @see https://datatracker.ietf.org/doc/html/rfc9110#section-5.3.3\n */\n headers.set(key, existing ? `${existing}, ${value}` : value)\n }\n\n /**\n * Removes a response header.\n * Header lookup is case-insensitive.\n *\n * @param name - The header name to remove\n * @example\n * ```typescript\n * response.setHeader('X-Custom-Header', 'value');\n * response.removeHeader('X-Custom-Header');\n *\n * const header = response.getHeader('X-Custom-Header');\n * console.log(header); // null\n * ```\n */\n removeHeader(name: string): void {\n this._headers?.delete(name.toLowerCase())\n }\n\n /**\n * Sets the HTTP status code for the response.\n *\n * @param code - The HTTP status code (e.g., 200, 404, 500)\n * @example\n * ```typescript\n * response.setStatus(200); // OK\n * response.setStatus(201); // Created\n * response.setStatus(400); // Bad Request\n * response.setStatus(404); // Not Found\n * response.setStatus(500); // Internal Server Error\n * ```\n */\n setStatus(code: number): void {\n this.statusCode = code\n }\n\n /**\n * Gets the current HTTP status code of the response.\n *\n * @returns The HTTP status code\n * @example\n * ```typescript\n * response.setStatus(404);\n * const status = response.getStatus();\n * console.log(status); // 404\n * ```\n */\n getStatus(): number {\n return this.statusCode\n }\n\n /**\n * Returns a Promise that resolves to the native Response object.\n * The Promise resolves when end() or redirect() is called.\n *\n * @returns Promise that resolves to the Bun Response object\n * @example\n * ```typescript\n * const response = new BunResponse();\n * response.setStatus(200);\n * response.end({ message: 'Success' });\n *\n * const nativeResponse = await response.res();\n * console.log(nativeResponse.status); // 200\n * ```\n */\n res(): Promise<Response> {\n return this.response\n }\n\n /**\n * Checks if the response has been ended.\n * Once ended, no further modifications can be made to the response.\n *\n * @returns true if the response has been ended, false otherwise\n * @example\n * ```typescript\n * const response = new BunResponse();\n * console.log(response.isEnded()); // false\n *\n * response.end({ message: 'Done' });\n * console.log(response.isEnded()); // true\n *\n * // This will be ignored since response is already ended\n * response.setHeader('X-Custom', 'value');\n * ```\n */\n isEnded(): boolean {\n return this.ended\n }\n\n private buildStreamableResponse(body: StreamableFile): Response {\n const streamHeaders = body.getHeaders()\n const headers = this.headersMap\n if (streamHeaders.type && !headers.has('content-type')) {\n headers.set('content-type', streamHeaders.type)\n }\n if (streamHeaders.disposition && !headers.has('content-disposition')) {\n headers.set('content-disposition', streamHeaders.disposition as string)\n }\n if (streamHeaders.length !== undefined && !headers.has('content-length')) {\n headers.set('content-length', String(streamHeaders.length))\n }\n return this.createResponse(body.getStream())\n }\n\n private buildJsonResponse(body: unknown): Response {\n const headers = this._headers\n // Hot path: no headers\n if (headers === null || headers.size === 0) {\n return Response.json(body, { status: this.statusCode })\n }\n // Set content-type only if not already set\n if (!headers.has('content-type')) {\n headers.set('content-type', JSON_CONTENT_TYPE)\n }\n return Response.json(body, {\n status: this.statusCode,\n headers: Object.fromEntries(headers),\n })\n }\n\n private createResponse(body: BodyInit | null): Response {\n const headers = this._headers\n if (headers === null || headers.size === 0) {\n return new Response(body, { status: this.statusCode })\n }\n return new Response(body, {\n status: this.statusCode,\n headers: Object.fromEntries(headers),\n })\n }\n}\n",
|
|
11
|
+
"import {\n CustomVersioningOptions,\n HeaderVersioningOptions,\n MediaTypeVersioningOptions,\n VersionValue,\n} from '@nestjs/common/interfaces/version-options.interface.js'\nimport { VERSION_NEUTRAL, VersioningOptions, VersioningType } from '@nestjs/common'\n\nimport { BunRequest } from './bun.request.js'\nimport { BunResponse } from './bun.response.js'\n\ntype VersionHandler = (req: BunRequest, res: BunResponse, next: () => void) => unknown\n\n/**\n * Metadata attached to request for custom versioning two-pass execution\n */\nexport interface CustomVersioningMeta {\n _customVersioningPhase?: 'discovery' | 'execution'\n _customVersioningCandidates?: Map<string, { priority: number, execute: () => unknown }>\n _customVersioningBestCandidate?: string\n}\n\n/** Helper to execute handler and await if needed */\nasync function executeHandler(handler: VersionHandler, req: BunRequest, res: BunResponse, next: () => void): Promise<unknown> {\n const result = handler(req, res, next)\n return result instanceof Promise ? await result : result\n}\n\n/** Helper to call next and await if needed */\nfunction callNext(next: () => void | Promise<void>): void | Promise<void> {\n return next()\n}\n\n/**\n * Middleware for handling NestJS versioning in BunAdapter.\n * Supports URI, Header, Media Type, and Custom versioning strategies.\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class BunVersionFilterMiddleware {\n /**\n * Creates a version-filtered handler wrapper.\n */\n static createFilter(\n handler: VersionHandler,\n version: VersionValue,\n versioningOptions: VersioningOptions,\n ): VersionHandler {\n if (version === VERSION_NEUTRAL || versioningOptions.type === VersioningType.URI) {\n return handler\n }\n\n // Use switch instead of object creation for better performance\n switch (versioningOptions.type) {\n case VersioningType.CUSTOM:\n return this.createCustomVersionFilter(handler, version, versioningOptions as CustomVersioningOptions)\n case VersioningType.MEDIA_TYPE:\n return this.createMediaTypeVersionFilter(handler, version, versioningOptions as MediaTypeVersioningOptions)\n case VersioningType.HEADER:\n return this.createHeaderVersionFilter(handler, version, versioningOptions as HeaderVersioningOptions)\n default:\n throw new Error('Unsupported versioning options')\n }\n }\n\n /** Checks if the handler version matches the requested version (optimized with Set for arrays) */\n private static createVersionMatcher(handlerVersion: VersionValue): (requestedVersion: string | undefined) => boolean {\n if (Array.isArray(handlerVersion)) {\n const versionSet = new Set(handlerVersion)\n return requestedVersion => requestedVersion !== undefined && versionSet.has(requestedVersion)\n }\n return requestedVersion => requestedVersion == handlerVersion\n }\n\n /** Pre-computes whether handler accepts VERSION_NEUTRAL */\n private static computeAcceptsNeutral(version: VersionValue): boolean {\n return version === VERSION_NEUTRAL\n || (Array.isArray(version) && version.includes(VERSION_NEUTRAL))\n }\n\n /** Extracts header value from request - optimized to use .get() directly */\n private static getHeader(req: BunRequest, name: string): string | undefined {\n // Headers.get() is case-insensitive per spec, so we only need one call\n return req.headers.get(name) ?? undefined\n }\n\n /** Creates a filter for Custom versioning (uses extractor function) */\n private static createCustomVersionFilter(\n handler: VersionHandler,\n version: VersionValue,\n options: CustomVersioningOptions,\n ): VersionHandler {\n // Pre-compute version set for O(1) lookups\n const isVersionArray = Array.isArray(version)\n const versionSet = isVersionArray ? new Set(version as string[]) : null\n const singleVersion = isVersionArray ? null : version as string\n\n return async (req, res, next) => {\n const extracted = options.extractor(req)\n const reqMeta = req as CustomVersioningMeta\n\n // Initialize metadata on first handler\n reqMeta._customVersioningPhase ??= 'discovery'\n reqMeta._customVersioningCandidates ??= new Map()\n\n const isDiscovery = reqMeta._customVersioningPhase === 'discovery'\n\n // Inline findVersionMatch for performance\n const extractedIsArray = Array.isArray(extracted)\n const extractedVersions = extractedIsArray ? extracted : [extracted]\n let match: string | undefined\n let matchIndex = -1\n\n for (let i = 0; i < extractedVersions.length; i++) {\n const extractedVersion = extractedVersions[i]\n if (versionSet ? versionSet.has(extractedVersion) : extractedVersion === singleVersion) {\n match = extractedVersion\n matchIndex = i\n break\n }\n }\n\n if (match) {\n if (isDiscovery) {\n reqMeta._customVersioningCandidates.set(match, {\n priority: matchIndex,\n execute: () => handler(req, res, next),\n })\n return callNext(next)\n }\n\n if (reqMeta._customVersioningBestCandidate === match) {\n return executeHandler(handler, req, res, next)\n }\n }\n\n return callNext(next)\n }\n }\n\n /** Creates a filter for Media Type (Accept header) versioning */\n private static createMediaTypeVersionFilter(\n handler: VersionHandler,\n version: VersionValue,\n options: MediaTypeVersioningOptions,\n ): VersionHandler {\n // Pre-compute at filter creation time\n const acceptsNeutral = this.computeAcceptsNeutral(version)\n const versionMatches = this.createVersionMatcher(version)\n const keyLength = options.key.length\n\n return async (req, res, next) => {\n const acceptHeader = this.getHeader(req, 'accept')\n\n if (acceptHeader) {\n // Find semicolon position without creating intermediate array\n const semiIndex = acceptHeader.indexOf(';')\n if (semiIndex !== -1) {\n const versionPart = acceptHeader.substring(semiIndex + 1).trim()\n // Find the key and extract version after it\n const keyIndex = versionPart.indexOf(options.key)\n if (keyIndex !== -1) {\n const headerVersion = versionPart.substring(keyIndex + keyLength)\n if (versionMatches(headerVersion)) {\n return executeHandler(handler, req, res, next)\n }\n return callNext(next)\n }\n }\n }\n\n // No version param found\n if (acceptsNeutral) {\n return executeHandler(handler, req, res, next)\n }\n return callNext(next)\n }\n }\n\n /** Creates a filter for Header versioning (custom header) */\n private static createHeaderVersionFilter(\n handler: VersionHandler,\n version: VersionValue,\n options: HeaderVersioningOptions & { defaultVersion?: VersionValue },\n ): VersionHandler {\n // Pre-compute at filter creation time\n const acceptsNeutral = this.computeAcceptsNeutral(version)\n const versionMatches = this.createVersionMatcher(version)\n const defaultVersion = options.defaultVersion\n const hasNeutralDefault = defaultVersion === VERSION_NEUTRAL\n const resolvedDefault = this.resolveDefaultVersion(version, defaultVersion)\n const headerName = options.header\n\n return async (req, res, next) => {\n let headerVersion: string | undefined = this.getHeader(req, headerName)?.trim()\n\n // Treat empty or whitespace-only as undefined\n if (headerVersion === '') headerVersion = undefined\n\n // Apply default version if no header provided\n headerVersion ??= resolvedDefault\n\n // No version provided\n if (!headerVersion) {\n // Handle VERSION_NEUTRAL default or neutral-accepting handler\n if ((hasNeutralDefault || !defaultVersion) && acceptsNeutral) {\n return executeHandler(handler, req, res, next)\n }\n return callNext(next)\n }\n\n if (versionMatches(headerVersion)) {\n return executeHandler(handler, req, res, next)\n }\n return callNext(next)\n }\n }\n\n /** Resolves default version that matches handler version */\n private static resolveDefaultVersion(\n handlerVersion: VersionValue,\n defaultVersion: VersionValue | undefined,\n ): string | undefined {\n if (defaultVersion === undefined || defaultVersion === VERSION_NEUTRAL) {\n return undefined\n }\n\n const handlerVersions = Array.isArray(handlerVersion) ? handlerVersion : [handlerVersion]\n\n if (typeof defaultVersion === 'string') {\n return handlerVersions.includes(defaultVersion) ? defaultVersion : undefined\n }\n\n if (Array.isArray(defaultVersion)) {\n return defaultVersion.find(dv => typeof dv === 'string' && handlerVersions.includes(dv)) as string | undefined\n }\n\n return undefined\n }\n\n /** Selects the best custom versioning candidate after discovery phase */\n static selectBestCustomVersionCandidate(req: BunRequest): string | null {\n const { _customVersioningPhase: phase, _customVersioningCandidates: candidates } = req as CustomVersioningMeta\n\n if (phase !== 'discovery' || !candidates?.size) return null\n\n let bestVersion: string | null = null\n let bestPriority = Infinity\n\n for (const [version, { priority }] of candidates) {\n if (priority < bestPriority) {\n bestPriority = priority\n bestVersion = version\n }\n }\n\n return bestVersion\n }\n\n /** Switches the request to execution phase for custom versioning */\n static setCustomVersioningExecutionPhase(req: BunRequest, bestVersion: string): void {\n const reqMeta = req as CustomVersioningMeta\n reqMeta._customVersioningPhase = 'execution'\n reqMeta._customVersioningBestCandidate = bestVersion\n }\n\n /** Checks if request has custom versioning candidates pending */\n static hasCustomVersioningCandidates(req: BunRequest): boolean {\n const { _customVersioningPhase: phase, _customVersioningCandidates: candidates } = req as CustomVersioningMeta\n return phase === 'discovery' && !!candidates?.size\n }\n}\n",
|
|
12
|
+
"import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'\nimport { basename, join } from 'node:path'\nimport { HttpAdapterHost } from '@nestjs/core'\nimport { Observable } from 'rxjs'\nimport { randomUUIDv7 } from 'bun'\nimport { tmpdir } from 'node:os'\n\nimport { BunAdapter } from './bun.adapter.js'\nimport { BunRequest } from './bun.request.js'\n\n@Injectable()\nexport class BunFileInterceptor implements NestInterceptor {\n private readonly uploadDir = Bun.env.BUN_UPLOAD_DIR\n constructor(private readonly adapter: HttpAdapterHost) {\n const httpAdapter = this.adapter.httpAdapter as unknown as BunAdapter\n this.uploadDir ??= join(tmpdir(), 'uploads', httpAdapter.getHttpServer().id, randomUUIDv7())\n }\n\n async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<unknown>> {\n const request = context.switchToHttp().getRequest<BunRequest>()\n if (!request.files?.length) {\n return next.handle()\n }\n\n const files = await Promise.all(\n request.files.map(async (file) => {\n const destPath = join(this.uploadDir as unknown as string, basename(file.name))\n await Bun.write(destPath, file)\n return Bun.file(destPath) as File\n }),\n )\n request.setFile(files[0])\n request.setFiles(files)\n\n return next.handle()\n }\n}\n"
|
|
13
|
+
],
|
|
14
|
+
"mappings": "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",
|
|
15
|
+
"debugId": "E15070B5DB09928264756E2164756E21",
|
|
16
|
+
"names": []
|
|
17
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@krisanalfa/bunest-adapter",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "High-performance Bun adapter for NestJS framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"prebuild": "bun test",
|
|
21
|
+
"build": "bun run build.ts",
|
|
22
|
+
"prepublishOnly": "bun run build",
|
|
23
|
+
"test": "bun test"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"nestjs",
|
|
27
|
+
"bun",
|
|
28
|
+
"adapter",
|
|
29
|
+
"http",
|
|
30
|
+
"server",
|
|
31
|
+
"performance",
|
|
32
|
+
"http-server",
|
|
33
|
+
"bun-adapter"
|
|
34
|
+
],
|
|
35
|
+
"author": "Krisan Alfa Timur",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/krisanalfa/bunest.git",
|
|
40
|
+
"directory": "packages/bunest-adapter"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/krisanalfa/bunest/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/krisanalfa/bunest#readme",
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@nestjs/common": "^11.0.0",
|
|
48
|
+
"@nestjs/core": "^11.0.0"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"cors": "^2.8.5",
|
|
52
|
+
"qs": "^6.14.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@nestjs/testing": "^11.1.9",
|
|
56
|
+
"@types/cors": "^2.8.19",
|
|
57
|
+
"@types/helmet": "^4.0.0",
|
|
58
|
+
"@types/qs": "^6.14.0",
|
|
59
|
+
"class-transformer": "^0.5.1",
|
|
60
|
+
"class-validator": "^0.14.3",
|
|
61
|
+
"helmet": "^8.1.0"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"bun": ">=1.3.0"
|
|
65
|
+
}
|
|
66
|
+
}
|