@remix-run/server-runtime
Version:
Server runtime for Remix
141 lines (131 loc) • 3.94 kB
JavaScript
/**
* @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
*/
;
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;