mirror of
https://github.com/freedbygrace/ActiveDirectoryManager.git
synced 2026-07-28 13:00:02 +00:00
11d0dcf0e8
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/30fe5a86-4e58-47d8-aa32-104aaf3a85ce.jpg
99 lines
2.8 KiB
TypeScript
99 lines
2.8 KiB
TypeScript
import { Express, Request, Response } from "express";
|
|
import archiver from "archiver";
|
|
import path from "path";
|
|
import fs from "fs";
|
|
import debugLib from "debug";
|
|
import { isAuthenticated } from "./authorization";
|
|
|
|
const debug = debugLib('api:download');
|
|
|
|
/**
|
|
* Sets up download endpoints for the application
|
|
* @param app Express application
|
|
*/
|
|
export function setupDownloadRoutes(app: Express) {
|
|
// Endpoint to download the entire application as a zip file
|
|
app.get('/api/download/app', isAuthenticated, (req: Request, res: Response) => {
|
|
debug('Download application requested');
|
|
|
|
const archive = archiver('zip', {
|
|
zlib: { level: 9 } // Compression level
|
|
});
|
|
|
|
// Set appropriate headers
|
|
res.attachment('ad-management-platform.zip');
|
|
res.setHeader('Content-Type', 'application/zip');
|
|
|
|
// Pipe archive data to the response
|
|
archive.pipe(res);
|
|
|
|
// Get the root directory (current working directory)
|
|
const rootDir = process.cwd();
|
|
|
|
// Add files and directories to include
|
|
const includeFiles = [
|
|
'client',
|
|
'server',
|
|
'shared',
|
|
'migrations',
|
|
'package.json',
|
|
'tsconfig.json',
|
|
'tailwind.config.ts',
|
|
'theme.json',
|
|
'postcss.config.js',
|
|
'vite.config.ts',
|
|
'drizzle.config.ts',
|
|
'Dockerfile',
|
|
'README.md'
|
|
];
|
|
|
|
// Exclude patterns (node_modules, .git, etc.)
|
|
const excludePatterns = [
|
|
'.git',
|
|
'node_modules',
|
|
'dist',
|
|
'.cache',
|
|
'.replit',
|
|
'.env'
|
|
];
|
|
|
|
// Helper function to check if path should be excluded
|
|
const shouldExclude = (filePath: string): boolean => {
|
|
return excludePatterns.some(pattern => filePath.includes(pattern));
|
|
};
|
|
|
|
// Add each included file/directory
|
|
includeFiles.forEach(filePath => {
|
|
const fullPath = path.join(rootDir, filePath);
|
|
|
|
if (fs.existsSync(fullPath)) {
|
|
const stats = fs.statSync(fullPath);
|
|
|
|
if (stats.isFile() && !shouldExclude(fullPath)) {
|
|
// Add individual file
|
|
archive.file(fullPath, { name: filePath });
|
|
debug(`Added file: ${filePath}`);
|
|
} else if (stats.isDirectory()) {
|
|
// Add directory recursively, with exclusions
|
|
archive.glob('**/*', {
|
|
cwd: fullPath,
|
|
ignore: excludePatterns,
|
|
dot: true
|
|
}, { prefix: filePath });
|
|
debug(`Added directory: ${filePath}`);
|
|
}
|
|
} else {
|
|
debug(`Path not found: ${fullPath}`);
|
|
}
|
|
});
|
|
|
|
// Handle errors
|
|
archive.on('error', (err) => {
|
|
debug(`Error creating archive: ${err.message}`);
|
|
res.status(500).send({ error: 'Failed to create download archive' });
|
|
});
|
|
|
|
// Finalize archive
|
|
archive.finalize();
|
|
});
|
|
} |