/**
 * This module was for the most part based on the code of cfworker's RequestBuilder
 * https://github.com/cfworker/cfworker/blob/master/packages/web/src/response-builder.ts
 *
 * The main differences:
 * - No magic static setting
 * - No magic statusText handling
 * - Removed etag, lastModified, type helpers, instead added 'set' and 'get' shorthands.
 *
 * (MIT Licensed)
 */ import { HeadersShorthands } from "../context" ; import { HttpStatus , RedirectStatus } from "../status" ; /**
 * The different types that can be sniffed and converted to a valid body automatically.
 */ export type ExtendedBodyInit = BodyInit | boolean | Date | number | object | undefined | null ; /**
 * The data that will be used as the response for the request.
 */ export class ResponseData implements ResponseInit , HeadersShorthands { public headers = new Headers ( { } ) ; public status ? : number ; public statusText ? : string ; /**
     * Cloudflare Worker websocket, non-standard API
     */ public webSocket ? : WebSocket | null ; private _implicitType = false ; private _stringifyBody = false ; private _body : ExtendedBodyInit ; get body ( ) { return this . _body ; } set body ( value ) { this . _body = value ; if ( value === undefined || value === null ) { this . headers . delete ( "content-type" ) ; this . headers . delete ( "content-length" ) ; this . headers . delete ( "transfer-encoding" ) ; return ; } if ( value instanceof FormData || value instanceof URLSearchParams || ArrayBuffer . isView ( value ) || value instanceof ArrayBuffer || value instanceof ReadableStream ) { this . _stringifyBody = false ; if ( this . _implicitType ) { this . _implicitType = false ; this . headers . delete ( "content-type" ) ; } } else if ( typeof value === "string" ) { this . _stringifyBody = false ; if ( ! this . headers . has ( "content-type" ) || this . _implicitType ) { this . _implicitType = true ; if ( /^\s*</ . test ( value ) ) { this . headers . set ( "content-type" , "text/html;charset=UTF-8" ) ; } else { this . headers . set ( "content-type" , "text/plain;charset=UTF-8" ) ; } } } else { this . _stringifyBody = true ; this . _implicitType = true ; this . headers . set ( "content-type" , "application/json;charset=UTF-8" ) ; } } set ( name , value ) { this . headers . set ( name , value ) ; } get ( name ) { return this . headers . get ( name ) ; } has ( name ) { return this . headers . has ( name ) ; } param url param status redirect ( url , status = HttpStatus . Found ) { this . status = status ; this . headers . set ( "location" , url instanceof URL ? url . href : url ) ; } param response param opts overwrite ( response , opts = { } ) { if ( opts . mergeHeaders ) { for ( const [ k , v ] of response . headers ) { this . headers . set ( k , v ) ; } } else { this . headers = response . headers ; } this . body = response . body ; this . status = response . status ; this . statusText = response . statusText ; this . webSocket = response . webSocket ; } /**
     * Create a native Response object, which is what FetchEvent expectst
     */ createResponse ( ) { const { body : rawBody , status , statusText , headers , webSocket } = this ; const body = this . _stringifyBody ? JSON . stringify ( rawBody ) : rawBody as Exclude < ExtendedBodyInit , number | boolean | object > ; return new Response ( body , { headers , webSocket , status , statusText } ) ; } }