{"version":3,"sources":["../src/network/request.ts","../src/core/constants.ts","../src/core/current-invoke.ts","../src/core/event-body.ts","../src/core/headers.ts","../src/core/is-binary.ts","../src/core/no-op.ts","../src/core/logger.ts","../src/core/optional.ts","../src/core/path.ts","../src/core/stream.ts","../src/network/response.ts","../src/network/utils.ts","../src/network/response-stream.ts","../src/core/base-handler.ts"],"sourcesContent":["// ATTRIBUTION: https://github.com/dougmoscrop/serverless-http\nimport { IncomingMessage } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport type { SingleValueHeaders } from '../@types';\nimport { NO_OP } from '../core';\n\nconst HTTPS_PORT = 443;\n\n/**\n * The properties to create a {@link ServerlessRequest}\n *\n * @breadcrumb Network / ServerlessRequest\n * @public\n */\nexport interface ServerlessRequestProps {\n  /**\n   * The HTTP Method of the request\n   */\n  method: string;\n\n  /**\n   * The URL requested\n   */\n  url: string;\n\n  /**\n   * The headers from the event source\n   */\n  headers: SingleValueHeaders;\n\n  /**\n   * The body from the event source\n   */\n  body?: Buffer | Uint8Array;\n\n  /**\n   * The IP Address from caller\n   */\n  remoteAddress?: string;\n}\n\n/**\n * The class that represents an {@link http#IncomingMessage} created by the library to represent an actual request to the framework.\n *\n * @breadcrumb Network / ServerlessRequest\n * @public\n */\nexport class ServerlessRequest extends IncomingMessage {\n  constructor({\n    method,\n    url,\n    headers,\n    body,\n    remoteAddress,\n  }: ServerlessRequestProps) {\n    super({\n      encrypted: true,\n      readable: true, // credits to @pnkp at https://github.com/CodeGenieApp/serverless-express/pull/692\n      remoteAddress,\n      address: () => ({ port: HTTPS_PORT }) as AddressInfo,\n      on: NO_OP,\n      removeListener: NO_OP,\n      removeEventListener: NO_OP,\n      end: NO_OP,\n      destroy: NO_OP,\n    } as any);\n\n    this.statusCode = 200;\n    this.statusMessage = 'OK';\n    this.complete = true;\n    this.httpVersion = '1.1';\n    this.httpVersionMajor = 1;\n    this.httpVersionMinor = 1;\n    this.method = method;\n    this.headers = headers;\n    this.body = body;\n    this.url = url;\n    this.ip = remoteAddress;\n\n    this._read = () => {\n      this.push(body);\n      this.push(null);\n    };\n  }\n\n  ip?: string;\n  body?: Buffer | Uint8Array;\n}\n","/**\n * Default encodings that are treated as binary, they are compared with the `Content-Encoding` header.\n *\n * @breadcrumb Core / Constants\n * @defaultValue ['gzip', 'deflate', 'br']\n * @public\n */\nexport const DEFAULT_BINARY_ENCODINGS: string[] = ['gzip', 'deflate', 'br'];\n\n/**\n * Default content types that are treated as binary, they are compared with the `Content-Type` header.\n *\n * @breadcrumb Core / Constants\n * @defaultValue ['image/png', 'image/jpeg', 'image/jpg', 'image/avif', 'image/bmp', 'image/x-png', 'image/gif', 'image/webp', 'video/mp4', 'application/pdf']\n * @public\n */\nexport const DEFAULT_BINARY_CONTENT_TYPES: string[] = [\n  'image/png',\n  'image/jpeg',\n  'image/jpg',\n  'image/avif',\n  'image/bmp',\n  'image/x-png',\n  'image/gif',\n  'image/webp',\n  'video/mp4',\n  'application/pdf',\n];\n\n/**\n * Type alias for empty response and can be used on some adapters when the adapter does not need to return a response.\n *\n * @breadcrumb Core / Constants\n * @public\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type IEmptyResponse = {};\n\n/**\n * Constant for empty response and can be used on some adapters when the adapter does not need to return a response.\n *\n * @breadcrumb Core / Constants\n * @public\n */\nexport const EmptyResponse: IEmptyResponse = {};\n","/**\n * The type that represents the object that handles the references to the event created by the serverless trigger or context created by the serverless environment.\n *\n * @breadcrumb Core / Current Invoke\n * @public\n */\nexport type CurrentInvoke<TEvent, TContext> = {\n  /**\n   * The event created by the serverless trigger\n   *\n   * @remarks It's only null when you call {@link getCurrentInvoke} outside this library's pipeline.\n   */\n  event: TEvent | null;\n\n  /**\n   * The context created by the serverless environment\n   *\n   * @remarks It's only null when you call {@link getCurrentInvoke} outside this library's pipeline.\n   */\n  context: TContext | null;\n};\n\nconst currentInvoke: CurrentInvoke<any, any> = {\n  context: null,\n  event: null,\n};\n\n/**\n * Get the reference to the event created by the serverless trigger or context created by the serverless environment.\n *\n * @example\n * ```typescript\n * import type { ALBEvent, Context } from 'aws-lambda';\n *\n * // inside the method that handles the aws alb request.\n * const { event, context } = getCurrentInvoke<ALBEvent, Context>();\n * ```\n *\n * @breadcrumb Core / Current Invoke\n * @public\n */\nexport function getCurrentInvoke<TEvent = any, TContext = any>(): CurrentInvoke<\n  TEvent,\n  TContext\n> {\n  return currentInvoke;\n}\n\n/**\n * Method that saves to the event created by the serverless trigger or context created by the serverless environment.\n *\n * @remarks This method MUST NOT be called by you, this method MUST only be used internally in this library.\n *\n * @param event - The event created by the serverless trigger\n * @param context - The context created by the serverless environment\n *\n * @breadcrumb Core / Current Invoke\n * @public\n */\nexport function setCurrentInvoke<TEvent = any, TContext = any>({\n  event,\n  context,\n}: CurrentInvoke<TEvent, TContext>) {\n  currentInvoke.event = event;\n  currentInvoke.context = context;\n}\n","/**\n * Get the event body as buffer from body string with content length\n *\n * @example\n * ```typescript\n * const body = '{}';\n * const [buffer, contentLength] = getEventBodyAsBuffer(body, false);\n * console.log(buffer);\n * // <Buffer 7b 7d>\n * console.log(contentLength);\n * // 2\n * ```\n *\n * @param body - The body string that can be encoded or not\n * @param isBase64Encoded - Tells if body string is encoded in base64\n *\n * @breadcrumb Core\n * @public\n */\nexport function getEventBodyAsBuffer(\n  body: string,\n  isBase64Encoded: boolean,\n): [body: Buffer, contentLength: number] {\n  const encoding: BufferEncoding = isBase64Encoded ? 'base64' : 'utf8';\n\n  const buffer = Buffer.from(body, encoding);\n  const contentLength = Buffer.byteLength(buffer, encoding);\n\n  return [buffer, contentLength];\n}\n","//#region Imports\n\nimport type { BothValueHeaders } from '../@types';\n\n//#endregion\n\n/**\n * Transform a header map and make sure the value is not an array\n *\n * @example\n * ```typescript\n * const headers = { 'accept-encoding': 'gzip', 'accept-language': ['en-US', 'en;q=0.9'] };\n * const flattenedHeaders = getFlattenedHeadersMap(headers, ',', true);\n * console.log(flattenedHeaders);\n * // { 'accept-encoding': 'gzip', 'accept-language': 'en-US,en;q=0.9' }\n * ```\n *\n * @param headersMap - The initial headers\n * @param separator - The separator used when we join the array of header's value\n * @param lowerCaseKey - Should put all keys in lowercase\n *\n * @breadcrumb Core / Headers\n * @public\n */\nexport function getFlattenedHeadersMap(\n  headersMap: BothValueHeaders,\n  separator: string = ',',\n  lowerCaseKey: boolean = false,\n): Record<string, string> {\n  return Object.keys(headersMap).reduce((acc, headerKey) => {\n    const newKey = lowerCaseKey ? headerKey.toLowerCase() : headerKey;\n    const headerValue = headersMap[headerKey];\n\n    if (Array.isArray(headerValue)) acc[newKey] = headerValue.join(separator);\n    else acc[newKey] = (headerValue ?? '') + '';\n\n    return acc;\n  }, {});\n}\n\n/**\n * Transforms a header map into a multi-value map header.\n *\n * @example\n * ```typescript\n * const headers = { 'accept-encoding': 'gzip', 'connection': ['keep-alive'] };\n * const multiValueHeaders = getMultiValueHeadersMap(headers);\n * console.log(multiValueHeaders);\n * // { 'accept-encoding': ['gzip'], 'connection': ['keep-alive'] }\n * ```\n *\n * @param headersMap - The initial headers\n *\n * @breadcrumb Core / Headers\n * @public\n */\nexport function getMultiValueHeadersMap(\n  headersMap: BothValueHeaders,\n): Record<string, string[]> {\n  return Object.keys(headersMap).reduce((acc, headerKey) => {\n    const headerValue = headersMap[headerKey];\n\n    acc[headerKey.toLowerCase()] = Array.isArray(headerValue)\n      ? headerValue.map(String)\n      : [String(headerValue)];\n\n    return acc;\n  }, {});\n}\n\n/**\n * The wrapper that holds the information about single value headers and cookies\n *\n * @breadcrumb Core / Headers\n * @public\n */\nexport type FlattenedHeadersAndCookies = {\n  /**\n   * Just the single value headers\n   */\n  headers: Record<string, string>;\n\n  /**\n   * The list of cookies\n   */\n  cookies: string[];\n};\n\n/**\n * Transforms a header map into a single value headers and cookies\n *\n * @param headersMap - The initial headers\n *\n * @breadcrumb Core / Headers\n * @public\n */\nexport function getFlattenedHeadersMapAndCookies(\n  headersMap: BothValueHeaders,\n): FlattenedHeadersAndCookies {\n  return Object.keys(headersMap).reduce(\n    (acc, headerKey) => {\n      const headerValue = headersMap[headerKey];\n      const lowerHeaderKey = headerKey.toLowerCase();\n\n      if (Array.isArray(headerValue)) {\n        if (lowerHeaderKey !== 'set-cookie')\n          acc.headers[headerKey] = headerValue.join(',');\n        else acc.cookies.push(...headerValue);\n      } else {\n        if (lowerHeaderKey === 'set-cookie' && headerValue !== undefined)\n          acc.cookies.push(headerValue ?? '');\n        else acc.headers[headerKey] = String(headerValue ?? '');\n      }\n\n      return acc;\n    },\n    {\n      cookies: [],\n      headers: {},\n    } as FlattenedHeadersAndCookies,\n  );\n}\n\n/**\n * Parse HTTP Raw Headers\n * Attribution to {@link https://github.com/kesla/parse-headers/blob/master/parse-headers.js}\n *\n * @param headers - The raw headers\n *\n * @breadcrumb Core / Headers\n * @public\n */\nexport function parseHeaders(\n  headers: string,\n): Record<string, string | string[]> {\n  if (!headers) return {};\n\n  const result = {};\n  const headersArr = headers.trim().split('\\n');\n\n  for (let i = 0; i < headersArr.length; i++) {\n    const row = headersArr[i];\n    const index = row.indexOf(':');\n    const key = row.slice(0, index).trim().toLowerCase();\n    const value = row.slice(index + 1).trim();\n\n    if (typeof result[key] === 'undefined') result[key] = value;\n    else if (Array.isArray(result[key])) result[key].push(value);\n    else result[key] = [result[key], value];\n  }\n\n  return result;\n}\n\nexport function keysToLowercase<T extends Record<string, unknown>>(\n  obj: T,\n): { [K in keyof T as Lowercase<string & K>]: T[K] } {\n  const result: any = {};\n  for (const [k, v] of Object.entries(obj)) result[k.toLowerCase()] = v;\n\n  return result as { [K in keyof T as Lowercase<string & K>]: T[K] };\n}\n","// ATTRIBUTION: https://github.com/dougmoscrop/serverless-http\n\n//#region Imports\n\nimport type { BinarySettings, BothValueHeaders } from '../@types';\n\n//#endregion\n\n/**\n * The function that determines by the content encoding whether the response should be treated as binary\n *\n * @example\n * ```typescript\n * const headers = { 'content-encoding': 'gzip' };\n * const isBinary = isContentEncodingBinary(headers, ['gzip']);\n * console.log(isBinary);\n * // true\n * ```\n *\n * @param headers - The headers of the response\n * @param binaryEncodingTypes - The list of content encodings that will be treated as binary\n *\n * @breadcrumb Core / isBinary\n * @public\n */\nexport function isContentEncodingBinary(\n  headers: BothValueHeaders,\n  binaryEncodingTypes: string[],\n): boolean {\n  let contentEncodings = headers['content-encoding'];\n\n  if (!contentEncodings) return false;\n\n  if (!Array.isArray(contentEncodings))\n    contentEncodings = contentEncodings.split(',');\n\n  return contentEncodings.some(value =>\n    binaryEncodingTypes.includes(value.trim()),\n  );\n}\n\n/**\n * The function that returns the content type of headers\n *\n * @example\n * ```typescript\n * const headers = { 'content-type': 'application/json' };\n * const contentType = getContentType(headers);\n * console.log(contentType);\n * // application/json\n * ```\n *\n * @param headers - The headers of the response\n *\n * @breadcrumb Core / isBinary\n * @public\n */\nexport function getContentType(headers: BothValueHeaders): string {\n  const contentTypeHeaderRaw = headers['content-type'];\n  const contentTypeHeader = Array.isArray(contentTypeHeaderRaw)\n    ? contentTypeHeaderRaw[0] || ''\n    : contentTypeHeaderRaw || '';\n\n  if (!contentTypeHeaderRaw) return '';\n\n  // only compare mime type; ignore encoding part\n  const contentTypeStart = contentTypeHeader.indexOf(';');\n\n  if (contentTypeStart === -1) return contentTypeHeader;\n\n  return contentTypeHeader.slice(0, contentTypeStart);\n}\n\n/**\n * The function that determines by the content type whether the response should be treated as binary\n *\n * @example\n * ```typescript\n * const headers = { 'content-type': 'image/png' };\n * const isBinary = isContentTypeBinary(headers, new Map([['image/png', true]]));\n * console.log(isBinary);\n * // true\n * ```\n *\n * @param headers - The headers of the response\n * @param binaryContentTypes - The list of content types that will be treated as binary\n *\n * @breadcrumb Core / isBinary\n * @public\n */\nexport function isContentTypeBinary(\n  headers: BothValueHeaders,\n  binaryContentTypes: string[],\n) {\n  const contentType = getContentType(headers);\n\n  if (!contentType) return false;\n\n  return binaryContentTypes.includes(contentType.trim());\n}\n\n/**\n * The function used to determine from the headers and the binary settings if a response should be encoded or not\n *\n * @example\n * ```typescript\n * const headers = { 'content-type': 'image/png', 'content-encoding': 'gzip' };\n * const isContentBinary = isBinary(headers, { contentEncodings: ['gzip'], contentTypes: ['image/png'] });\n * console.log(isContentBinary);\n * // true\n * ```\n *\n * @param headers - The headers of the response\n * @param binarySettings - The settings for the validation\n *\n * @breadcrumb Core / isBinary\n * @public\n */\nexport function isBinary(\n  headers: BothValueHeaders,\n  binarySettings: BinarySettings,\n): boolean {\n  if ('isBinary' in binarySettings) {\n    if (binarySettings.isBinary === false) return false;\n\n    return binarySettings.isBinary(headers);\n  }\n\n  return (\n    isContentEncodingBinary(headers, binarySettings.contentEncodings) ||\n    isContentTypeBinary(headers, binarySettings.contentTypes)\n  );\n}\n","/**\n * No operation function is used when we need to pass a function, but we don't want to specify any behavior.\n *\n * @breadcrumb Core\n * @public\n */\nexport const NO_OP: (...args: any[]) => any = () => void 0;\n","import { NO_OP } from './no-op';\n\n/**\n * The type representing the possible log levels to choose from.\n *\n * @breadcrumb Core / Logger\n * @public\n */\nexport type LogLevels =\n  | 'debug'\n  | 'verbose'\n  | 'info'\n  | 'warn'\n  | 'error'\n  | 'none';\n\n/**\n * The options to customize {@link ILogger}\n *\n * @breadcrumb Core / Logger\n * @public\n */\nexport type LoggerOptions = {\n  /**\n   * Select the log level, {@link LogLevels | see more}.\n   *\n   * @defaultValue error\n   */\n  level: LogLevels;\n};\n\n/**\n * The log function used in any level.\n *\n * @breadcrumb Core / Logger\n * @public\n */\nexport type LoggerFN = (message: any, ...additional: any[]) => void;\n\n/**\n * The interface representing the logger, you can provide a custom logger by implementing this interface.\n *\n * @breadcrumb Core / Logger\n * @public\n */\nexport type ILogger = Record<Exclude<LogLevels, 'none'>, LoggerFN>;\n\n/**\n * The symbol used to check against an ILogger instace to verify if that ILogger was created by this library\n *\n * @breadcrumb Core / Logger\n * @public\n */\nconst InternalLoggerSymbol = Symbol('InternalLogger');\n\nconst logLevels: Record<\n  LogLevels,\n  [level: LogLevels, consoleMethod: keyof Console][]\n> = {\n  debug: [\n    ['debug', 'debug'],\n    ['verbose', 'debug'],\n    ['info', 'info'],\n    ['error', 'error'],\n    ['warn', 'warn'],\n  ],\n  verbose: [\n    ['verbose', 'debug'],\n    ['info', 'info'],\n    ['error', 'error'],\n    ['warn', 'warn'],\n  ],\n  info: [\n    ['info', 'info'],\n    ['error', 'error'],\n    ['warn', 'warn'],\n  ],\n  warn: [\n    ['warn', 'warn'],\n    ['error', 'error'],\n  ],\n  error: [['error', 'error']],\n  none: [],\n};\n\nconst lazyPrint = (value: () => any | unknown) => {\n  if (typeof value === 'function') return value();\n\n  return value;\n};\n\nconst print =\n  (fn: string) =>\n  (message: any, ...additional: (() => any)[]) =>\n    console[fn](message, ...additional.map(lazyPrint));\n\n/**\n * The method used to create a simple logger instance to use in this library.\n *\n * @remarks Behind the scenes, this simple logger sends the message to the `console` methods.\n *\n * @example\n * ```typescript\n * const logger = createDefaultLogger();\n *\n * logger.error('An error happens.');\n * // An error happens.\n * ```\n *\n * @param level - Select the level of the log\n *\n * @breadcrumb Core / Logger\n * @public\n */\nexport function createDefaultLogger(\n  { level }: LoggerOptions = { level: 'error' },\n): ILogger {\n  const levels = logLevels[level];\n\n  if (!levels) throw new Error('Invalid log level');\n\n  const logger = {\n    [InternalLoggerSymbol]: true,\n    error: NO_OP,\n    debug: NO_OP,\n    info: NO_OP,\n    verbose: NO_OP,\n    warn: NO_OP,\n  } as ILogger;\n\n  for (const [level, consoleMethod] of levels)\n    logger[level] = print(consoleMethod);\n\n  return logger;\n}\n\n/**\n * The method used to chck if logger was created by this library, or it was defined by the user.\n *\n * @param logger - The instance of the logger to check\n *\n * @breadcrumb Core / Logger\n * @public\n */\nexport function isInternalLogger(logger: ILogger): boolean {\n  return !!logger[InternalLoggerSymbol];\n}\n","/**\n * Return the defaultValue whether the value is undefined, otherwise, return the value.\n *\n * @example\n * ```typescript\n * const value1 = getDefaultIfUndefined(undefined, true);\n * const value2 = getDefaultIfUndefined(false, true);\n *\n * console.log(value1);\n * // true\n * console.log(value2);\n * // false\n * ```\n *\n * @param value - The value to be checked\n * @param defaultValue - The default value when value is undefined\n *\n * @breadcrumb Core\n * @public\n */\nexport function getDefaultIfUndefined<T>(\n  value: T | undefined,\n  defaultValue: T,\n): T {\n  if (value === undefined) return defaultValue;\n\n  return value;\n}\n","/**\n * Transform the path and a map of query params to a string with formatted query params\n *\n * @example\n * ```typescript\n * const path = '/pets/search';\n * const queryParams = { batata: undefined, petType: [ 'dog', 'fish' ] };\n * const result = getPathWithQueryStringParams(path, queryParams);\n * console.log(result);\n * // /pets/search?batata=&petType=dog&petType=fish\n * ```\n *\n * @param path - The path\n * @param queryParams - The query params\n *\n * @breadcrumb Core / Path\n * @public\n */\nexport function getPathWithQueryStringParams(\n  path: string,\n  queryParams:\n    | string\n    | Record<string, string | string[] | undefined>\n    | undefined\n    | null,\n): string {\n  if (String(queryParams || '').length === 0) return path;\n\n  if (typeof queryParams === 'string') return `${path}?${queryParams}`;\n\n  const queryParamsString = getQueryParamsStringFromRecord(queryParams);\n\n  if (!queryParamsString) return path;\n\n  return `${path}?${queryParamsString}`;\n}\n\n/**\n * Map query params to a string with formatted query params\n *\n * @example\n * ```typescript\n * const queryParams = { batata: undefined, petType: [ 'dog', 'fish' ] };\n * const result = getQueryParamsStringFromRecord(queryParams);\n * console.log(result);\n * // batata=&petType=dog&petType=fish\n * ```\n *\n * @param queryParamsRecord - The query params record\n *\n * @breadcrumb Core / Path\n * @public\n */\nexport function getQueryParamsStringFromRecord(\n  queryParamsRecord:\n    | Record<string, string | string[] | undefined>\n    | undefined\n    | null,\n): string {\n  const searchParams = new URLSearchParams();\n\n  const multiValueHeadersEntries: [string, string | string[] | undefined][] =\n    Object.entries(queryParamsRecord || {});\n\n  if (multiValueHeadersEntries.length === 0) return '';\n\n  for (const [key, value] of multiValueHeadersEntries) {\n    if (!Array.isArray(value)) {\n      searchParams.append(key, value || '');\n      continue;\n    }\n\n    for (const arrayValue of value) searchParams.append(key, arrayValue);\n  }\n\n  return searchParams.toString();\n}\n\n/**\n * Type of the function to strip base path\n *\n * @breadcrumb Core / Path\n * @public\n */\nexport type StripBasePathFn = (path: string) => string;\n\nconst NOOPBasePath: StripBasePathFn = (path: string) => path;\n\n/**\n * Get the strip base path function\n *\n * @param basePath - The base path\n *\n * @breadcrumb Core / Path\n * @public\n */\nexport function buildStripBasePath(\n  basePath: string | undefined,\n): StripBasePathFn {\n  if (!basePath) return NOOPBasePath;\n\n  const length = basePath.length;\n\n  return (path: string) => {\n    if (path.startsWith(basePath))\n      return path.slice(path.indexOf(basePath) + length, path.length) || '/';\n\n    return path;\n  };\n}\n","//#region Imports\n\nimport { Readable, Writable } from 'node:stream';\n\n//#endregion\n\n/**\n * Check if stream already ended\n *\n * @param stream - The stream\n *\n * @breadcrumb Core / Stream\n * @public\n */\nexport function isStreamEnded(stream: Readable | Writable): boolean {\n  if ('readableEnded' in stream && stream.readableEnded) return true;\n\n  if ('writableEnded' in stream && stream.writableEnded) return true;\n\n  return false;\n}\n\n/**\n * Wait asynchronous the stream to complete\n *\n * @param stream - The stream\n *\n * @breadcrumb Core / Stream\n * @public\n */\nexport function waitForStreamComplete<TStream extends Readable | Writable>(\n  stream: TStream,\n): Promise<TStream> {\n  if (isStreamEnded(stream)) return Promise.resolve(stream);\n\n  return new Promise<TStream>((resolve, reject) => {\n    // Reading the {@link https://github.com/nodejs/node/blob/v12.22.9/lib/events.js#L262 | emit source code},\n    // it's almost impossible to complete being called twice because the emit function runs synchronously and removes the other listeners,\n    // but I'll leave it at that because I didn't write that code, so I couldn't figure out what the author thought when he wrote this.\n    let isComplete = false;\n\n    function complete(err: any) {\n      /* istanbul ignore next */\n      if (isComplete) return;\n\n      isComplete = true;\n\n      stream.removeListener('error', complete);\n      stream.removeListener('end', complete);\n      stream.removeListener('finish', complete);\n\n      if (err) reject(err);\n      else resolve(stream);\n    }\n\n    stream.once('error', complete);\n    stream.once('end', complete);\n    stream.once('finish', complete);\n  });\n}\n","// ATTRIBUTION: https://github.com/dougmoscrop/serverless-http\nimport { IncomingMessage, ServerResponse } from 'node:http';\nimport type { Socket } from 'node:net';\nimport { NO_OP } from '../core';\nimport { getString } from './utils';\n\nconst headerEnd = '\\r\\n\\r\\n';\nconst endChunked = '0\\r\\n\\r\\n';\n\nconst BODY = Symbol('Response body');\nconst HEADERS = Symbol('Response headers');\n\nfunction addData(stream: ServerlessResponse, data: Uint8Array | string) {\n  if (\n    Buffer.isBuffer(data) ||\n    typeof data === 'string' ||\n    data instanceof Uint8Array\n  )\n    stream[BODY].push(Buffer.from(data));\n  else throw new Error(`response.write() of unexpected type: ${typeof data}`);\n}\n\n/**\n * The properties to create a {@link ServerlessResponse}.\n *\n * @breadcrumb Network / ServerlessResponse\n * @public\n */\nexport interface ServerlessResponseProps {\n  /**\n   * The HTTP Method from request\n   */\n  method?: string;\n}\n\n/**\n * The class that represents a response instance used to send to the framework and wait until the framework finishes processing the request.\n * Once it's happens, we use the properties from this response to built the response to the cloud.\n *\n * @breadcrumb Network / ServerlessResponse\n * @public\n */\nexport class ServerlessResponse extends ServerResponse {\n  constructor({ method }: ServerlessResponseProps) {\n    super({ method } as any);\n\n    this[BODY] = [];\n    this[HEADERS] = {};\n\n    this.useChunkedEncodingByDefault = false;\n    this.chunkedEncoding = false;\n    this._header = '';\n\n    // this ignore is used because I need to ignore these write calls:\n    // https://github.com/nodejs/node/blob/main/lib/_http_outgoing.js#L934-L935\n    // https://github.com/nodejs/node/blob/main/lib/_http_outgoing.js#L937\n    let writesToIgnore = 1;\n\n    const socket: Partial<Socket> & { _writableState: any } = {\n      _writableState: {},\n      writable: true,\n      on: NO_OP,\n      removeListener: NO_OP,\n      destroy: NO_OP,\n      cork: NO_OP,\n      uncork: NO_OP,\n      write: (\n        data: Uint8Array | string,\n        encoding?: string | null | (() => void),\n        cb?: () => void,\n      ): any => {\n        if (typeof encoding === 'function') {\n          cb = encoding;\n          encoding = null;\n        }\n\n        if (this._header === '' || this._wroteHeader) {\n          if (!this.chunkedEncoding) addData(this, data);\n          else {\n            if (writesToIgnore > 0) writesToIgnore--;\n            else if (data !== endChunked) {\n              addData(this, data);\n              writesToIgnore = 3;\n            }\n          }\n        } else {\n          const string = getString(data);\n          const index = string.indexOf(headerEnd);\n\n          if (index !== -1) {\n            const remainder = string.slice(index + headerEnd.length);\n\n            if (remainder && !this.chunkedEncoding) addData(this, remainder);\n\n            this._wroteHeader = true;\n          }\n        }\n\n        if (typeof cb === 'function') cb();\n      },\n    };\n\n    this.assignSocket(socket as unknown as Socket);\n  }\n\n  _header: string;\n  _headers?: Record<any, any>;\n  _wroteHeader?: boolean;\n\n  [BODY]: any[];\n  [HEADERS]: Record<any, any>;\n\n  get headers(): Record<any, any> {\n    return this[HEADERS];\n  }\n\n  static from(res: IncomingMessage) {\n    const response = new ServerlessResponse({ method: res.method });\n\n    response.statusCode = res.statusCode || 0;\n    response[HEADERS] = res.headers;\n    response[BODY] = (res as any).body ? [Buffer.from((res as any).body)] : [];\n    response.end();\n\n    return response;\n  }\n\n  static body(res: ServerlessResponse): Buffer {\n    return Buffer.concat(res[BODY]);\n  }\n\n  static headers(res: ServerlessResponse) {\n    const headers = res.getHeaders();\n\n    return Object.assign(headers, res[HEADERS]);\n  }\n\n  override setHeader(\n    key: string,\n    value: number | string | readonly string[],\n  ): any {\n    if (this._wroteHeader) this[HEADERS][key] = value;\n    else super.setHeader(key, value);\n  }\n\n  override writeHead(\n    statusCode: number,\n    statusMessage?: string | any | any[],\n    obj?: any | any[],\n  ): any {\n    const headersObjOrArray =\n      typeof statusMessage === 'string' ? obj : statusMessage;\n\n    const arrayHeaders = Array.isArray(headersObjOrArray)\n      ? headersObjOrArray\n      : [headersObjOrArray || {}];\n\n    for (const headers of arrayHeaders) {\n      for (const name in headers) {\n        this.setHeader(name, headers[name]!);\n\n        if (!this._wroteHeader) {\n          // we only need to initiate super.headers once\n          // writeHead will add the other headers itself\n          break;\n        }\n      }\n    }\n\n    return this.callNativeWriteHead(statusCode, statusMessage, obj);\n  }\n\n  /**\n   * I use ignore here because in nodejs 12.x, statusMessage can be string | OutgoingHttpHeaders\n   * But in nodejs \\>=14.x, statusMessage can also be OutgoingHttpHeaders[]\n   * I take care of these cases above, but here I can't handle it well, so I give up\n   * nodejs 12.x ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v12/http.d.ts#L229\n   * nodejs 14.x ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v14/http.d.ts#L263\n   */\n  protected callNativeWriteHead(\n    statusCode: number,\n    statusMessage?: string | any | any[],\n    obj?: any | any[],\n  ): this {\n    return super.writeHead(statusCode, statusMessage, obj);\n  }\n}\n","/**\n * Get the data from a buffer, string, or Uint8Array\n *\n * @breadcrumb Network\n * @param data - The data that was written inside the stream\n */\nexport function getString(data: Buffer | string | unknown) {\n  if (Buffer.isBuffer(data)) return data.toString('utf8');\n  else if (typeof data === 'string') return data;\n  else if (data instanceof Uint8Array) return new TextDecoder().decode(data);\n  else throw new Error(`response.write() of unexpected type: ${typeof data}`);\n}\n","import { ServerResponse } from 'node:http';\nimport type { Socket } from 'node:net';\nimport type { Writable } from 'node:stream';\nimport type { BothValueHeaders } from '../@types';\nimport { type ILogger, NO_OP, parseHeaders } from '../core';\nimport { getString } from './utils';\n\n// header or data crlf\nconst crlfBuffer = Buffer.from('\\r\\n');\n\nconst endChunked = '0\\r\\n\\r\\n';\nconst headerEnd = '\\r\\n\\r\\n';\nconst endStatusSeparator = '\\r\\n';\n\n/**\n * The properties to create a {@link ServerlessStreamResponse}.\n *\n * @breadcrumb Network / ServerlessStreamResponse\n * @public\n */\nexport interface ServerlessStreamResponseProps {\n  /**\n   * The HTTP Method from request\n   */\n  method?: string;\n\n  /**\n   * The callback to receive the headers when they are written to the stream\n   * You need to return a writable stream be able to continue writing the response\n   *\n   * @param statusCode - The status code of the response\n   * @param headers - The headers of the response\n   */\n  onReceiveHeaders: (statusCode: number, headers: BothValueHeaders) => Writable;\n\n  /**\n   * Instance of the logger\n   */\n  log: ILogger;\n}\n\n/**\n * The class that represents a response instance used to send to the framework and wait until the framework finishes processing the request.\n * This response is specially built to deal with transfer-encoding: chunked\n *\n * @breadcrumb Network / ServerlessStreamResponse\n * @public\n */\nexport class ServerlessStreamResponse extends ServerResponse {\n  constructor({\n    method,\n    onReceiveHeaders,\n    log,\n  }: ServerlessStreamResponseProps) {\n    super({ method } as any);\n\n    this.useChunkedEncodingByDefault = true;\n    this.chunkedEncoding = true;\n\n    let internalWritable: Writable | null = null;\n    let firstCrlfBufferEncountered = false;\n    let chunkEncountered = false;\n\n    const socket: Partial<Socket> & { _writableState: any } = {\n      _writableState: {},\n      writable: true,\n      on: NO_OP,\n      removeListener: NO_OP,\n      destroy: NO_OP,\n      cork: NO_OP,\n      uncork: NO_OP,\n      write: (\n        data: Uint8Array | string,\n        encoding?: string | null | (() => void),\n        cb?: () => void,\n      ): any => {\n        // very unlikely, I don't even know how to reproduce this, but exist on types\n        // istanbul ignore if\n        if (typeof encoding === 'function') {\n          cb = encoding;\n          encoding = null;\n        }\n\n        log.debug('SERVERLESS_ADAPTER:RESPONSE_STREAM:DATA', () => ({\n          data: Buffer.isBuffer(data) ? data.toString('utf8') : data,\n          encoding,\n        }));\n\n        if (!internalWritable) {\n          const stringData = getString(data);\n          const endStatusIndex = stringData.indexOf(endStatusSeparator);\n          const status = +stringData.slice(0, endStatusIndex).split(' ')[1];\n          const endHeaderIndex = stringData.indexOf(headerEnd);\n\n          const headerData = stringData.slice(\n            endStatusIndex + 2,\n            endHeaderIndex,\n          );\n          const headers = parseHeaders(headerData);\n          log.debug(\n            'SERVERLESS_ADAPTER:RESPONSE_STREAM:FRAMEWORK_HEADERS',\n            () => ({\n              headers,\n            }),\n          );\n\n          internalWritable = onReceiveHeaders(status, headers);\n\n          // If we get an endChunked right after header which means the response body is empty, we need to immediately end the writable\n          if (stringData.substring(endHeaderIndex + 4) === endChunked)\n            internalWritable.end();\n\n          return true;\n        }\n\n        // node sends the last chunk crlf as a string:\n        // https://github.com/nodejs/node/blob/v22.8.0/lib/_http_outgoing.js#L1131\n        if (data === endChunked) {\n          internalWritable.end(cb);\n          return true;\n        }\n\n        // check for header or data crlf\n        // node sends the header and data crlf as a buffer\n        // below code is aligned to following node implementation of the HTTP/1.1 chunked transfer coding:\n        // https://github.com/nodejs/node/blob/v22.8.0/lib/_http_outgoing.js#L1012-L1015\n        // for reference: https://datatracker.ietf.org/doc/html/rfc9112#section-7\n        if (Buffer.isBuffer(data) && crlfBuffer.equals(data)) {\n          const isHeaderCrlf = !firstCrlfBufferEncountered;\n          if (isHeaderCrlf) {\n            firstCrlfBufferEncountered = true;\n            return true;\n          }\n\n          const isDataCrlf = firstCrlfBufferEncountered && chunkEncountered;\n          if (isDataCrlf) {\n            // done with chunk\n            firstCrlfBufferEncountered = false;\n            chunkEncountered = false;\n            return true;\n          }\n\n          // the crlf *is* the chunk\n        }\n\n        const isContentLength = !firstCrlfBufferEncountered;\n        if (isContentLength) {\n          // discard content length\n          return true;\n        }\n\n        // write chunk\n        chunkEncountered = true;\n        internalWritable.write(data, cb);\n        return true;\n      },\n    };\n\n    this.assignSocket(socket as unknown as Socket);\n  }\n}\n","//#region Imports\n\nimport type { BinarySettings } from '../@types';\nimport type {\n  AdapterContract,\n  AdapterRequest,\n  FrameworkContract,\n  HandlerContract,\n  ResolverContract,\n  ServerlessHandler,\n} from '../contracts';\nimport { ServerlessRequest, ServerlessResponse } from '../network';\nimport type { ILogger } from './index';\n\n//#endregion\n\n/**\n * The abstract class that represents the base class for a handler\n *\n * @breadcrumb Core\n * @public\n */\nexport abstract class BaseHandler<\n  TApp,\n  TEvent,\n  TContext,\n  TCallback,\n  TResponse,\n  TReturn,\n> implements\n    HandlerContract<TApp, TEvent, TContext, TCallback, TResponse, TReturn>\n{\n  //#region Public Methods\n\n  /**\n   * Get the handler that will handle serverless requests\n   */\n  public abstract getHandler(\n    app: TApp,\n    framework: FrameworkContract<TApp>,\n    adapters: AdapterContract<TEvent, TContext, TResponse>[],\n    resolverFactory: ResolverContract<\n      TEvent,\n      TContext,\n      TCallback,\n      TResponse,\n      TReturn\n    >,\n    binarySettings: BinarySettings,\n    respondWithErrors: boolean,\n    log: ILogger,\n  ): ServerlessHandler<TReturn>;\n\n  //#endregion\n\n  //#region Protected Methods\n\n  /**\n   * Get the adapter to handle a specific event and context\n   *\n   * @param event - The event sent by serverless\n   * @param context - The context sent by serverless\n   * @param adapters - The list of adapters\n   * @param log - The instance of logger\n   */\n  protected getAdapterByEventAndContext(\n    event: TEvent,\n    context: TContext,\n    adapters: AdapterContract<TEvent, TContext, TResponse>[],\n    log: ILogger,\n  ): AdapterContract<TEvent, TContext, TResponse> {\n    const resolvedAdapters = adapters.filter(adapter =>\n      adapter.canHandle(event, context, log),\n    );\n\n    if (resolvedAdapters.length === 0) {\n      throw new Error(\n        \"SERVERLESS_ADAPTER: Couldn't find adapter to handle this event.\",\n      );\n    }\n\n    if (resolvedAdapters.length > 1) {\n      throw new Error(\n        `SERVERLESS_ADAPTER: Two or more adapters was resolved by the event, the adapters are: ${adapters\n          .map(adapter => adapter.getAdapterName())\n          .join(', ')}.`,\n      );\n    }\n\n    return resolvedAdapters[0];\n  }\n\n  /**\n   * Get serverless request and response frmo the adapter request\n   *\n   * @param requestValues - The request values from adapter\n   */\n  protected getServerlessRequestResponseFromAdapterRequest(\n    requestValues: AdapterRequest,\n  ): [request: ServerlessRequest, response: ServerlessResponse] {\n    const request = new ServerlessRequest({\n      method: requestValues.method,\n      headers: requestValues.headers,\n      body: requestValues.body,\n      remoteAddress: requestValues.remoteAddress,\n      url: requestValues.path,\n    });\n\n    const response = new ServerlessResponse({\n      method: requestValues.method,\n    });\n\n    return [request, response];\n  }\n\n  //#endregion\n}\n"],"mappings":"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","names":["IncomingMessage","DEFAULT_BINARY_ENCODINGS","DEFAULT_BINARY_CONTENT_TYPES","EmptyResponse","currentInvoke","getCurrentInvoke","__name","setCurrentInvoke","event","context","getEventBodyAsBuffer","body","isBase64Encoded","encoding","buffer","contentLength","__name","getFlattenedHeadersMap","headersMap","separator","lowerCaseKey","acc","headerKey","newKey","headerValue","__name","getMultiValueHeadersMap","getFlattenedHeadersMapAndCookies","lowerHeaderKey","parseHeaders","headers","result","headersArr","i","row","index","key","value","keysToLowercase","obj","k","v","isContentEncodingBinary","headers","binaryEncodingTypes","contentEncodings","value","__name","getContentType","contentTypeHeaderRaw","contentTypeHeader","contentTypeStart","isContentTypeBinary","binaryContentTypes","contentType","isBinary","binarySettings","NO_OP","__name","InternalLoggerSymbol","logLevels","lazyPrint","__name","value","print","fn","message","additional","createDefaultLogger","level","levels","logger","NO_OP","consoleMethod","isInternalLogger","getDefaultIfUndefined","value","defaultValue","__name","getPathWithQueryStringParams","path","queryParams","queryParamsString","getQueryParamsStringFromRecord","__name","queryParamsRecord","searchParams","multiValueHeadersEntries","key","value","arrayValue","NOOPBasePath","buildStripBasePath","basePath","length","isStreamEnded","stream","__name","waitForStreamComplete","resolve","reject","isComplete","complete","err","HTTPS_PORT","ServerlessRequest","IncomingMessage","__name","method","url","headers","body","remoteAddress","NO_OP","ServerResponse","getString","data","__name","headerEnd","endChunked","BODY","HEADERS","addData","stream","data","__name","ServerlessResponse","_ServerlessResponse","ServerResponse","method","writesToIgnore","socket","NO_OP","encoding","cb","string","getString","index","remainder","res","response","headers","key","value","statusCode","statusMessage","obj","headersObjOrArray","arrayHeaders","name","ServerResponse","crlfBuffer","endChunked","headerEnd","endStatusSeparator","ServerlessStreamResponse","ServerResponse","__name","method","onReceiveHeaders","log","internalWritable","firstCrlfBufferEncountered","chunkEncountered","socket","NO_OP","data","encoding","cb","stringData","getString","endStatusIndex","status","endHeaderIndex","headerData","headers","parseHeaders","BaseHandler","__name","event","context","adapters","log","resolvedAdapters","adapter","requestValues","request","ServerlessRequest","response","ServerlessResponse"]}