initial commit

This commit is contained in:
Kar k1
2025-08-30 18:18:57 +05:30
commit 7219108342
270 changed files with 70221 additions and 0 deletions

152
lib/file-vault.ts Normal file
View File

@@ -0,0 +1,152 @@
/**
* File upload service using external API
* Replaces MINIO with custom file upload API
*/
import { env } from './env'
// File upload result from the API
export interface FileUploadResponse {
success: boolean
url: string
filename: string
}
// File upload result for internal use
export interface UploadResult {
url: string
filename: string
originalName: string
size: number
type: string
uploadedAt: string
}
/**
* Upload file to external API
*/
export async function uploadFile(
buffer: Buffer,
filename: string,
contentType: string,
userId?: string
): Promise<UploadResult> {
console.log('📤 Starting file upload:', { filename, contentType, bufferSize: buffer.length })
try {
// Create FormData for multipart upload
const formData = new FormData()
const blob = new Blob([buffer], { type: contentType })
formData.append('file', blob, filename)
// Prepare headers
const headers: Record<string, string> = {
'x-user-data': userId || 'default-user',
Authorization: `Bearer ${env.FILE_UPLOAD_TOKEN || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3QgVXNlciIsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'}`,
}
console.log('📤 Uploading to external API:', {
url: process.env.UPLOAD_API_URL,
filename,
size: buffer.length,
userId: userId || 'default-user',
})
// Make the upload request
const response = await fetch(process.env.UPLOAD_API_URL, {
method: 'POST',
headers,
body: formData,
})
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Upload failed: ${response.status} ${response.statusText} - ${errorText}`)
}
const result: FileUploadResponse = await response.json()
if (!result.success) {
throw new Error('Upload API returned success: false')
}
console.log('✅ File uploaded successfully:', result)
return {
url: result.url,
filename: result.filename,
originalName: filename,
size: buffer.length,
type: contentType,
uploadedAt: new Date().toISOString(),
}
} catch (error) {
console.error('❌ Error uploading file:', error)
throw error
}
}
/**
* Generate unique filename with timestamp and random string
*/
export function generateUniqueFilename(originalName: string): string {
const timestamp = Date.now()
const randomString = Math.random().toString(36).substring(2)
const extension = originalName.split('.').pop()
return `${timestamp}-${randomString}.${extension}`
}
/**
* Validate file type
*/
export function validateFileType(mimetype: string, allowedTypes: string[]): boolean {
return allowedTypes.includes(mimetype)
}
/**
* Validate file size (in bytes)
*/
export function validateFileSize(size: number, maxSize: number): boolean {
return size <= maxSize
}
/**
* Get file URL (files are already publicly accessible)
*/
export async function getFileUrl(filePath: string): Promise<string> {
// Files from the upload API are already publicly accessible
// If filePath is already a full URL, return it as is
if (filePath.startsWith('http')) {
return filePath
}
// Otherwise, construct the URL using the delivery base URL
return `${process.env.DELIVERY_BASE_URL}/${filePath}`
}
/**
* Delete file (not supported by the current API)
*/
export async function deleteFile(filePath: string): Promise<void> {
console.warn('⚠️ File deletion not supported by current upload API:', filePath)
// The external API doesn't provide a delete endpoint
// This is a no-op for now
}
/**
* Move file to permanent storage (not needed with new API)
*/
export async function moveToPermStorage(tempPath: string, permanentPath: string): Promise<void> {
console.log(' Move to permanent storage not needed with new API')
// The new API directly uploads to permanent storage
// This is a no-op
}
/**
* Initialize bucket (not needed with new API)
*/
export async function initializeBucket(): Promise<void> {
console.log(' Bucket initialization not needed with new API')
// The new API handles storage internally
// This is a no-op
}