react-router
Version:
Declarative routing for React
74 lines (73 loc) • 2.97 kB
JavaScript
/**
* react-router v8.0.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
import invariant from "./invariant.js";
import { splitSetCookieString } from "cookie-es";
//#region lib/server-runtime/headers.ts
function getDocumentHeaders(context, build) {
return getDocumentHeadersImpl(context, (m) => {
let route = build.routes[m.route.id];
invariant(route, `Route with id "${m.route.id}" not found in build`);
return route.module.headers;
});
}
function getDocumentHeadersImpl(context, getRouteHeadersFn, _defaultHeaders) {
let boundaryIdx = context.errors ? context.matches.findIndex((m) => context.errors[m.route.id]) : -1;
let matches = boundaryIdx >= 0 ? context.matches.slice(0, boundaryIdx + 1) : context.matches;
let errorHeaders;
if (boundaryIdx >= 0) {
let { actionHeaders, actionData, loaderHeaders, loaderData } = context;
context.matches.slice(boundaryIdx).some((match) => {
let id = match.route.id;
if (actionHeaders[id] && (!actionData || !actionData.hasOwnProperty(id))) errorHeaders = actionHeaders[id];
else if (loaderHeaders[id] && !loaderData.hasOwnProperty(id)) errorHeaders = loaderHeaders[id];
return errorHeaders != null;
});
}
const defaultHeaders = new Headers(_defaultHeaders);
return matches.reduce((parentHeaders, match, idx) => {
let { id } = match.route;
let loaderHeaders = context.loaderHeaders[id] || new Headers();
let actionHeaders = context.actionHeaders[id] || new Headers();
let includeErrorHeaders = errorHeaders != null && idx === matches.length - 1;
let includeErrorCookies = includeErrorHeaders && errorHeaders !== loaderHeaders && errorHeaders !== actionHeaders;
let headersFn = getRouteHeadersFn(match);
if (headersFn == null) {
let headers = new Headers(parentHeaders);
if (includeErrorCookies) prependCookies(errorHeaders, headers);
prependCookies(actionHeaders, headers);
prependCookies(loaderHeaders, headers);
return headers;
}
let headers = new Headers(typeof headersFn === "function" ? headersFn({
loaderHeaders,
parentHeaders,
actionHeaders,
errorHeaders: includeErrorHeaders ? errorHeaders : void 0
}) : headersFn);
if (includeErrorCookies) prependCookies(errorHeaders, headers);
prependCookies(actionHeaders, headers);
prependCookies(loaderHeaders, headers);
prependCookies(parentHeaders, headers);
return headers;
}, new Headers(defaultHeaders));
}
function prependCookies(parentHeaders, childHeaders) {
let parentSetCookieString = parentHeaders.get("Set-Cookie");
if (parentSetCookieString) {
let cookies = splitSetCookieString(parentSetCookieString);
let childCookies = new Set(childHeaders.getSetCookie());
cookies.forEach((cookie) => {
if (!childCookies.has(cookie)) childHeaders.append("Set-Cookie", cookie);
});
}
}
//#endregion
export { getDocumentHeaders };