chore: publish clean community baseline
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
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 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 wizardProtoUpload = window.wizardProtoUpload;
|
||||
var wizardDescriptorSetUpload = window.wizardDescriptorSetUpload;
|
||||
var wizardSoapWsdlUpload = window.wizardSoapWsdlUpload;
|
||||
var wizardSoapXsdUpload = window.wizardSoapXsdUpload;
|
||||
var wizardTestResponsePreview = window.wizardTestResponsePreview;
|
||||
var wizardProtocolCapabilities = window.wizardProtocolCapabilities;
|
||||
var wizardSecrets = window.wizardSecrets;
|
||||
var wizardAuthProfiles = window.wizardAuthProfiles;
|
||||
var selectedUpstreamId = window.selectedUpstreamId;
|
||||
var editingUpstreamId = window.editingUpstreamId;
|
||||
var protoParsed = window.protoParsed;
|
||||
var selectedRpcMethod = window.selectedRpcMethod;
|
||||
|
||||
async function initWizardPage() {
|
||||
renderSidebarBrand('create');
|
||||
document.querySelector('.btn-continue').addEventListener('click', function() {
|
||||
if (currentStep < TOTAL_STEPS) {
|
||||
goToStep(currentStep + 1);
|
||||
} else {
|
||||
saveOperation();
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector('.btn-back').addEventListener('click', function() {
|
||||
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);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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: null,
|
||||
POST: { icon: 'info', text: { en: { title: 'POST selected — body encoding required.', body: 'In step 4 you will define the JSON schema for the body payload. Crank will automatically serialize MCP tool arguments into the format you specify.' }, ru: { title: 'Выбран POST — требуется кодирование тела запроса.', body: 'На шаге 4 вы зададите JSON-схему для body payload. 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 body schema in step 4.' }, ru: { title: 'Выбран PUT — полная замена ресурса.', body: 'Request body должен содержать полное представление ресурса. Задайте body schema на шаге 4.' } } },
|
||||
PATCH: { icon: 'info', text: { en: { title: 'PATCH selected — partial update.', body: 'Only include the fields you want to modify in the body schema defined in step 4.' }, ru: { title: 'Выбран PATCH — частичное обновление.', body: 'В body schema на шаге 4 включайте только те поля, которые хотите изменить.' } } },
|
||||
};
|
||||
|
||||
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 = buildIconSvg(
|
||||
(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;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── GraphQL operation type picker (Step 4 GraphQL) ── */
|
||||
|
||||
function selectGqlType(btn) {
|
||||
document.querySelectorAll('.gql-type-card').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
// Update query editor placeholder if it's still the default
|
||||
var editor = document.getElementById('gql-query-editor');
|
||||
if (!editor) return;
|
||||
var type = btn.dataset.gqlType;
|
||||
var defaults = {
|
||||
query: 'query GetContact($id: ID!) {\n contact(id: $id) {\n id\n firstName\n lastName\n email\n company {\n id\n name\n }\n createdAt\n }\n}',
|
||||
mutation: 'mutation CreateContact(\n $firstName: String!\n $lastName: String!\n $email: String!\n $company: String\n) {\n createContact(input: {\n firstName: $firstName\n lastName: $lastName\n email: $email\n company: $company\n }) {\n id\n firstName\n lastName\n createdAt\n }\n}'
|
||||
};
|
||||
if (defaults[type]) editor.value = defaults[type];
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str).replace(/&/g,'&').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) || {};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user