{"version":3,"file":"node-http-gyWQuCv2.mjs","names":["req: NodeHTTPRequest","opts: {\n    /**\n     * Max body size in bytes. If the body is larger than this, the request will be aborted\n     */\n    maxBodySize: number | null;\n  }","chunk: Buffer","incoming: http.IncomingHttpHeaders","res: NodeHTTPResponse","init: RequestInit","res: NodeHTTPResponse","chunk: Uint8Array","err: unknown","opts: {\n  res: NodeHTTPResponse;\n  signal: AbortSignal;\n  body: NonNullable<Response['body']>;\n}","opts: {\n  request: Request;\n  response: Response;\n  rawResponse: NodeHTTPResponse;\n}","opts: NodeHTTPRequestHandlerOptions<TRouter, TRequest, TResponse>","cause: unknown","err: unknown","createContext: ResolveHTTPRequestOptionsContextFn<\n          TRouter\n        >"],"sources":["../src/adapters/node-http/incomingMessageToRequest.ts","../src/adapters/node-http/writeResponse.ts","../src/adapters/node-http/nodeHTTPRequestHandler.ts"],"sourcesContent":["import type * as http from 'http';\nimport { IncomingMessage } from 'node:http';\nimport { TRPCError } from '../../@trpc/server';\nimport type { NodeHTTPRequest, NodeHTTPResponse } from './types';\n\nfunction createBody(\n  req: NodeHTTPRequest,\n  opts: {\n    /**\n     * Max body size in bytes. If the body is larger than this, the request will be aborted\n     */\n    maxBodySize: number | null;\n  },\n): RequestInit['body'] {\n  // Some adapters will pre-parse the body and add it to the request object\n  if ('body' in req) {\n    if (req.body === undefined) {\n      // If body property exists but is undefined, return undefined\n      return undefined;\n    }\n    // If the body is already a string, return it directly\n    if (typeof req.body === 'string') {\n      return req.body;\n    }\n    // formData use\n    if (req.body instanceof IncomingMessage) {\n      return req.body as any;\n    }\n    // If body exists but isn't a string, stringify it as JSON\n    return JSON.stringify(req.body);\n  }\n  let size = 0;\n  let hasClosed = false;\n\n  return new ReadableStream({\n    start(controller) {\n      const onData = (chunk: Buffer) => {\n        size += chunk.length;\n        if (!opts.maxBodySize || size <= opts.maxBodySize) {\n          controller.enqueue(\n            new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength),\n          );\n          return;\n        }\n        controller.error(\n          new TRPCError({\n            code: 'PAYLOAD_TOO_LARGE',\n          }),\n        );\n        hasClosed = true;\n        req.off('data', onData);\n        req.off('end', onEnd);\n      };\n\n      const onEnd = () => {\n        if (hasClosed) {\n          return;\n        }\n        hasClosed = true;\n        req.off('data', onData);\n        req.off('end', onEnd);\n        controller.close();\n      };\n\n      req.on('data', onData);\n      req.on('end', onEnd);\n    },\n    cancel() {\n      req.destroy();\n    },\n  });\n}\nexport function createURL(req: NodeHTTPRequest): URL {\n  try {\n    const protocol =\n      // http2\n      (req.headers[':scheme'] && req.headers[':scheme'] === 'https') ||\n      // http1\n      (req.socket && 'encrypted' in req.socket && req.socket.encrypted)\n        ? 'https:'\n        : 'http:';\n\n    const host = req.headers.host ?? req.headers[':authority'] ?? 'localhost';\n\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    return new URL(req.url!, `${protocol}//${host}`);\n  } catch (cause) {\n    throw new TRPCError({\n      code: 'BAD_REQUEST',\n      message: 'Invalid URL',\n      cause,\n    });\n  }\n}\n\nfunction createHeaders(incoming: http.IncomingHttpHeaders): Headers {\n  const headers = new Headers();\n\n  for (const key in incoming) {\n    const value = incoming[key];\n    if (typeof key === 'string' && key.startsWith(':')) {\n      // Skip HTTP/2 pseudo-headers\n      continue;\n    }\n\n    if (Array.isArray(value)) {\n      for (const item of value) {\n        headers.append(key, item);\n      }\n    } else if (value != null) {\n      headers.append(key, value);\n    }\n  }\n\n  return headers;\n}\n\n/**\n * Convert an [`IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) to a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)\n */\nexport function incomingMessageToRequest(\n  req: NodeHTTPRequest,\n  res: NodeHTTPResponse,\n  opts: {\n    /**\n     * Max body size in bytes. If the body is larger than this, the request will be aborted\n     */\n    maxBodySize: number | null;\n  },\n): Request {\n  const ac = new AbortController();\n\n  const onAbort = () => {\n    res.off('close', onAbort);\n    req.off('aborted', onAbort);\n\n    // abort the request\n    ac.abort();\n  };\n\n  res.once('close', onAbort);\n  req.once('aborted', onAbort);\n\n  // Get host from either regular header or HTTP/2 pseudo-header\n  const url = createURL(req);\n\n  const init: RequestInit = {\n    headers: createHeaders(req.headers),\n    method: req.method,\n    signal: ac.signal,\n  };\n\n  if (req.method !== 'GET' && req.method !== 'HEAD') {\n    init.body = createBody(req, opts);\n\n    // init.duplex = 'half' must be set when body is a ReadableStream, and Node follows the spec.\n    // However, this property is not defined in the TypeScript types for RequestInit, so we have\n    // to cast it here in order to set it without a type error.\n    // See https://fetch.spec.whatwg.org/#dom-requestinit-duplex\n    // @ts-expect-error this is fine\n    init.duplex = 'half';\n  }\n\n  const request = new Request(url, init);\n\n  return request;\n}\n","// eslint-disable-next-line no-restricted-imports\nimport { isAbortError } from '../../unstable-core-do-not-import';\nimport type { NodeHTTPResponse } from './types';\n\nasync function writeResponseBodyChunk(\n  res: NodeHTTPResponse,\n  chunk: Uint8Array,\n) {\n  // useful for debugging 🙃\n  // console.debug('writing', new TextDecoder().decode(chunk));\n\n  if (res.write(chunk) === false) {\n    await new Promise<void>((resolve, reject) => {\n      const onError = (err: unknown) => {\n        reject(err);\n        cleanup();\n      };\n      const onDrain = () => {\n        resolve();\n        cleanup();\n      };\n      const cleanup = () => {\n        res.off('error', onError);\n        res.off('drain', onDrain);\n      };\n      res.once('error', onError);\n      res.once('drain', onDrain);\n    });\n  }\n}\n/**\n * @internal\n */\n\nexport async function writeResponseBody(opts: {\n  res: NodeHTTPResponse;\n  signal: AbortSignal;\n  body: NonNullable<Response['body']>;\n}) {\n  const { res } = opts;\n\n  try {\n    const writableStream = new WritableStream({\n      async write(chunk) {\n        await writeResponseBodyChunk(res, chunk);\n        res.flush?.();\n      },\n    });\n\n    await opts.body.pipeTo(writableStream, {\n      signal: opts.signal,\n    });\n  } catch (err) {\n    if (isAbortError(err)) {\n      return;\n    }\n    throw err;\n  }\n}\n/**\n * @internal\n */\n\nexport async function writeResponse(opts: {\n  request: Request;\n  response: Response;\n  rawResponse: NodeHTTPResponse;\n}) {\n  const { response, rawResponse } = opts;\n\n  // Only override status code if it hasn't been explicitly set in a procedure etc\n  if (rawResponse.statusCode === 200) {\n    rawResponse.statusCode = response.status;\n  }\n  for (const [key, value] of response.headers) {\n    if (key.toLowerCase() === 'set-cookie') continue;\n    rawResponse.setHeader(key, value);\n  }\n  const cookies = response.headers.getSetCookie();\n  if (cookies.length > 0) {\n    rawResponse.setHeader('set-cookie', cookies);\n  }\n  try {\n    if (response.body) {\n      await writeResponseBody({\n        res: rawResponse,\n        signal: opts.request.signal,\n        body: response.body,\n      });\n    }\n  } catch (err) {\n    if (!rawResponse.headersSent) {\n      rawResponse.statusCode = 500;\n    }\n    throw err;\n  } finally {\n    rawResponse.end();\n  }\n}\n","/**\n * If you're making an adapter for tRPC and looking at this file for reference, you should import types and functions from `@trpc/server` and `@trpc/server/http`\n *\n * @example\n * ```ts\n * import type { AnyTRPCRouter } from '@trpc/server'\n * import type { HTTPBaseHandlerOptions } from '@trpc/server/http'\n * ```\n */\n\n// @trpc/server\n\nimport {\n  getTRPCErrorFromUnknown,\n  transformTRPCResponse,\n  type AnyRouter,\n} from '../../@trpc/server';\nimport type { ResolveHTTPRequestOptionsContextFn } from '../../@trpc/server/http';\nimport { resolveResponse } from '../../@trpc/server/http';\n// eslint-disable-next-line no-restricted-imports\nimport { getErrorShape, run } from '../../unstable-core-do-not-import';\nimport { incomingMessageToRequest } from './incomingMessageToRequest';\nimport type {\n  NodeHTTPRequest,\n  NodeHTTPRequestHandlerOptions,\n  NodeHTTPResponse,\n} from './types';\nimport { writeResponse } from './writeResponse';\n\n/**\n * @internal\n */\nexport function internal_exceptionHandler<\n  TRouter extends AnyRouter,\n  TRequest extends NodeHTTPRequest,\n  TResponse extends NodeHTTPResponse,\n>(opts: NodeHTTPRequestHandlerOptions<TRouter, TRequest, TResponse>) {\n  return (cause: unknown) => {\n    const { res, req } = opts;\n    const error = getTRPCErrorFromUnknown(cause);\n\n    const shape = getErrorShape({\n      config: opts.router._def._config,\n      error,\n      type: 'unknown',\n      path: undefined,\n      input: undefined,\n      ctx: undefined,\n    });\n\n    opts.onError?.({\n      req,\n      error,\n      type: 'unknown',\n      path: undefined,\n      input: undefined,\n      ctx: undefined,\n    });\n\n    const transformed = transformTRPCResponse(opts.router._def._config, {\n      error: shape,\n    });\n\n    res.statusCode = shape.data.httpStatus;\n    res.end(JSON.stringify(transformed));\n  };\n}\n\n/**\n * @remark the promise never rejects\n */\nexport async function nodeHTTPRequestHandler<\n  TRouter extends AnyRouter,\n  TRequest extends NodeHTTPRequest,\n  TResponse extends NodeHTTPResponse,\n>(opts: NodeHTTPRequestHandlerOptions<TRouter, TRequest, TResponse>) {\n  return new Promise<void>((resolve) => {\n    const handleViaMiddleware =\n      opts.middleware ?? ((_req, _res, next) => next());\n\n    opts.res.once('finish', () => {\n      resolve();\n    });\n    return handleViaMiddleware(opts.req, opts.res, (err: unknown) => {\n      run(async () => {\n        const request = incomingMessageToRequest(opts.req, opts.res, {\n          maxBodySize: opts.maxBodySize ?? null,\n        });\n\n        // Build tRPC dependencies\n        const createContext: ResolveHTTPRequestOptionsContextFn<\n          TRouter\n        > = async (innerOpts) => {\n          return await opts.createContext?.({\n            ...opts,\n            ...innerOpts,\n          });\n        };\n\n        const response = await resolveResponse({\n          ...opts,\n          req: request,\n          error: err ? getTRPCErrorFromUnknown(err) : null,\n          createContext,\n          onError(o) {\n            opts?.onError?.({\n              ...o,\n              req: opts.req,\n            });\n          },\n        });\n\n        await writeResponse({\n          request,\n          response,\n          rawResponse: opts.res,\n        });\n      }).catch(internal_exceptionHandler(opts));\n    });\n  });\n}\n"],"mappings":"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"}