mirror of
https://github.com/LukeHagar/sveltekit-adapters.git
synced 2025-12-06 12:47:48 +00:00
125 lines
3.4 KiB
JavaScript
125 lines
3.4 KiB
JavaScript
import { Server } from 'SERVER';
|
|
import { manifest, prerendered } from 'MANIFEST';
|
|
import { existsSync, readFileSync } from 'fs';
|
|
import { lookup } from 'mime-types';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const server = new Server(manifest);
|
|
|
|
const dir = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
/**
|
|
* @param {string} path
|
|
* @param {boolean} isClient
|
|
* @param {boolean} isStatic
|
|
* @returns {Record<string, string> }
|
|
* */
|
|
function mapCacheControl(path, isClient, isStatic) {
|
|
if (isClient && path.startsWith(`/${manifest.appPath}/immutable/`)) {
|
|
return { 'cache-control': 'public,max-age=31536000,immutable' };
|
|
} else if (isStatic) {
|
|
return { 'cache-control': 'public,max-age=31536000' };
|
|
} else {
|
|
return { 'cache-control': 'public,max-age=0,must-revalidate' };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} path
|
|
* @param {boolean} client
|
|
* @param {boolean} isStatic
|
|
* @returns {{ file: Buffer | undefined, headers: Record<string, string> }}
|
|
*/
|
|
function getStaticfile(path, client = false, isStatic = false) {
|
|
if (!existsSync(path)) return { file: undefined, headers: {} };
|
|
|
|
const file = readFileSync(path);
|
|
const mimeType = lookup(path);
|
|
const headers = {
|
|
'Content-Type': mimeType ? mimeType : 'text/plain',
|
|
...mapCacheControl(path, client, isStatic)
|
|
};
|
|
|
|
return { file, headers };
|
|
}
|
|
|
|
/** @type {import('./entry.js').default} */
|
|
export default async (opt) => {
|
|
const { req, res, log, error } = opt;
|
|
|
|
await server.init({
|
|
env: process.env
|
|
});
|
|
|
|
const url = new URL(req.url);
|
|
|
|
log(JSON.stringify(manifest, null, 4));
|
|
|
|
// client files first
|
|
if (url.pathname.startsWith(`/${manifest.appPath}`)) {
|
|
// split the pathname into parts and join them with the dir
|
|
const filePath = path.join(dir, 'client', url.pathname);
|
|
log('client asset');
|
|
log(url.pathname);
|
|
log(filePath);
|
|
const { file, headers } = getStaticfile(filePath, true);
|
|
if (file) return res.send(file.toString(), 200, headers);
|
|
}
|
|
|
|
// //prerendered assets
|
|
let { pathname } = url;
|
|
|
|
try {
|
|
pathname = decodeURIComponent(pathname);
|
|
} catch {
|
|
// ignore invalid URI
|
|
}
|
|
|
|
const stripped_pathname = pathname.replace(/\/$/, '');
|
|
|
|
// prerendered pages and /static files
|
|
let is_static_asset = false;
|
|
const filename = stripped_pathname.substring(1);
|
|
if (filename) {
|
|
is_static_asset = manifest.assets.has(filename);
|
|
}
|
|
|
|
// static assets
|
|
if (is_static_asset) {
|
|
// split the pathname into parts and join them with the dir
|
|
const filePath = path.join(dir, 'client', filename);
|
|
log('static asset');
|
|
log(filename);
|
|
log(filePath);
|
|
const { file, headers } = getStaticfile(filePath, false, true);
|
|
if (file) return res.send(file, 200, headers);
|
|
}
|
|
|
|
if (prerendered.has(pathname)) {
|
|
// split the pathname into parts and join them with the dir
|
|
const filePath = path.join(dir, 'prerendered', pathname + '.html');
|
|
log('prerendered asset');
|
|
log(pathname);
|
|
log(filePath);
|
|
const { file, headers } = getStaticfile(filePath, false);
|
|
if (file) return res.send(file.toString(), 200, headers);
|
|
}
|
|
|
|
const body = req.body !== '' ? req.body : undefined;
|
|
|
|
const request = new Request(req.url, {
|
|
headers: req.headers,
|
|
body,
|
|
method: req.method
|
|
});
|
|
|
|
const response = await server.respond(request, {
|
|
getClientAddress: () => request.headers.get('x-forwarded-for')
|
|
});
|
|
|
|
const respBody = await response.text();
|
|
|
|
return res.send(respBody, response.status, Object.fromEntries(response.headers.entries()));
|
|
};
|