/* fn-archive.js — создание функции из архива (независимый модуль) */ function onLangChangeArchive() { var lang = document.getElementById('ca-lang').value; var t = LANG_TEMPLATES[lang]; if (t) { document.getElementById('ca-entry').value = t.entrypoint; } } function openCreateArchive() { document.getElementById('ca-lang').value = 'python'; onLangChangeArchive(); document.getElementById('ca-name').value = ''; document.getElementById('ca-route').value = ''; document.getElementById('ca-methods').value = 'GET'; document.getElementById('ca-timeout').value = '60'; document.getElementById('ca-schedule-enabled').checked = false; document.getElementById('ca-cron').value = ''; toggleScheduleFields('ca'); var fileInput = document.getElementById('ca-archive-file'); if (fileInput) fileInput.value = ''; var aiRes = document.getElementById('ca-ai-result'); if (aiRes) { aiRes.style.display = 'none'; aiRes.textContent = ''; } hideModalError('ca-error'); document.getElementById('create-archive-modal').classList.add('open'); document.getElementById('ca-name').focus(); } function closeCreateArchive() { document.getElementById('create-archive-modal').classList.remove('open'); } async function submitCreateArchive() { const btn = document.getElementById('ca-submit'); btn.disabled = true; const progress = startTimedStatus('Создаём функцию...', 'Создание функции...', explainDelay); try { const name = document.getElementById('ca-name').value.trim(); if (!name) throw new Error('name is required'); const lang = document.getElementById('ca-lang').value.trim(); if (!lang) throw new Error('language is required'); const archiveFile = document.getElementById('ca-archive-file').files[0]; if (!archiveFile) throw new Error('выберите .zip архив'); if (!archiveFile.name.toLowerCase().endsWith('.zip')) throw new Error('файл должен быть .zip архивом, не .' + archiveFile.name.split('.').pop()); var fd = new FormData(); fd.append('name', name); fd.append('language', lang); fd.append('entrypoint', document.getElementById('ca-entry').value.trim()); fd.append('route', document.getElementById('ca-route').value.trim()); fd.append('methods', document.getElementById('ca-methods').value.trim()); fd.append('timeout', String(parseTimeout(document.getElementById('ca-timeout').value))); fd.append('archive', archiveFile); var resp = await fetch(API_BASE + '/functions', { method: 'POST', headers: authHeaders(), body: fd }); if (!resp.ok) { var e = await resp.json().catch(() => ({})); throw new Error(e.error || resp.statusText); } try { await syncScheduleForFunction(name, 'ca'); } catch (scheduleErr) { try { await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name), 'DELETE'); } catch (rollbackErr) { scheduleErr.message += '; rollback failed: ' + rollbackErr.message; } throw scheduleErr; } closeCreateArchive(); progress.stop('Функция создана: ' + name, 'ok'); await reloadAll(); } catch (e) { progress.stop('Ошибка создания: ' + e.message, 'err'); showModalError('ca-error', 'Ошибка: ' + e.message); } finally { btn.disabled = false; } }