Spaces:
Sleeping
Sleeping
anoderb
feat: implement chatbot service, active shift logic corrections, audit logs, and void transaction tool
48013ee | import dotenv from 'dotenv'; | |
| dotenv.config(); | |
| const SUPABASE_URL = (process.env.SUPABASE_URL || '').replace(/\/$/, ''); | |
| const SUPABASE_SERVICE_KEY = process.env.SUPABASE_SERVICE_KEY || ''; | |
| interface ParsedImage { | |
| fileBytes: Buffer; | |
| mimeType: string; | |
| } | |
| export const parseBase64Image = (base64Str: string): ParsedImage => { | |
| if (base64Str.includes(',')) { | |
| const [header, data] = base64Str.split(',', 2); | |
| let mimeType = 'image/jpeg'; | |
| if (header.includes('data:')) { | |
| const parts = header.split(';'); | |
| if (parts.length > 0) { | |
| mimeType = parts[0].replace('data:', ''); | |
| } | |
| let fileBytes: Buffer; | |
| if (header.includes('base64')) { | |
| fileBytes = Buffer.from(data, 'base64'); | |
| } else { | |
| const decodedStr = decodeURIComponent(data); | |
| fileBytes = Buffer.from(decodedStr, 'utf-8'); | |
| } | |
| return { fileBytes, mimeType }; | |
| } | |
| const fileBytes = Buffer.from(data, 'base64'); | |
| return { fileBytes, mimeType }; | |
| } else { | |
| const fileBytes = Buffer.from(base64Str, 'base64'); | |
| return { fileBytes, mimeType: 'image/jpeg' }; | |
| } | |
| }; | |
| export const uploadBase64ToSupabase = async ( | |
| bucket: string, | |
| filePath: string, | |
| base64Str: string | |
| ): Promise<string | null> => { | |
| try { | |
| const { fileBytes, mimeType } = parseBase64Image(base64Str); | |
| const uploadUrl = `${SUPABASE_URL}/storage/v1/object/${bucket}/${filePath}`; | |
| const response = await fetch(uploadUrl, { | |
| method: 'POST', | |
| headers: { | |
| 'Authorization': `Bearer ${SUPABASE_SERVICE_KEY}`, | |
| 'Content-Type': mimeType, | |
| 'x-upsert': 'true' | |
| }, | |
| body: fileBytes | |
| }); | |
| if (response.ok) { | |
| return `${SUPABASE_URL}/storage/v1/object/public/${bucket}/${filePath}`; | |
| } else { | |
| const errorText = await response.text(); | |
| console.error(`Supabase upload failed: ${response.status} - ${errorText}`); | |
| return null; | |
| } | |
| } catch (error) { | |
| console.error('Error uploading to Supabase:', error); | |
| return null; | |
| } | |
| }; | |
| export const uploadBufferToSupabase = async ( | |
| bucket: string, | |
| filePath: string, | |
| fileBuffer: Buffer, | |
| mimeType: string | |
| ): Promise<string | null> => { | |
| try { | |
| const uploadUrl = `${SUPABASE_URL}/storage/v1/object/${bucket}/${filePath}`; | |
| const response = await fetch(uploadUrl, { | |
| method: 'POST', | |
| headers: { | |
| 'Authorization': `Bearer ${SUPABASE_SERVICE_KEY}`, | |
| 'Content-Type': mimeType, | |
| 'x-upsert': 'true' | |
| }, | |
| body: fileBuffer | |
| }); | |
| if (response.ok) { | |
| return `${SUPABASE_URL}/storage/v1/object/public/${bucket}/${filePath}`; | |
| } else { | |
| const errorText = await response.text(); | |
| console.error(`Supabase upload failed: ${response.status} - ${errorText}`); | |
| return null; | |
| } | |
| } catch (error) { | |
| console.error('Error uploading buffer to Supabase:', error); | |
| return null; | |
| } | |
| }; | |
| export const deleteFromSupabase = async ( | |
| bucket: string, | |
| filePath: string | |
| ): Promise<boolean> => { | |
| try { | |
| const deleteUrl = `${SUPABASE_URL}/storage/v1/object/${bucket}/${filePath}`; | |
| const response = await fetch(deleteUrl, { | |
| method: 'DELETE', | |
| headers: { | |
| 'Authorization': `Bearer ${SUPABASE_SERVICE_KEY}` | |
| } | |
| }); | |
| return response.ok; | |
| } catch (error) { | |
| console.error('Error deleting from Supabase:', error); | |
| return false; | |
| } | |
| }; | |