mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-28 19:05:31 +02:00
86 lines
3 KiB
TypeScript
86 lines
3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import path from 'path';
|
|
import fs from 'fs/promises';
|
|
import fsSync from 'fs';
|
|
import { container } from '@/di/container';
|
|
import { IDataSourceDocsRepository } from '@/src/application/repositories/data-source-docs.repository.interface';
|
|
|
|
const UPLOADS_DIR = process.env.RAG_UPLOADS_DIR || '/uploads';
|
|
|
|
const dataSourceDocsRepository = container.resolve<IDataSourceDocsRepository>('dataSourceDocsRepository');
|
|
|
|
// PUT endpoint to handle file uploads
|
|
export async function PUT(request: NextRequest, props: { params: Promise<{ fileId: string }> }) {
|
|
const params = await props.params;
|
|
const fileId = params.fileId;
|
|
if (!fileId) {
|
|
return NextResponse.json({ error: 'Missing file ID' }, { status: 400 });
|
|
}
|
|
|
|
const filePath = path.join(UPLOADS_DIR, fileId);
|
|
|
|
try {
|
|
const data = await request.arrayBuffer();
|
|
await fs.writeFile(filePath, new Uint8Array(data));
|
|
|
|
return NextResponse.json({ success: true });
|
|
} catch (error) {
|
|
console.error('Error saving file:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to save file' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
// GET endpoint to handle file downloads
|
|
export async function GET(request: NextRequest, props: { params: Promise<{ fileId: string }> }) {
|
|
const params = await props.params;
|
|
const fileId = params.fileId;
|
|
if (!fileId) {
|
|
return NextResponse.json({ error: 'Missing file ID' }, { status: 400 });
|
|
}
|
|
|
|
// get mimetype from database
|
|
const doc = await dataSourceDocsRepository.fetch(fileId);
|
|
if (!doc) {
|
|
return NextResponse.json({ error: 'File not found' }, { status: 404 });
|
|
}
|
|
|
|
if (doc.data.type !== 'file_local') {
|
|
return NextResponse.json({ error: 'File is not local' }, { status: 400 });
|
|
}
|
|
const mimeType = 'application/octet-stream';
|
|
const fileName = doc.data.name;
|
|
|
|
try {
|
|
// strip uploads dir from path
|
|
const filePath = path.join(UPLOADS_DIR, doc.data.path.split('/api/uploads/')[1]);
|
|
|
|
// Check if file exists
|
|
await fs.access(filePath);
|
|
// Create a readable stream
|
|
const nodeStream = fsSync.createReadStream(filePath);
|
|
// Convert Node.js stream to Web stream
|
|
const webStream = new ReadableStream({
|
|
start(controller) {
|
|
nodeStream.on('data', (chunk) => controller.enqueue(chunk));
|
|
nodeStream.on('end', () => controller.close());
|
|
nodeStream.on('error', (err) => controller.error(err));
|
|
}
|
|
});
|
|
return new NextResponse(webStream, {
|
|
status: 200,
|
|
headers: {
|
|
'Content-Type': mimeType,
|
|
'Content-Disposition': `attachment; filename="${fileName}"`,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
console.error('Error reading file:', error);
|
|
return NextResponse.json(
|
|
{ error: 'File not found' },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
}
|