"use client";

"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "fetchServerResponse", {
    enumerable: true,
    get: function() {
        return fetchServerResponse;
    }
});
const _approuterheaders = require("../app-router-headers");
const _appcallserver = require("../../app-call-server");
const _routerreducertypes = require("./router-reducer-types");
const _hash = require("../../../shared/lib/hash");
// @ts-ignore
// eslint-disable-next-line import/no-extraneous-dependencies
// import { createFromFetch } from 'react-server-dom-webpack/client'
const { createFromFetch } = !!process.env.NEXT_RUNTIME ? require('react-server-dom-webpack/client.edge') : require('react-server-dom-webpack/client');
function urlToUrlWithoutFlightMarker(url) {
    const urlWithoutFlightParameters = new URL(url, location.origin);
    urlWithoutFlightParameters.searchParams.delete(_approuterheaders.NEXT_RSC_UNION_QUERY);
    if (process.env.NODE_ENV === 'production') {
        if (process.env.__NEXT_CONFIG_OUTPUT === 'export' && urlWithoutFlightParameters.pathname.endsWith('.txt')) {
            const { pathname } = urlWithoutFlightParameters;
            const length = pathname.endsWith('/index.txt') ? 10 : 4;
            // Slice off `/index.txt` or `.txt` from the end of the pathname
            urlWithoutFlightParameters.pathname = pathname.slice(0, -length);
        }
    }
    return urlWithoutFlightParameters;
}
function doMpaNavigation(url) {
    return {
        flightData: urlToUrlWithoutFlightMarker(url).toString(),
        canonicalUrl: undefined,
        couldBeIntercepted: false,
        isPrerender: false,
        postponed: false
    };
}
async function fetchServerResponse(url, options) {
    const { flightRouterState, nextUrl, buildId, prefetchKind } = options;
    const headers = {
        // Enable flight response
        [_approuterheaders.RSC_HEADER]: '1',
        // Provide the current router state
        [_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER]: encodeURIComponent(JSON.stringify(flightRouterState))
    };
    /**
   * Three cases:
   * - `prefetchKind` is `undefined`, it means it's a normal navigation, so we want to prefetch the page data fully
   * - `prefetchKind` is `full` - we want to prefetch the whole page so same as above
   * - `prefetchKind` is `auto` - if the page is dynamic, prefetch the page data partially, if static prefetch the page data fully
   */ if (prefetchKind === _routerreducertypes.PrefetchKind.AUTO) {
        headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER] = '1';
    }
    if (process.env.NODE_ENV === 'development' && options.isHmrRefresh) {
        headers[_approuterheaders.NEXT_HMR_REFRESH_HEADER] = '1';
    }
    if (nextUrl) {
        headers[_approuterheaders.NEXT_URL] = nextUrl;
    }
    if (process.env.NEXT_DEPLOYMENT_ID) {
        headers['x-deployment-id'] = process.env.NEXT_DEPLOYMENT_ID;
    }
    const uniqueCacheQuery = (0, _hash.hexHash)([
        headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER] || '0',
        headers[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER],
        headers[_approuterheaders.NEXT_URL]
    ].join(','));
    try {
        var _res_headers_get;
        let fetchUrl = new URL(url);
        if (process.env.NODE_ENV === 'production') {
            if (process.env.__NEXT_CONFIG_OUTPUT === 'export') {
                if (fetchUrl.pathname.endsWith('/')) {
                    fetchUrl.pathname += 'index.txt';
                } else {
                    fetchUrl.pathname += '.txt';
                }
            }
        }
        // Add unique cache query to avoid caching conflicts on CDN which don't respect the Vary header
        fetchUrl.searchParams.set(_approuterheaders.NEXT_RSC_UNION_QUERY, uniqueCacheQuery);
        // When creating a "temporary" prefetch (the "on-demand" prefetch that gets created on navigation, if one doesn't exist)
        // we send the request with a "high" priority as it's in response to a user interaction that could be blocking a transition.
        // Otherwise, all other prefetches are sent with a "low" priority.
        // We use "auto" for in all other cases to match the existing default, as this function is shared outside of prefetching.
        const fetchPriority = prefetchKind ? prefetchKind === _routerreducertypes.PrefetchKind.TEMPORARY ? 'high' : 'low' : 'auto';
        if (process.env.__NEXT_TEST_MODE) {
            headers['Next-Test-Fetch-Priority'] = fetchPriority;
        }
        const res = await fetch(fetchUrl, {
            // Backwards compat for older browsers. `same-origin` is the default in modern browsers.
            credentials: 'same-origin',
            headers,
            priority: fetchPriority
        });
        const responseUrl = urlToUrlWithoutFlightMarker(res.url);
        const canonicalUrl = res.redirected ? responseUrl : undefined;
        const contentType = res.headers.get('content-type') || '';
        const interception = !!((_res_headers_get = res.headers.get('vary')) == null ? void 0 : _res_headers_get.includes(_approuterheaders.NEXT_URL));
        const isPrerender = !!res.headers.get(_approuterheaders.NEXT_IS_PRERENDER_HEADER);
        const postponed = !!res.headers.get(_approuterheaders.NEXT_DID_POSTPONE_HEADER);
        let isFlightResponse = contentType === _approuterheaders.RSC_CONTENT_TYPE_HEADER;
        if (process.env.NODE_ENV === 'production') {
            if (process.env.__NEXT_CONFIG_OUTPUT === 'export') {
                if (!isFlightResponse) {
                    isFlightResponse = contentType.startsWith('text/plain');
                }
            }
        }
        // If fetch returns something different than flight response handle it like a mpa navigation
        // If the fetch was not 200, we also handle it like a mpa navigation
        if (!isFlightResponse || !res.ok) {
            // in case the original URL came with a hash, preserve it before redirecting to the new URL
            if (url.hash) {
                responseUrl.hash = url.hash;
            }
            return doMpaNavigation(responseUrl.toString());
        }
        // We may navigate to a page that requires a different Webpack runtime.
        // In prod, every page will have the same Webpack runtime.
        // In dev, the Webpack runtime is minimal for each page.
        // We need to ensure the Webpack runtime is updated before executing client-side JS of the new page.
        if (process.env.NODE_ENV !== 'production' && !process.env.TURBOPACK) {
            await require('../react-dev-overlay/app/hot-reloader-client').waitForWebpackRuntimeHotUpdate();
        }
        // Handle the `fetch` readable stream that can be unwrapped by `React.use`.
        const response = await createFromFetch(Promise.resolve(res), {
            callServer: _appcallserver.callServer
        });
        if (buildId !== response.b) {
            return doMpaNavigation(res.url);
        }
        return {
            flightData: response.f,
            canonicalUrl: canonicalUrl,
            couldBeIntercepted: interception,
            isPrerender: isPrerender,
            postponed
        };
    } catch (err) {
        console.error("Failed to fetch RSC payload for " + url + ". Falling back to browser navigation.", err);
        // If fetch fails handle it like a mpa navigation
        // TODO-APP: Add a test for the case where a CORS request fails, e.g. external url redirect coming from the response.
        // See https://github.com/vercel/next.js/issues/43605#issuecomment-1451617521 for a reproduction.
        return {
            flightData: url.toString(),
            canonicalUrl: undefined,
            couldBeIntercepted: false,
            isPrerender: false,
            postponed: false
        };
    }
}

if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
  Object.defineProperty(exports.default, '__esModule', { value: true });
  Object.assign(exports.default, exports);
  module.exports = exports.default;
}

//# sourceMappingURL=fetch-server-response.js.map