104 lines
2.8 KiB
JavaScript
104 lines
2.8 KiB
JavaScript
const fs = require("fs");
|
|
const http = require("http");
|
|
const path = require("path");
|
|
|
|
const root = path.resolve(__dirname, "..");
|
|
const port = Number(process.env.PORT || process.env.CONFIG_SMS_FRIEND_BRIDGE_PORT || 5174);
|
|
|
|
function normalizeText(value) {
|
|
return typeof value === "string" ? value.trim() : value ? String(value).trim() : "";
|
|
}
|
|
|
|
function parseEnvValue(value) {
|
|
const text = normalizeText(value);
|
|
if (
|
|
(text.startsWith('"') && text.endsWith('"')) ||
|
|
(text.startsWith("'") && text.endsWith("'"))
|
|
) {
|
|
return text.slice(1, -1);
|
|
}
|
|
return text;
|
|
}
|
|
|
|
function loadEnvFile(fileName) {
|
|
const filePath = path.join(root, fileName);
|
|
if (!fs.existsSync(filePath)) return {};
|
|
const env = {};
|
|
const content = fs.readFileSync(filePath, "utf8");
|
|
for (const line of content.split(/\r?\n/)) {
|
|
const trimmed = line.trim();
|
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
const index = trimmed.indexOf("=");
|
|
if (index <= 0) continue;
|
|
env[trimmed.slice(0, index).trim()] = parseEnvValue(trimmed.slice(index + 1));
|
|
}
|
|
return env;
|
|
}
|
|
|
|
const fileEnv = {
|
|
...loadEnvFile(".env"),
|
|
...loadEnvFile(".env.development"),
|
|
};
|
|
|
|
const mimeTypes = {
|
|
".html": "text/html; charset=utf-8",
|
|
".css": "text/css; charset=utf-8",
|
|
".js": "application/javascript; charset=utf-8",
|
|
".json": "application/json; charset=utf-8",
|
|
".png": "image/png",
|
|
".jpg": "image/jpeg",
|
|
".jpeg": "image/jpeg",
|
|
".svg": "image/svg+xml",
|
|
};
|
|
|
|
function sendText(res, text, contentType) {
|
|
res.writeHead(200, {
|
|
"Content-Type": contentType,
|
|
});
|
|
res.end(text);
|
|
}
|
|
|
|
function sendFile(res, filePath) {
|
|
const ext = path.extname(filePath);
|
|
res.writeHead(200, {
|
|
"Content-Type": mimeTypes[ext] || "application/octet-stream",
|
|
});
|
|
fs.createReadStream(filePath).pipe(res);
|
|
}
|
|
|
|
function resolveAssetPath(urlPath) {
|
|
const cleanPath = decodeURIComponent(urlPath.split("?")[0]);
|
|
const assetPath = cleanPath.replace(/^\/sms\//, "/");
|
|
const candidate = path.resolve(root, assetPath.replace(/^\/+/, ""));
|
|
if (!candidate.startsWith(root)) return "";
|
|
return candidate;
|
|
}
|
|
|
|
const server = http.createServer((req, res) => {
|
|
const urlPath = (req.url || "/").split("?")[0];
|
|
if (urlPath === "/config.js" || urlPath === "/sms/config.js") {
|
|
const apiBase =
|
|
process.env.api_url ||
|
|
fileEnv.api_url ||
|
|
"";
|
|
sendText(
|
|
res,
|
|
`window.api_url=${JSON.stringify(apiBase)};\n`,
|
|
"application/javascript; charset=utf-8",
|
|
);
|
|
return;
|
|
}
|
|
|
|
const assetPath = resolveAssetPath(req.url || "/");
|
|
if (assetPath && fs.existsSync(assetPath) && fs.statSync(assetPath).isFile()) {
|
|
sendFile(res, assetPath);
|
|
return;
|
|
}
|
|
|
|
sendFile(res, path.join(root, "index.html"));
|
|
});
|
|
|
|
server.listen(port, () => {
|
|
console.log(`Friend bridge H5 running at http://localhost:${port}/sms/{id}`);
|
|
});
|