/*** @ Base: https://play.google.com/store/apps/details?id=xyz.thingapps.banana @ Author: Shannz @ Note: 이미지 편집 및 이미지 생성을 간편하게. ***/ import axios from 'axios'; import fs from 'fs'; import crypto from 'crypto'; const 설정 = { 베이스_엔드: "https://dydkrpmnafsnivjxmipj.supabase.co", 비밀키: "sb_publishable_W_1Ofv9769iYEEn9dfyAHQ_OhuCER6g", 경로: { 회원가입: "/auth/v1/signup", 새로_고침: "/auth/v1/token", 편집: "/functions/v1/edit-image", 생성: "/functions/v1/generate-image" }, 헤더: { "User-Agent": "Dart/3.9 (dart:io)", "Accept-Encoding": "gzip", "x-supabase-client-platform": "android", "x-client-info": "supabase-flutter/2.10.3", "x-supabase-client-platform-version": "15 A15.0.2.0.VGWIDXM", "Content-Type": "application/json; charset=utf-8", "x-supabase-api-version": "2024-01-01" } }; let 세션 = { 액세스_토큰: null, 리프레시_토큰: null, 만료일: 0 }; const 클라우드_업로드 = async (buffer, ext = '.png') => { try { const 파일_이름 = `flux-${crypto.randomUUID()}${ext}`; const 콘텐츠_유형 = 'image/png'; const 파일_크기 = buffer.length; const { data } = await axios.post('https://api.cloudsky.biz.id/get-upload-url', { fileKey: 파일_이름, contentType: 콘텐츠_유형, fileSize: 파일_크기 }); await axios.put(data.uploadUrl, buffer, { headers: { 'Content-Type': 콘텐츠_유형, 'Content-Length': 파일_크기, 'x-amz-server-side-encryption': 'AES256' }, maxBodyLength: Infinity, maxContentLength: Infinity }); return `https://api.cloudsky.biz.id/file?key=${encodeURIComponent(파일_이름)}`; } catch (에러) { console.error(`[Upload Cloud Error]: ${에러.message}`); return null; } }; const Base64로_변환 = async (입력_데이터) => { try { let 완충기; if (Buffer.isBuffer(입력_데이터)) { 완충기 = 입력_데이터; } else if (typeof 입력_데이터 === 'string' && 입력_데이터.startsWith('http')) { const 응답 = await axios.get(입력_데이터, { responseType: 'arraybuffer' }); 완충기 = Buffer.from(응답.data); } else if (fs.existsSync(입력_데이터)) { 완충기 = fs.readFileSync(입력_데이터); } else { return null; } return 완충기.toString('base64'); } catch (e) { return null; } }; export const fluxAi = { signup: async () => { try { const 유효_탑재량 = { data: {}, gotrue_meta_security: { captcha_token: null } }; const 헤더 = { ...설정.헤더, "apikey": 설정.비밀키, "Authorization": `Bearer ${설정.비밀키}` }; const 응답 = await axios.post(설정.베이스_엔드 + 설정.경로.회원가입, 유효_탑재량, { headers: 헤더 }); if (응답.data?.access_token) { 세션.액세스_토큰 = 응답.data.access_token; 세션.리프레시_토큰 = 응답.data.refresh_token; return 세션.액세스_토큰; } return null; } catch (e) { console.error("Signup Error:", e.message); return null; } }, editImage: async (imageInput, prompt) => { try { if (!세션.액세스_토큰) await fluxAi.signup(); if (!세션.액세스_토큰) return { success: false, msg: 'Auth failed' }; const base64이미지 = await Base64로_변환(imageInput); if (!base64이미지) return { success: false, msg: 'Invalid input image' }; const 유효_탑재량 = { image: base64이미지, mimeType: "image/png", prompt: prompt, model: "auto", isFirstAttempt: true }; const 헤더 = { ...설정.헤더, "apikey": 설정.비밀키, "Authorization": `Bearer ${세션.액세스_토큰}` }; const 응답 = await axios.post(설정.베이스_엔드 + 설정.경로.편집, 유효_탑재량, { headers: 헤더 }); if (응답.data && 응답.data.image) { const 결과_버퍼 = Buffer.from(응답.data.image, 'base64'); const 클라우드_URL = await 클라우드_업로드(결과_버퍼); return { success: true, prompt: 응답.data.prompt, model: 응답.data.model, url: 클라우드_URL }; } return { success: false, msg: 'No image data returned' }; } catch (에러) { return { success: false, msg: 에러.message }; } }, generateImage: async (prompt, model = "fal-ai/flux-2") => { try { if (!세션.액세스_토큰) await fluxAi.signup(); if (!세션.액세스_토큰) return { success: false, msg: 'Auth failed' }; const 유효_탑재량 = { prompt: prompt, model: model }; const 헤더 = { ...설정.헤더, "apikey": 설정.비밀키, "Authorization": `Bearer ${세션.액세스_토큰}` }; const 응답 = await axios.post(설정.베이스_엔드 + 설정.경로.생성, 유효_탑재량, { headers: 헤더 }); if (응답.data && 응답.data.image) { const 결과_버퍼 = Buffer.from(응답.data.image, 'base64'); const 클라우드_URL = await 클라우드_업로드(결과_버퍼); return { success: true, prompt: 응답.data.prompt, model: 응답.data.model, url: 클라우드_URL }; } return { success: false, msg: 'No image data returned' }; } catch (에러) { return { success: false, msg: 에러.message }; } } };