UNPKG

@remix-run/server-runtime

Version:
141 lines (131 loc) 3.94 kB
/** * @remix-run/server-runtime v2.16.8 * * 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 */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var responses = require('./responses.js'); /** * An object of unknown type for route loaders and actions provided by the * server's `getLoadContext()` function. This is defined as an empty interface * specifically so apps can leverage declaration merging to augment this type * globally: https://www.typescriptlang.org/docs/handbook/declaration-merging.html */ /** * Data for a route that was returned from a `loader()`. */ async function callRouteAction({ loadContext, action, params, request, routeId, singleFetch }) { let result = await action({ request: singleFetch ? stripRoutesParam(stripIndexParam(request)) : stripDataParam(stripIndexParam(request)), context: loadContext, params }); if (result === undefined) { throw new Error(`You defined an action for route "${routeId}" but didn't return ` + `anything from your \`action\` function. Please return a value or \`null\`.`); } // Allow naked object returns when single fetch is enabled if (singleFetch) { return result; } return responses.isResponse(result) ? result : responses.json(result); } async function callRouteLoader({ loadContext, loader, params, request, routeId, singleFetch }) { let result = await loader({ request: singleFetch ? stripRoutesParam(stripIndexParam(request)) : stripDataParam(stripIndexParam(request)), context: loadContext, params }); if (result === undefined) { throw new Error(`You defined a loader for route "${routeId}" but didn't return ` + `anything from your \`loader\` function. Please return a value or \`null\`.`); } if (responses.isDeferredData(result)) { if (result.init && responses.isRedirectStatusCode(result.init.status || 200)) { return responses.redirect(new Headers(result.init.headers).get("Location"), result.init); } return result; } // Allow naked object returns when single fetch is enabled if (singleFetch) { return result; } return responses.isResponse(result) ? result : responses.json(result); } // TODO: Document these search params better // and stop stripping these in V2. These break // support for running in a SW and also expose // valuable info to data funcs that is being asked // for such as "is this a data request?". function stripIndexParam(request) { let url = new URL(request.url); let indexValues = url.searchParams.getAll("index"); url.searchParams.delete("index"); let indexValuesToKeep = []; for (let indexValue of indexValues) { if (indexValue) { indexValuesToKeep.push(indexValue); } } for (let toKeep of indexValuesToKeep) { url.searchParams.append("index", toKeep); } let init = { method: request.method, body: request.body, headers: request.headers, signal: request.signal }; if (init.body) { init.duplex = "half"; } return new Request(url.href, init); } function stripDataParam(request) { let url = new URL(request.url); url.searchParams.delete("_data"); let init = { method: request.method, body: request.body, headers: request.headers, signal: request.signal }; if (init.body) { init.duplex = "half"; } return new Request(url.href, init); } function stripRoutesParam(request) { let url = new URL(request.url); url.searchParams.delete("_routes"); let init = { method: request.method, body: request.body, headers: request.headers, signal: request.signal }; if (init.body) { init.duplex = "half"; } return new Request(url.href, init); } exports.callRouteAction = callRouteAction; exports.callRouteLoader = callRouteLoader;