/** * rbxlImporterApi.js — клиент для rbxl-importer (Flask API на VM 130). * * Endpoints: * POST /api-rbxl/import/rbxl/analyze — анализ .rbxl, возвращает report + preview_hash * POST /api-rbxl/import/rbxl/create — скачать ассеты, создать проект * GET /api-rbxl/health — healthcheck */ import { RBXL_addres } from './API.js'; // На dev (localhost) backend ещё не интегрирован с user-service для JWT-парсинга. // Используем dev override: явно передаём user_id. В prod NPM или user-service // сами выставят X-User-Id из JWT. const IS_DEV = typeof window !== 'undefined' && (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'); function authHeaders() { const token = localStorage.getItem('Authorization') || ''; const headers = { 'Authorization': token }; if (IS_DEV) { // Достаём user_id из JWT для dev (без validation — backend на dev доверяет). try { const payload = JSON.parse(atob(token.split('.')[1] || '')); if (payload && payload.id != null) headers['X-Auth-Override'] = String(payload.id); } catch (e) { // если JWT не парсится — забыли залогиниться, всё равно отправим что-то } } return headers; } /** * Анализ .rbxl. Принимает File (из ) или Blob. * Возвращает { preview_hash, report }. */ export async function analyzeRbxl(file) { const fd = new FormData(); fd.append('file', file, file.name || 'upload.rbxl'); const resp = await fetch(`${RBXL_addres}/import/rbxl/analyze`, { method: 'POST', headers: authHeaders(), body: fd, }); if (!resp.ok) { const text = await resp.text(); throw new Error(`analyze failed (${resp.status}): ${text}`); } return resp.json(); } /** * Создаёт проект из preview_hash. Возвращает { project_id, redirect, assets_downloaded, assets_failed }. */ export async function createRbxlProject(previewHash, title, opts = {}) { const resp = await fetch(`${RBXL_addres}/import/rbxl/create`, { method: 'POST', headers: { ...authHeaders(), 'Content-Type': 'application/json' }, body: JSON.stringify({ preview_hash: previewHash, title: title || '', // 'disabled' (default) — импортнуть выключенными, читать можно // 'enabled' — попытаться запустить (может вешать карту) // 'skip' — не импортировать совсем scripts_mode: opts.scriptsMode || 'disabled', }), }); if (!resp.ok) { const text = await resp.text(); throw new Error(`create failed (${resp.status}): ${text}`); } return resp.json(); }