function tKey(key) { return typeof t === 'function' ? t(key) : key; } function tfKey(key, vars) { return typeof tf === 'function' ? tf(key, vars) : key; } var TOTAL_STEPS = window.CrankWizardShell.TOTAL_STEPS; var loadProtocolCapabilities = window.CrankWizardState.loadProtocolCapabilities; var loadEditionCapabilities = window.CrankWizardState.loadEditionCapabilities; var currentProtocolCapabilities = window.CrankWizardState.currentProtocolCapabilities; var loadStep = window.CrankWizardShell.loadStep; var goToStep = window.CrankWizardShell.goToStep; var _doGoToStep = window.CrankWizardShell.doGoToStep; var loadWizardPanels = window.CrankWizardShell.loadWizardPanels; var bindProtocolCards = window.CrankWizardShell.bindProtocolCards; var applyEditionProtocolVisibility = window.CrankWizardShell.applyEditionProtocolVisibility; var step3PanelId = window.CrankWizardShell.step3PanelId; var saveOperation = window.CrankWizardLive.saveOperation; var loadOperationForEdit = window.CrankWizardLive.loadOperationForEdit; var showPendingImportGuidance = window.CrankWizardLive.showPendingImportGuidance; var bindWizardLiveActions = window.CrankWizardLive.bindWizardLiveActions; var updateWizardProtocolVisibility = window.CrankWizardLive.updateWizardProtocolVisibility; var currentStep = window.currentStep; var wizardProtocol = window.wizardProtocol; var wizardMode = window.wizardMode; var wizardEditId = window.wizardEditId; var wizardWorkspaceId = window.wizardWorkspaceId; var wizardCurrentOperation = window.wizardCurrentOperation; var wizardCurrentVersion = window.wizardCurrentVersion; var wizardTestResponsePreview = window.wizardTestResponsePreview; var wizardProtocolCapabilities = window.wizardProtocolCapabilities; var wizardSecrets = window.wizardSecrets; var wizardAuthProfiles = window.wizardAuthProfiles; var selectedUpstreamId = window.selectedUpstreamId; var editingUpstreamId = window.editingUpstreamId; async function initWizardPage() { renderSidebarBrand('create'); document.querySelector('.btn-continue').addEventListener('click', function() { currentStep = window.currentStep || 1; if (currentStep < TOTAL_STEPS) { goToStep(currentStep + 1); } else { saveOperation(); } }); document.querySelector('.btn-back').addEventListener('click', function() { currentStep = window.currentStep || 1; if (!this.disabled && currentStep > 1) goToStep(currentStep - 1); }); document.querySelectorAll('.step-item').forEach(function(item, i) { item.addEventListener('click', function() { goToStep(i + 1); }); }); var backToCatalog = document.getElementById('back-to-catalog'); if (backToCatalog) { backToCatalog.addEventListener('click', function() { window.location.href = (window.CrankRoutes && window.CrankRoutes.home) || '/'; }); } var closeBtn = document.querySelector('.progress-close'); if (closeBtn) { closeBtn.addEventListener('click', function() { window.location.href = (window.CrankRoutes && window.CrankRoutes.home) || '/'; }); } var saveDraftBtn = document.querySelector('.btn-save-draft'); if (saveDraftBtn) { saveDraftBtn.addEventListener('click', function() { saveOperation(true); }); } await (window.whenWorkspacesReady ? window.whenWorkspacesReady() : Promise.resolve()); var workspace = window.getCurrentWorkspace ? window.getCurrentWorkspace() : null; wizardWorkspaceId = workspace ? workspace.id : null; window.wizardWorkspaceId = wizardWorkspaceId; var editionCapabilities = await loadEditionCapabilities(); await loadProtocolCapabilities(); await loadWizardPanels([1, 2, 3, 4, 5]); if (window.CrankOverlay && typeof window.CrankOverlay.render === 'function') { await window.CrankOverlay.render(document, { workspace: workspace, capabilities: editionCapabilities, locale: localStorage.getItem('crank_lang') || 'en', }); } await loadWizardAuthResources(); bindProtocolCards(); applyEditionProtocolVisibility(editionCapabilities); bindWizardLiveActions(); updateUpstreamAuthUi(); renderEditionCapabilityHints(editionCapabilities); window.addEventListener('focus', refreshWizardAuthResourcesOnFocus); var quickSecretModal = document.getElementById('quick-secret-modal'); var quickSecretClose = document.getElementById('quick-secret-close-btn'); var quickSecretCancel = document.getElementById('quick-secret-cancel-btn'); var quickSecretSubmit = document.getElementById('quick-secret-submit-btn'); if (quickSecretClose) quickSecretClose.addEventListener('click', closeQuickSecretModal); if (quickSecretCancel) quickSecretCancel.addEventListener('click', closeQuickSecretModal); if (quickSecretModal) { quickSecretModal.addEventListener('click', function(event) { if (event.target === quickSecretModal) closeQuickSecretModal(); }); } if (quickSecretSubmit) { quickSecretSubmit.addEventListener('click', async function() { var button = quickSecretSubmit; var original = button.textContent; button.disabled = true; button.textContent = tKey('wizard.step2.quick_secret_submit'); try { await submitQuickSecret(); } catch (error) { if (window.CrankUi) { window.CrankUi.error( error.message || tKey('wizard.toast.quick_secret_error_title'), tKey('wizard.toast.quick_secret_error_title') ); } } finally { button.disabled = false; button.textContent = original; } }); } var params = new URLSearchParams(window.location.search); if (params.get('mode') === 'edit' && params.get('operationId')) { wizardMode = 'edit'; wizardEditId = params.get('operationId'); window.wizardMode = wizardMode; window.wizardEditId = wizardEditId; document.title = 'Crank — ' + tKey('wizard.progress.edit'); await loadOperationForEdit(); showPendingImportGuidance(); } updateWizardProtocolVisibility(); _doGoToStep(1); } function renderEditionCapabilityHints(capabilities) { var securityNote = document.getElementById('wizard-security-level-note'); var securityText = securityNote ? securityNote.querySelector('.info-callout-text') : null; if (!securityText) return; var levels = capabilities && Array.isArray(capabilities.supported_security_levels) ? capabilities.supported_security_levels : ['standard']; securityNote.hidden = !(levels.length === 1 && levels[0] === 'standard'); if (!securityNote.hidden) { securityText.textContent = tKey('wizard.step5.community_security_note'); } } window.renderEditionCapabilityHints = renderEditionCapabilityHints; if (window.CrankDiagnostics && typeof window.CrankDiagnostics.bootstrap === 'function') { window.CrankDiagnostics.bootstrap('wizard', initWizardPage); } else { document.addEventListener('DOMContentLoaded', function() { void initWizardPage(); }); } /* ── HTTP method picker (Step 4 REST) ── */ var METHOD_CALLOUTS = { GET: null, DELETE: { icon: 'info', text: { en: { title: 'DELETE selected — confirmation is required.', body: 'Crank will expose this MCP tool as a two-step action: the first call returns a confirmation token, the second call with the same arguments and token executes the API request.' }, ru: { title: 'Выбран DELETE — требуется подтверждение.', body: 'Crank откроет этот MCP инструмент как двухшаговое действие: первый вызов вернет токен подтверждения, второй вызов с теми же аргументами и токеном выполнит запрос к API.' } } }, POST: { icon: 'info', text: { en: { title: 'POST selected — request body is required.', body: 'In step 4 you will define the JSON schema for the request body. Crank will convert MCP tool parameters into the selected format.' }, ru: { title: 'Выбран POST — требуется тело запроса.', body: 'На шаге 4 вы зададите JSON-схему тела запроса. Crank преобразует параметры MCP инструмента в выбранный формат.' } } }, PUT: { icon: 'info', text: { en: { title: 'PUT selected — full-resource replacement.', body: 'The request body must contain a complete resource representation. Define the request schema in step 4.' }, ru: { title: 'Выбран PUT — полная замена ресурса.', body: 'Тело запроса должно содержать полное представление ресурса. Задайте схему запроса на шаге 4.' } } }, PATCH: { icon: 'info', text: { en: { title: 'PATCH selected — partial update.', body: 'Only include the fields you want to modify in the request schema defined in step 4.' }, ru: { title: 'Выбран PATCH — частичное обновление.', body: 'В схему запроса на шаге 4 включайте только те поля, которые хотите изменить.' } } }, }; function buildWizardIconSvg(href, width, height) { var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.setAttribute('width', String(width)); svg.setAttribute('height', String(height)); var use = document.createElementNS('http://www.w3.org/2000/svg', 'use'); use.setAttribute('href', href); svg.appendChild(use); return svg; } function renderSidebarBrand(mode) { var sidebarBrand = document.querySelector('.step-sidebar-brand'); if (!sidebarBrand) return; var language = localStorage.getItem('crank_lang') || 'en'; var parts; if (mode === 'edit') { parts = language === 'ru' ? { prefix: 'Редактировать ', suffix: 'операцию' } : { prefix: 'Edit ', suffix: 'operation' }; } else { parts = language === 'ru' ? { prefix: 'Создать ', suffix: 'операцию' } : { prefix: 'Create ', suffix: 'operation' }; } sidebarBrand.dataset.wizardBrand = mode; sidebarBrand.textContent = parts.prefix; var accent = document.createElement('span'); accent.textContent = parts.suffix; sidebarBrand.appendChild(accent); } window.addEventListener('crank:langchange', function() { renderSidebarBrand(wizardMode === 'edit' ? 'edit' : 'create'); }); function selectMethod(btn) { document.querySelectorAll('.method-card').forEach(function(b) { b.classList.remove('active'); }); btn.classList.add('active'); var method = btn.dataset.method; var callout = document.getElementById('method-callout-rest'); if (!callout) return; var info = METHOD_CALLOUTS[method]; if (info) { var lang = localStorage.getItem('crank_lang') || 'en'; var text = typeof info.text === 'string' ? info.text : (info.text[lang] || info.text.en); callout.innerHTML = ''; var icon = buildWizardIconSvg( (window.APP_BASE || '') + 'icons/general/info-circle.svg#icon', 15, 15 ); icon.style.flexShrink = '0'; icon.style.color = 'var(--accent)'; callout.appendChild(icon); var content = document.createElement('span'); var title = document.createElement('strong'); title.textContent = text.title; content.appendChild(title); content.appendChild(document.createTextNode(' ' + text.body)); callout.appendChild(content); callout.hidden = false; } else { callout.replaceChildren(); callout.hidden = true; } } function escapeHtml(str) { return String(str).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } // Close dropdown on outside click document.addEventListener('click', function() { if (dropdownOpen) closeUpstreamDropdown(); }); function textValue(id) { var element = document.getElementById(id); return element ? element.value.trim() : ''; } function setValue(id, value) { var element = document.getElementById(id); if (element) element.value = value || ''; } function parseStructuredText(text) { if (!text.trim()) return {}; try { return JSON.parse(text); } catch (_error) { if (!window.jsyaml) throw new Error(tKey('wizard.error.parser_unavailable')); return window.jsyaml.load(text) || {}; } }