| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 |
|
| 11 | import invariant from "./invariant.js";
|
| 12 | import { splitSetCookieString } from "cookie-es";
|
| 13 |
|
| 14 | function getDocumentHeaders(context, build) {
|
| 15 | return getDocumentHeadersImpl(context, (m) => {
|
| 16 | let route = build.routes[m.route.id];
|
| 17 | invariant(route, `Route with id "${m.route.id}" not found in build`);
|
| 18 | return route.module.headers;
|
| 19 | });
|
| 20 | }
|
| 21 | function getDocumentHeadersImpl(context, getRouteHeadersFn, _defaultHeaders) {
|
| 22 | let boundaryIdx = context.errors ? context.matches.findIndex((m) => context.errors[m.route.id]) : -1;
|
| 23 | let matches = boundaryIdx >= 0 ? context.matches.slice(0, boundaryIdx + 1) : context.matches;
|
| 24 | let errorHeaders;
|
| 25 | if (boundaryIdx >= 0) {
|
| 26 | let { actionHeaders, actionData, loaderHeaders, loaderData } = context;
|
| 27 | context.matches.slice(boundaryIdx).some((match) => {
|
| 28 | let id = match.route.id;
|
| 29 | if (actionHeaders[id] && (!actionData || !actionData.hasOwnProperty(id))) errorHeaders = actionHeaders[id];
|
| 30 | else if (loaderHeaders[id] && !loaderData.hasOwnProperty(id)) errorHeaders = loaderHeaders[id];
|
| 31 | return errorHeaders != null;
|
| 32 | });
|
| 33 | }
|
| 34 | const defaultHeaders = new Headers(_defaultHeaders);
|
| 35 | return matches.reduce((parentHeaders, match, idx) => {
|
| 36 | let { id } = match.route;
|
| 37 | let loaderHeaders = context.loaderHeaders[id] || new Headers();
|
| 38 | let actionHeaders = context.actionHeaders[id] || new Headers();
|
| 39 | let includeErrorHeaders = errorHeaders != null && idx === matches.length - 1;
|
| 40 | let includeErrorCookies = includeErrorHeaders && errorHeaders !== loaderHeaders && errorHeaders !== actionHeaders;
|
| 41 | let headersFn = getRouteHeadersFn(match);
|
| 42 | if (headersFn == null) {
|
| 43 | let headers = new Headers(parentHeaders);
|
| 44 | if (includeErrorCookies) prependCookies(errorHeaders, headers);
|
| 45 | prependCookies(actionHeaders, headers);
|
| 46 | prependCookies(loaderHeaders, headers);
|
| 47 | return headers;
|
| 48 | }
|
| 49 | let headers = new Headers(typeof headersFn === "function" ? headersFn({
|
| 50 | loaderHeaders,
|
| 51 | parentHeaders,
|
| 52 | actionHeaders,
|
| 53 | errorHeaders: includeErrorHeaders ? errorHeaders : void 0
|
| 54 | }) : headersFn);
|
| 55 | if (includeErrorCookies) prependCookies(errorHeaders, headers);
|
| 56 | prependCookies(actionHeaders, headers);
|
| 57 | prependCookies(loaderHeaders, headers);
|
| 58 | prependCookies(parentHeaders, headers);
|
| 59 | return headers;
|
| 60 | }, new Headers(defaultHeaders));
|
| 61 | }
|
| 62 | function prependCookies(parentHeaders, childHeaders) {
|
| 63 | let parentSetCookieString = parentHeaders.get("Set-Cookie");
|
| 64 | if (parentSetCookieString) {
|
| 65 | let cookies = splitSetCookieString(parentSetCookieString);
|
| 66 | let childCookies = new Set(childHeaders.getSetCookie());
|
| 67 | cookies.forEach((cookie) => {
|
| 68 | if (!childCookies.has(cookie)) childHeaders.append("Set-Cookie", cookie);
|
| 69 | });
|
| 70 | }
|
| 71 | }
|
| 72 |
|
| 73 | export { getDocumentHeaders };
|