@mcansh/remix-fastify
Version:
Fastify server request handler for Remix and React Router
173 lines (169 loc) • 5.95 kB
JavaScript
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const node_stream = __toESM(require("node:stream"));
const node_path = __toESM(require("node:path"));
const node_url = __toESM(require("node:url"));
const __fastify_static = __toESM(require("@fastify/static"));
const pretty_cache_header = __toESM(require("pretty-cache-header"));
//#region src/shared.ts
function createHeaders(requestHeaders) {
let headers = new Headers();
for (let [key, values] of Object.entries(requestHeaders)) if (values) if (Array.isArray(values)) for (let value of values) headers.append(key, value);
else headers.set(key, values);
return headers;
}
function getUrl(request) {
let origin = `${request.protocol}://${request.host}`;
let url$1 = `${origin}${request.originalUrl}`;
return url$1;
}
function createRequest(request, reply, createReadableStreamFromReadable) {
let url$1 = getUrl(request);
let controller = new AbortController();
let init = {
method: request.method,
headers: createHeaders(request.headers),
signal: controller.signal
};
reply.raw.on("finish", () => controller = null);
reply.raw.on("close", () => controller?.abort());
if (request.method !== "GET" && request.method !== "HEAD") {
init.body = createReadableStreamFromReadable(request.raw);
init.duplex = "half";
}
return new Request(url$1, init);
}
async function sendResponse(reply, nodeResponse) {
reply.status(nodeResponse.status);
for (let [key, values] of nodeResponse.headers.entries()) reply.headers({ [key]: values });
if (nodeResponse.body) {
let stream = responseToReadable(nodeResponse);
return reply.send(stream);
}
return reply.send(await nodeResponse.text());
}
function responseToReadable(response) {
if (!response.body) return null;
let reader = response.body.getReader();
let readable = new node_stream.Readable();
readable._read = async () => {
try {
let result = await reader.read();
if (!result.done) readable.push(Buffer.from(result.value));
else readable.push(null);
} catch (error) {
readable.destroy(error);
throw error;
}
};
return readable;
}
//#endregion
//#region src/plugins/index.ts
function createPlugin(fastify, { basename = "/", buildDirectory = "build", serverBuildFile = "index.js", getLoadContext, mode = process.env.NODE_ENV, viteOptions, fastifyStaticOptions, assetCacheControl = {
public: true,
maxAge: "1 year",
immutable: true
}, defaultCacheControl = {
public: true,
maxAge: "1 hour"
}, productionServerBuild, childServerOptions }, virtualModule, createRequestHandler) {
return async () => {
let cwd = process.env.REMIX_ROOT ?? process.cwd();
let vite;
if (mode !== "production") vite = await import("vite").then((mod) => {
return mod.createServer({
...viteOptions,
server: {
...viteOptions?.server,
middlewareMode: true
}
});
});
let resolvedBuildDirectory = node_path.default.resolve(cwd, buildDirectory);
let SERVER_BUILD = node_path.default.join(resolvedBuildDirectory, "server", serverBuildFile);
let SERVER_BUILD_URL = node_url.default.pathToFileURL(SERVER_BUILD).href;
let handler = createRequestHandler({
mode,
getLoadContext,
build: vite ? () => vite.ssrLoadModule(virtualModule) : productionServerBuild ?? await import(SERVER_BUILD_URL)
});
if (vite) {
let middie = await import("@fastify/middie").then((mod) => mod.default);
await fastify.register(middie);
fastify.use(vite.middlewares);
} else {
let BUILD_DIR = node_path.default.join(resolvedBuildDirectory, "client");
let ASSET_DIR = node_path.default.join(BUILD_DIR, "assets");
await fastify.register(__fastify_static.default, {
root: BUILD_DIR,
prefix: basename,
wildcard: false,
cacheControl: false,
dotfiles: "allow",
etag: true,
serveDotFiles: true,
lastModified: true,
setHeaders(res, filepath) {
let isAsset = filepath.startsWith(ASSET_DIR);
res.setHeader("cache-control", isAsset ? (0, pretty_cache_header.cacheHeader)(assetCacheControl) : (0, pretty_cache_header.cacheHeader)(defaultCacheControl));
},
...fastifyStaticOptions
});
}
fastify.register(async function createRemixRequestHandler(childServer) {
childServer.removeAllContentTypeParsers();
childServer.addContentTypeParser("*", (_request, payload, done) => {
done(null, payload);
});
if (childServerOptions) childServer.all("*", childServerOptions, handler);
else childServer.all("*", handler);
}, { prefix: basename });
};
}
//#endregion
Object.defineProperty(exports, '__toESM', {
enumerable: true,
get: function () {
return __toESM;
}
});
Object.defineProperty(exports, 'createPlugin', {
enumerable: true,
get: function () {
return createPlugin;
}
});
Object.defineProperty(exports, 'createRequest', {
enumerable: true,
get: function () {
return createRequest;
}
});
Object.defineProperty(exports, 'sendResponse', {
enumerable: true,
get: function () {
return sendResponse;
}
});
//# sourceMappingURL=plugins-B2SMtsK6.cjs.map