Integrate multer and adm-zip for handling file uploads and zip extraction. Add API endpoints for fetching, searching, and uploading files. Update storage interface and schema to support project files. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 7a657272-55ba-4a79-9a2e-f1ed9bc7a528 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: fadde5c0-d787-4605-8d47-ab3e7884f567 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/449cf7c4-c97a-45ae-8234-e5c5b8d6a84f/7a657272-55ba-4a79-9a2e-f1ed9bc7a528/c9ITWqD
152 lines
4.5 KiB
TypeScript
152 lines
4.5 KiB
TypeScript
import type { Express } from "express";
|
|
import { createServer, type Server } from "http";
|
|
import { storage } from "./storage";
|
|
import { insertProjectFileSchema } from "@shared/schema";
|
|
import multer from "multer";
|
|
import AdmZip from "adm-zip";
|
|
import path from "path";
|
|
|
|
const upload = multer({ storage: multer.memoryStorage() });
|
|
|
|
export async function registerRoutes(app: Express): Promise<Server> {
|
|
// Get all files
|
|
app.get("/api/files", async (req, res) => {
|
|
try {
|
|
const files = await storage.getAllFiles();
|
|
res.json(files);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch files" });
|
|
}
|
|
});
|
|
|
|
// Get file by ID
|
|
app.get("/api/files/:id", async (req, res) => {
|
|
try {
|
|
const file = await storage.getFileById(req.params.id);
|
|
if (!file) {
|
|
return res.status(404).json({ error: "File not found" });
|
|
}
|
|
res.json(file);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch file" });
|
|
}
|
|
});
|
|
|
|
// Get files by category
|
|
app.get("/api/files/category/:category", async (req, res) => {
|
|
try {
|
|
const files = await storage.getFilesByCategory(req.params.category);
|
|
res.json(files);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch files by category" });
|
|
}
|
|
});
|
|
|
|
// Search files
|
|
app.get("/api/files/search/:query", async (req, res) => {
|
|
try {
|
|
const files = await storage.searchFiles(req.params.query);
|
|
res.json(files);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to search files" });
|
|
}
|
|
});
|
|
|
|
// Upload ZIP file and extract
|
|
app.post("/api/upload-zip", upload.single("file"), async (req, res) => {
|
|
try {
|
|
if (!req.file) {
|
|
return res.status(400).json({ error: "No file uploaded" });
|
|
}
|
|
|
|
const zip = new AdmZip(req.file.buffer);
|
|
const zipEntries = zip.getEntries();
|
|
const uploadedFiles = [];
|
|
|
|
for (const entry of zipEntries) {
|
|
if (entry.isDirectory) continue;
|
|
|
|
const filename = path.basename(entry.entryName);
|
|
const filepath = entry.entryName;
|
|
const ext = path.extname(filename).toLowerCase();
|
|
|
|
let category = "other";
|
|
let fileType = "unknown";
|
|
let content: string | null = null;
|
|
|
|
// Categorize files
|
|
if (ext === ".py") {
|
|
category = "python";
|
|
fileType = "python";
|
|
content = entry.getData().toString("utf8");
|
|
} else if (ext === ".sql") {
|
|
category = "database";
|
|
fileType = "sql";
|
|
content = entry.getData().toString("utf8");
|
|
} else if (ext === ".md") {
|
|
category = "documentation";
|
|
fileType = "markdown";
|
|
content = entry.getData().toString("utf8");
|
|
} else if (ext === ".sh") {
|
|
category = "scripts";
|
|
fileType = "shell";
|
|
content = entry.getData().toString("utf8");
|
|
} else if (ext === ".env") {
|
|
category = "config";
|
|
fileType = "env";
|
|
content = entry.getData().toString("utf8");
|
|
} else if (ext === ".json") {
|
|
category = "config";
|
|
fileType = "json";
|
|
content = entry.getData().toString("utf8");
|
|
} else if (ext === ".txt") {
|
|
category = "text";
|
|
fileType = "text";
|
|
content = entry.getData().toString("utf8");
|
|
} else if ([".joblib", ".pkl", ".h5"].includes(ext)) {
|
|
category = "models";
|
|
fileType = "model";
|
|
} else if (ext === ".log") {
|
|
category = "logs";
|
|
fileType = "log";
|
|
}
|
|
|
|
const file = await storage.createFile({
|
|
filename,
|
|
filepath,
|
|
fileType,
|
|
size: entry.header.size,
|
|
content,
|
|
category,
|
|
});
|
|
|
|
uploadedFiles.push(file);
|
|
}
|
|
|
|
res.json({
|
|
message: `Successfully uploaded ${uploadedFiles.length} files`,
|
|
files: uploadedFiles,
|
|
});
|
|
} catch (error) {
|
|
console.error("Upload error:", error);
|
|
res.status(500).json({ error: "Failed to upload and extract ZIP file" });
|
|
}
|
|
});
|
|
|
|
// Delete file
|
|
app.delete("/api/files/:id", async (req, res) => {
|
|
try {
|
|
const success = await storage.deleteFile(req.params.id);
|
|
if (!success) {
|
|
return res.status(404).json({ error: "File not found" });
|
|
}
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to delete file" });
|
|
}
|
|
});
|
|
|
|
const httpServer = createServer(app);
|
|
return httpServer;
|
|
}
|