This commit is contained in:
parent
fbfc3430a0
commit
1e1ede6cf0
207 changed files with 12220 additions and 0 deletions
96
server.mjs
Normal file
96
server.mjs
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import { createReadStream, existsSync, readFileSync, statSync } from "node:fs";
|
||||
import { createServer } from "node:http";
|
||||
import { extname, join, relative, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const root = resolve(fileURLToPath(new URL(".", import.meta.url)), "website");
|
||||
const publicRoot = join(root, "public");
|
||||
|
||||
function loadEnvFile(file = ".env") {
|
||||
if (!existsSync(file)) return;
|
||||
|
||||
const lines = readFileSync(file, "utf8").split(/\r?\n/);
|
||||
lines.forEach((line) => {
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed || trimmed.startsWith("#")) return;
|
||||
|
||||
const separatorIndex = trimmed.indexOf("=");
|
||||
if (separatorIndex < 1) return;
|
||||
|
||||
const key = trimmed.slice(0, separatorIndex).trim();
|
||||
const value = trimmed.slice(separatorIndex + 1).trim().replace(/^["']|["']$/g, "");
|
||||
if (!process.env[key]) process.env[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
loadEnvFile();
|
||||
|
||||
const port = Number(process.env.PORT || 5173);
|
||||
|
||||
const types = {
|
||||
".html": "text/html; charset=utf-8",
|
||||
".css": "text/css; charset=utf-8",
|
||||
".js": "text/javascript; charset=utf-8",
|
||||
".json": "application/json; charset=utf-8",
|
||||
".svg": "image/svg+xml",
|
||||
".ico": "image/x-icon",
|
||||
".png": "image/png",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".webp": "image/webp"
|
||||
};
|
||||
|
||||
function isInsideRoot(parent, file) {
|
||||
const relativePath = relative(parent, file);
|
||||
return Boolean(relativePath) && !relativePath.startsWith("..") && !relativePath.startsWith("/");
|
||||
}
|
||||
|
||||
function fileIfReadable(file) {
|
||||
return isInsideRoot(root, file) && existsSync(file) && statSync(file).isFile() ? file : null;
|
||||
}
|
||||
|
||||
function resolvePath(url) {
|
||||
let requested;
|
||||
try {
|
||||
requested = decodeURIComponent(new URL(url, "http://localhost").pathname);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
const candidate = fileIfReadable(resolve(root, `.${requested}`));
|
||||
if (candidate) return candidate;
|
||||
|
||||
const publicCandidate = fileIfReadable(resolve(publicRoot, `.${requested}`));
|
||||
if (publicCandidate && isInsideRoot(publicRoot, publicCandidate)) return publicCandidate;
|
||||
|
||||
return join(publicRoot, "index.html");
|
||||
}
|
||||
|
||||
const server = createServer((req, res) => {
|
||||
const file = resolvePath(req.url || "/");
|
||||
if (!file || !existsSync(file)) {
|
||||
res.writeHead(404);
|
||||
res.end("Not found");
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(200, {
|
||||
"Content-Type": types[extname(file)] || "application/octet-stream",
|
||||
"Cache-Control": "no-store"
|
||||
});
|
||||
createReadStream(file).pipe(res);
|
||||
});
|
||||
|
||||
server.on("error", (error) => {
|
||||
if (error.code === "EADDRINUSE") {
|
||||
console.error(`Port ${port} is already in use. Set PORT to another value.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log(`Sokko G dev server running at http://localhost:${port}`);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue