Repository navigation
Expand file tree
/
Copy pathserver.ts
More file actions
89 lines (74 loc) · 2.99 KB
/
Copy pathserver.ts
File metadata and controls
89 lines (74 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import "dotenv/config";
import dns from "dns";
import { execFileSync } from "child_process";
import type { NextFunction, Request, Response } from "express";
import express from "express";
import fs from "fs/promises";
import http from "http";
import multer from "multer";
import path from "path";
import { Server } from "socket.io";
import cors from "cors";
import { createFileRouter } from "./routes/fileRoutes";
import { INVALID_FILE_TYPE } from "./config/errorMessages";
import { ytDlpBinaryPath } from "./config/ytDlpConfig";
import { ALLOWED_ORIGINS } from "./config/allowedOrigins";
import { MAX_UPLOAD_SIZE_MB } from "./config/limits";
dns.setDefaultResultOrder("ipv4first");
const app = express();
app.set("trust proxy", 1);
const server = http.createServer(app);
const io = new Server(server, {
cors: { origin: ALLOWED_ORIGINS, methods: ["GET", "POST"] },
});
const PORT = process.env.PORT || 3000;
const UPLOADS_DIR = path.join(process.cwd(), "uploads");
const OUTPUTS_DIR = path.join(process.cwd(), "outputs");
process.on("SIGTERM", () => server.close());
process.on("SIGINT", () => server.close());
async function ensureDirectories() {
await Promise.all([
fs.mkdir(UPLOADS_DIR, { recursive: true }),
fs.mkdir(OUTPUTS_DIR, { recursive: true }),
]);
console.log("Directories ready:", UPLOADS_DIR, OUTPUTS_DIR);
}
function logYtDlpVersion() {
try {
const version = execFileSync(ytDlpBinaryPath, ["--version"], { encoding: "utf8" }).trim();
console.log(`[STARTUP] yt-dlp ${version} at ${ytDlpBinaryPath}`);
} catch (err: any) {
console.warn("[STARTUP] yt-dlp not found:", err.message);
}
}
app.disable("x-powered-by");
app.use(cors({ origin: ALLOWED_ORIGINS }));
app.use(express.json({ limit: "1mb", strict: true }));
app.use(express.urlencoded({ extended: false, limit: "1mb" }));
app.use((req, _res, next) => {
const body = req.is("multipart/form-data") ? "[multipart]" : JSON.stringify(req.body);
console.log(`${req.method} ${req.path}`, body);
next();
});
app.get("/", (_req, res) => res.status(200).send("StripIt backend is running."));
app.get("/health", (_req, res) => res.status(200).json({ status: "ok" }));
app.use(createFileRouter(io, OUTPUTS_DIR, UPLOADS_DIR));
app.use((err: unknown, _req: Request, res: Response, _next: NextFunction) => {
if (err instanceof multer.MulterError && err.code === "LIMIT_FILE_SIZE") {
return res.status(413).json({ error: `File too large. Max allowed size is ${MAX_UPLOAD_SIZE_MB}MB` });
}
if (err instanceof Error && err.message === INVALID_FILE_TYPE) {
return res.status(400).json({ error: err.message });
}
if (err instanceof Error) {
return res.status(500).json({ error: err.message || "Internal server error" });
}
return res.status(500).json({ error: "Internal server error" });
});
logYtDlpVersion();
ensureDirectories()
.then(() => server.listen(PORT, () => console.log(`Server running on port ${PORT}`)))
.catch((error) => {
console.error("Failed to initialize directories:", error);
process.exit(1);
});