726 lines
25 KiB
JavaScript
726 lines
25 KiB
JavaScript
(function() {
|
||
var REQUEST_TARGETS = ['path', 'query', 'headers', 'body'];
|
||
var SCALAR_TYPES = ['string', 'number', 'integer', 'boolean', 'null'];
|
||
var suspendSync = false;
|
||
|
||
function field(id) {
|
||
return document.getElementById(id);
|
||
}
|
||
|
||
function readText(id) {
|
||
var element = field(id);
|
||
return element ? element.value.trim() : '';
|
||
}
|
||
|
||
function writeText(id, value) {
|
||
var element = field(id);
|
||
if (element) element.value = value || '';
|
||
}
|
||
|
||
function parseText(id) {
|
||
if (typeof parseStructuredText === 'function') {
|
||
return parseStructuredText(readText(id));
|
||
}
|
||
return JSON.parse(readText(id));
|
||
}
|
||
|
||
function dumpYaml(object) {
|
||
return window.jsyaml
|
||
? window.jsyaml.dump(object, { lineWidth: -1, noRefs: true })
|
||
: JSON.stringify(object, null, 2);
|
||
}
|
||
|
||
function safeJson(id) {
|
||
try {
|
||
return parseText(id);
|
||
} catch (_error) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function scalarType(value) {
|
||
if (value === null) return 'null';
|
||
if (Array.isArray(value)) return 'array';
|
||
var typeName = typeof value;
|
||
if (typeName === 'number') return Number.isInteger(value) ? 'integer' : 'number';
|
||
if (typeName === 'boolean') return 'boolean';
|
||
if (typeName === 'object') return 'object';
|
||
return 'string';
|
||
}
|
||
|
||
function inferJsonSchema(value) {
|
||
var typeName = scalarType(value);
|
||
if (typeName === 'object') {
|
||
var properties = {};
|
||
var required = [];
|
||
Object.keys(value || {}).forEach(function(name) {
|
||
properties[name] = inferJsonSchema(value[name]);
|
||
if (value[name] !== null && value[name] !== undefined) required.push(name);
|
||
});
|
||
var schema = {
|
||
type: 'object',
|
||
properties: properties,
|
||
additionalProperties: false,
|
||
};
|
||
if (required.length) schema.required = required;
|
||
return schema;
|
||
}
|
||
if (typeName === 'array') {
|
||
return {
|
||
type: 'array',
|
||
items: value.length ? inferJsonSchema(value[0]) : { type: 'string' },
|
||
};
|
||
}
|
||
return { type: typeName };
|
||
}
|
||
|
||
function collectSchemaFields(schema, prefix) {
|
||
var result = [];
|
||
var node = schema || {};
|
||
if (node.type === 'object' && node.properties) {
|
||
Object.keys(node.properties).forEach(function(name) {
|
||
var child = node.properties[name] || {};
|
||
var path = prefix ? prefix + '.' + name : name;
|
||
if (child.type === 'object' && child.properties) {
|
||
result = result.concat(collectSchemaFields(child, path));
|
||
} else {
|
||
result.push({
|
||
name: path,
|
||
required: Array.isArray(node.required) && node.required.indexOf(name) >= 0,
|
||
});
|
||
}
|
||
});
|
||
}
|
||
return result;
|
||
}
|
||
|
||
function requiredSchemaFields(schema) {
|
||
return collectSchemaFields(schema, '').filter(function(item) {
|
||
return item.required;
|
||
}).map(function(item) {
|
||
return item.name;
|
||
});
|
||
}
|
||
|
||
function collectJsonLeaves(value, prefix) {
|
||
var result = [];
|
||
if (Array.isArray(value)) {
|
||
if (!value.length) {
|
||
if (prefix) result.push({ name: prefix, required: true, array: true });
|
||
return result;
|
||
}
|
||
var samplePath = prefix ? prefix + '[0]' : '[0]';
|
||
return collectJsonLeaves(value[0], samplePath).map(function(item) {
|
||
item.array = true;
|
||
return item;
|
||
});
|
||
}
|
||
if (value && typeof value === 'object') {
|
||
Object.keys(value).forEach(function(name) {
|
||
var path = prefix ? prefix + '.' + name : name;
|
||
var child = value[name];
|
||
if (child && typeof child === 'object') {
|
||
result = result.concat(collectJsonLeaves(child, path));
|
||
} else {
|
||
result.push({ name: path, required: child !== null && child !== undefined });
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
if (prefix) result.push({ name: prefix, required: true });
|
||
return result;
|
||
}
|
||
|
||
function pathParams() {
|
||
var path = readText('endpoint-path') || '';
|
||
var params = [];
|
||
path.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, function(_match, name) {
|
||
params.push(name);
|
||
return _match;
|
||
});
|
||
path.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, function(_match, name) {
|
||
params.push(name);
|
||
return _match;
|
||
});
|
||
return Array.from(new Set(params));
|
||
}
|
||
|
||
function currentMethod() {
|
||
var active = document.querySelector('.method-card.active');
|
||
return active ? active.dataset.method || 'GET' : 'GET';
|
||
}
|
||
|
||
function defaultTargetKind() {
|
||
var method = currentMethod().toUpperCase();
|
||
return method === 'GET' || method === 'DELETE' ? 'query' : 'body';
|
||
}
|
||
|
||
function splitRequestTarget(target) {
|
||
var value = String(target || '').replace(/^\$\.request\./, '').replace(/^request\./, '');
|
||
var parts = value.split('.');
|
||
var kind = parts.shift() || defaultTargetKind();
|
||
if (REQUEST_TARGETS.indexOf(kind) < 0) kind = defaultTargetKind();
|
||
return { kind: kind, name: parts.join('.') };
|
||
}
|
||
|
||
function sourceToField(source) {
|
||
return String(source || '')
|
||
.replace(/^\$\.mcp\.?/, '')
|
||
.replace(/^\$\.input\.?/, '');
|
||
}
|
||
|
||
function responseSourceToPath(source) {
|
||
return String(source || '')
|
||
.replace(/^\$\.response\.body\.?/, '')
|
||
.replace(/^\$\.response\.data\.?/, '');
|
||
}
|
||
|
||
function outputTargetToField(target) {
|
||
return String(target || '').replace(/^\$\.output\.?/, '');
|
||
}
|
||
|
||
function mappingEntrySource(entry) {
|
||
return entry && typeof entry === 'object' && !Array.isArray(entry)
|
||
? entry.source
|
||
: entry;
|
||
}
|
||
|
||
function mappingEntryDefault(entry) {
|
||
return entry && typeof entry === 'object' && !Array.isArray(entry) && Object.prototype.hasOwnProperty.call(entry, 'default_value')
|
||
? entry.default_value
|
||
: undefined;
|
||
}
|
||
|
||
function mappingEntryTransform(entry) {
|
||
if (!entry || typeof entry !== 'object' || Array.isArray(entry) || entry.transform === undefined || entry.transform === null) {
|
||
return '';
|
||
}
|
||
var value = typeof entry.transform === 'object' ? entry.transform.kind : entry.transform;
|
||
value = String(value || '').trim();
|
||
return transformKinds().indexOf(value) >= 0 ? value : '';
|
||
}
|
||
|
||
function defaultValueToText(value) {
|
||
if (value === undefined) return '';
|
||
if (typeof value === 'string') return value;
|
||
return JSON.stringify(value);
|
||
}
|
||
|
||
function parseDefaultValue(text) {
|
||
var value = String(text || '').trim();
|
||
if (!value) return undefined;
|
||
if (/^(true|false|null)$/i.test(value) || /^-?(0|[1-9][0-9]*)(\.[0-9]+)?$/.test(value) || /^[\[{]/.test(value)) {
|
||
try {
|
||
return JSON.parse(value);
|
||
} catch (_error) {
|
||
return value;
|
||
}
|
||
}
|
||
return value;
|
||
}
|
||
|
||
function transformKinds() {
|
||
return [
|
||
'to_string',
|
||
'to_number',
|
||
'to_boolean',
|
||
'join',
|
||
'split',
|
||
'wrap_array',
|
||
'unwrap_singleton',
|
||
];
|
||
}
|
||
|
||
function requestRowsFromEditor() {
|
||
var parsed = safeJson('tool-input-mapping') || {};
|
||
return Object.keys(parsed).map(function(target) {
|
||
var entry = parsed[target];
|
||
var source = mappingEntrySource(entry);
|
||
var split = splitRequestTarget(target);
|
||
return {
|
||
input: sourceToField(source) || split.name,
|
||
target: split.kind,
|
||
apiName: split.name || sourceToField(source),
|
||
defaultValue: defaultValueToText(mappingEntryDefault(entry)),
|
||
transform: mappingEntryTransform(entry),
|
||
};
|
||
});
|
||
}
|
||
|
||
function responseRowsFromEditor() {
|
||
var parsed = safeJson('tool-output-mapping') || {};
|
||
return Object.keys(parsed).map(function(outputField) {
|
||
var source = mappingEntrySource(parsed[outputField]);
|
||
return {
|
||
output: outputField,
|
||
responsePath: responseSourceToPath(source) || outputField,
|
||
};
|
||
});
|
||
}
|
||
|
||
function suggestedRequestRows() {
|
||
var rows = [];
|
||
pathParams().forEach(function(name) {
|
||
rows.push({ input: name, target: 'path', apiName: name });
|
||
});
|
||
|
||
var sample = safeJson('wizard-input-sample');
|
||
var fields = [];
|
||
if (sample && typeof sample === 'object') {
|
||
fields = collectJsonLeaves(sample, '');
|
||
}
|
||
if (!fields.length) {
|
||
fields = collectSchemaFields(safeJson('tool-input-schema'), '');
|
||
}
|
||
|
||
var pathSet = new Set(rows.map(function(row) { return row.input; }));
|
||
fields.forEach(function(item) {
|
||
if (pathSet.has(item.name)) return;
|
||
rows.push({
|
||
input: item.name,
|
||
target: defaultTargetKind(),
|
||
apiName: item.name,
|
||
});
|
||
});
|
||
return rows;
|
||
}
|
||
|
||
function suggestedResponseRows() {
|
||
var sample = safeJson('wizard-output-sample');
|
||
var fields = sample && typeof sample === 'object'
|
||
? collectJsonLeaves(sample, '')
|
||
: collectSchemaFields(safeJson('tool-output-schema'), '');
|
||
return fields.map(function(item) {
|
||
return {
|
||
output: outputNameFromPath(item.name),
|
||
responsePath: item.name,
|
||
};
|
||
});
|
||
}
|
||
|
||
function outputNameFromPath(path) {
|
||
return String(path || 'value')
|
||
.replace(/^\[0\]\.?/, 'item_')
|
||
.replace(/\[([0-9]+)\]/g, '_$1')
|
||
.replace(/[^A-Za-z0-9_]+/g, '_')
|
||
.replace(/^_+|_+$/g, '')
|
||
|| 'value';
|
||
}
|
||
|
||
function joinJsonPath(root, relativePath) {
|
||
var path = String(relativePath || '').trim();
|
||
if (!path) return root;
|
||
return path.charAt(0) === '[' ? root + path : root + '.' + path;
|
||
}
|
||
|
||
function makeOption(value, label, selected) {
|
||
var option = document.createElement('option');
|
||
option.value = value;
|
||
option.textContent = label;
|
||
option.selected = selected;
|
||
return option;
|
||
}
|
||
|
||
function makeInput(value, className, placeholder) {
|
||
var input = document.createElement('input');
|
||
input.className = className || 'form-input input-mono';
|
||
input.value = value === undefined || value === null ? '' : String(value);
|
||
input.placeholder = placeholder || '';
|
||
input.autocomplete = 'off';
|
||
input.spellcheck = false;
|
||
input.addEventListener('input', syncVisualMappingsToYaml);
|
||
input.addEventListener('change', syncVisualMappingsToYaml);
|
||
return input;
|
||
}
|
||
|
||
function makeRemoveButton(row) {
|
||
var button = document.createElement('button');
|
||
button.type = 'button';
|
||
button.className = 'row-btn row-btn-delete mapping-row-remove';
|
||
button.title = 'Удалить строку';
|
||
button.textContent = '×';
|
||
button.addEventListener('click', function() {
|
||
row.remove();
|
||
syncVisualMappingsToYaml();
|
||
});
|
||
return button;
|
||
}
|
||
|
||
function renderRequestRows(rows) {
|
||
var root = field('wizard-request-mapping-rows');
|
||
if (!root) return;
|
||
root.replaceChildren();
|
||
if (!rows.length) rows = suggestedRequestRows();
|
||
rows.forEach(function(row) {
|
||
root.appendChild(createRequestRow(row));
|
||
});
|
||
if (!suspendSync) syncVisualMappingsToYaml();
|
||
}
|
||
|
||
function createRequestRow(row) {
|
||
var item = document.createElement('div');
|
||
item.className = 'mapping-row request-mapping-row';
|
||
item.dataset.mappingRow = 'request';
|
||
|
||
var input = makeInput(row.input, 'form-input input-mono mapping-source', 'base');
|
||
input.dataset.role = 'input';
|
||
item.appendChild(input);
|
||
|
||
var select = document.createElement('select');
|
||
select.className = 'form-select mapping-target';
|
||
select.dataset.role = 'target';
|
||
[
|
||
['path', 'Path'],
|
||
['query', 'Query'],
|
||
['headers', 'Header'],
|
||
['body', 'Body'],
|
||
].forEach(function(entry) {
|
||
select.appendChild(makeOption(entry[0], entry[1], entry[0] === row.target));
|
||
});
|
||
select.addEventListener('change', syncVisualMappingsToYaml);
|
||
item.appendChild(select);
|
||
|
||
var apiName = makeInput(row.apiName || row.input, 'form-input input-mono mapping-api-name', 'base');
|
||
apiName.dataset.role = 'apiName';
|
||
item.appendChild(apiName);
|
||
|
||
var defaultValue = makeInput(row.defaultValue, 'form-input input-mono mapping-default-value', 'по умолчанию');
|
||
defaultValue.dataset.role = 'defaultValue';
|
||
defaultValue.title = 'Значение по умолчанию, если поле не передано';
|
||
item.appendChild(defaultValue);
|
||
|
||
var transform = document.createElement('select');
|
||
transform.className = 'form-select mapping-transform';
|
||
transform.dataset.role = 'transform';
|
||
transform.appendChild(makeOption('', 'Без преобразования', !row.transform));
|
||
transformKinds().forEach(function(kind) {
|
||
transform.appendChild(makeOption(kind, kind, kind === row.transform));
|
||
});
|
||
transform.title = 'Простое преобразование перед отправкой в API';
|
||
transform.addEventListener('change', syncVisualMappingsToYaml);
|
||
item.appendChild(transform);
|
||
|
||
item.appendChild(makeRemoveButton(item));
|
||
return item;
|
||
}
|
||
|
||
function renderResponseRows(rows) {
|
||
var root = field('wizard-response-mapping-rows');
|
||
if (!root) return;
|
||
root.replaceChildren();
|
||
if (!rows.length) rows = suggestedResponseRows();
|
||
rows.forEach(function(row) {
|
||
root.appendChild(createResponseRow(row));
|
||
});
|
||
if (!suspendSync) syncVisualMappingsToYaml();
|
||
}
|
||
|
||
function createResponseRow(row) {
|
||
var item = document.createElement('div');
|
||
item.className = 'mapping-row response-mapping-row';
|
||
item.dataset.mappingRow = 'response';
|
||
|
||
var responsePath = makeInput(row.responsePath, 'form-input input-mono mapping-response-path', 'rates.EUR');
|
||
responsePath.dataset.role = 'responsePath';
|
||
item.appendChild(responsePath);
|
||
|
||
var output = makeInput(row.output, 'form-input input-mono mapping-output-field', 'rate');
|
||
output.dataset.role = 'output';
|
||
item.appendChild(output);
|
||
item.appendChild(makeRemoveButton(item));
|
||
return item;
|
||
}
|
||
|
||
function valueIn(row, role) {
|
||
var input = row.querySelector('[data-role="' + role + '"]');
|
||
return input ? input.value.trim() : '';
|
||
}
|
||
|
||
function syncVisualMappingsToYaml() {
|
||
var requestRows = document.querySelectorAll('[data-mapping-row="request"]');
|
||
if (requestRows.length) {
|
||
var requestMapping = {};
|
||
requestRows.forEach(function(row) {
|
||
var input = valueIn(row, 'input');
|
||
var target = valueIn(row, 'target');
|
||
var apiName = valueIn(row, 'apiName') || input;
|
||
var defaultText = valueIn(row, 'defaultValue');
|
||
var transform = valueIn(row, 'transform');
|
||
if (!input || !target || !apiName) return;
|
||
if (defaultText || transform) {
|
||
var entry = { source: '$.input.' + input };
|
||
if (defaultText) entry.default_value = parseDefaultValue(defaultText);
|
||
if (transform) entry.transform = transform;
|
||
requestMapping[target + '.' + apiName] = entry;
|
||
return;
|
||
}
|
||
requestMapping[target + '.' + apiName] = '$.input.' + input;
|
||
});
|
||
writeText('tool-input-mapping', dumpYaml(requestMapping));
|
||
}
|
||
|
||
var responseRows = document.querySelectorAll('[data-mapping-row="response"]');
|
||
if (responseRows.length) {
|
||
var responseMapping = {};
|
||
responseRows.forEach(function(row) {
|
||
var responsePath = valueIn(row, 'responsePath');
|
||
var output = valueIn(row, 'output') || outputNameFromPath(responsePath);
|
||
if (!responsePath || !output) return;
|
||
responseMapping[output] = joinJsonPath('$.response.body', responsePath);
|
||
});
|
||
writeText('tool-output-mapping', dumpYaml(responseMapping));
|
||
}
|
||
renderMappingWarnings();
|
||
}
|
||
|
||
function currentRequestMappedInputs() {
|
||
return Array.from(document.querySelectorAll('[data-mapping-row="request"]')).map(function(row) {
|
||
return valueIn(row, 'input');
|
||
}).filter(Boolean);
|
||
}
|
||
|
||
function currentResponseMappedOutputs() {
|
||
return Array.from(document.querySelectorAll('[data-mapping-row="response"]')).map(function(row) {
|
||
return valueIn(row, 'output');
|
||
}).filter(Boolean);
|
||
}
|
||
|
||
function jsonParseWarning(id, label) {
|
||
var raw = readText(id);
|
||
if (!raw) return null;
|
||
try {
|
||
parseText(id);
|
||
return null;
|
||
} catch (error) {
|
||
return label + ': JSON не разобран. ' + error.message;
|
||
}
|
||
}
|
||
|
||
function buildMappingWarnings() {
|
||
var warnings = [];
|
||
var inputJsonWarning = jsonParseWarning('wizard-input-sample', 'Пример входных данных');
|
||
var outputJsonWarning = jsonParseWarning('wizard-output-sample', 'Пример ответа');
|
||
if (inputJsonWarning) warnings.push(inputJsonWarning);
|
||
if (outputJsonWarning) warnings.push(outputJsonWarning);
|
||
|
||
var required = requiredSchemaFields(safeJson('tool-input-schema'));
|
||
var mapped = new Set(currentRequestMappedInputs());
|
||
var missing = required.filter(function(name) { return !mapped.has(name); });
|
||
if (missing.length) {
|
||
warnings.push('Обязательные поля входной схемы не отправляются в API: ' + missing.join(', ') + '.');
|
||
}
|
||
|
||
var outputRows = currentResponseMappedOutputs();
|
||
if (!outputRows.length) {
|
||
warnings.push('Ответ инструмента пустой. Выберите хотя бы одно поле из ответа API.');
|
||
}
|
||
if (outputRows.length > 12) {
|
||
warnings.push('В ответ инструмента выбрано много полей: ' + outputRows.length + '. Лучше вернуть только данные, нужные агенту.');
|
||
}
|
||
var hasArrayIndex = Array.from(document.querySelectorAll('[data-mapping-row="response"]')).some(function(row) {
|
||
return /\[[0-9]+\]/.test(valueIn(row, 'responsePath'));
|
||
});
|
||
if (hasArrayIndex) {
|
||
warnings.push('В ответе выбрано поле из одного элемента массива. Если агенту нужен весь список, верните массив целиком через расширенный YAML-маппинг.');
|
||
}
|
||
return warnings;
|
||
}
|
||
|
||
function renderMappingWarnings() {
|
||
var root = field('wizard-mapping-warnings');
|
||
if (!root) return;
|
||
var warnings = buildMappingWarnings();
|
||
root.replaceChildren();
|
||
root.hidden = warnings.length === 0;
|
||
warnings.forEach(function(message) {
|
||
var item = document.createElement('div');
|
||
item.className = 'mapping-warning';
|
||
var title = document.createElement('strong');
|
||
title.textContent = 'Проверьте маппинг. ';
|
||
item.appendChild(title);
|
||
item.appendChild(document.createTextNode(message));
|
||
root.appendChild(item);
|
||
});
|
||
}
|
||
|
||
function renderResponseTree() {
|
||
var root = field('wizard-response-json-tree');
|
||
if (!root) return;
|
||
root.replaceChildren();
|
||
var sample = safeJson('wizard-output-sample');
|
||
var leaves = sample && typeof sample === 'object' ? collectJsonLeaves(sample, '') : [];
|
||
if (!leaves.length) {
|
||
var empty = document.createElement('div');
|
||
empty.className = 'form-hint';
|
||
empty.textContent = 'Добавьте пример ответа JSON, чтобы выбрать поля кликом.';
|
||
root.appendChild(empty);
|
||
return;
|
||
}
|
||
leaves.forEach(function(leaf) {
|
||
var button = document.createElement('button');
|
||
button.type = 'button';
|
||
button.className = 'json-tree-node';
|
||
button.textContent = leaf.name;
|
||
button.addEventListener('click', function() {
|
||
var output = outputNameFromPath(leaf.name);
|
||
field('wizard-response-mapping-rows').appendChild(createResponseRow({
|
||
responsePath: leaf.name,
|
||
output: output,
|
||
}));
|
||
syncVisualMappingsToYaml();
|
||
});
|
||
root.appendChild(button);
|
||
});
|
||
}
|
||
|
||
function formatSamplesAndInferSchemas() {
|
||
var input = parseText('wizard-input-sample');
|
||
var output = parseText('wizard-output-sample');
|
||
writeText('wizard-input-sample', JSON.stringify(input, null, 2));
|
||
writeText('wizard-test-input', JSON.stringify(input, null, 2));
|
||
writeText('wizard-output-sample', JSON.stringify(output, null, 2));
|
||
writeText('tool-input-schema', JSON.stringify(inferJsonSchema(input), null, 2));
|
||
writeText('tool-output-schema', JSON.stringify(inferJsonSchema(output), null, 2));
|
||
renderRequestRows(suggestedRequestRows());
|
||
renderResponseRows(suggestedResponseRows());
|
||
renderResponseTree();
|
||
if (window.CrankWizardLive && typeof window.CrankWizardLive.renderAgentFacingPreview === 'function') {
|
||
window.CrankWizardLive.renderAgentFacingPreview();
|
||
}
|
||
}
|
||
|
||
function loadJsonFile(inputId, targetTextareaId, afterLoad) {
|
||
var input = field(inputId);
|
||
if (!input) return;
|
||
var file = input.files && input.files[0];
|
||
if (!file) return;
|
||
var reader = new FileReader();
|
||
reader.onload = function(event) {
|
||
try {
|
||
var parsed = JSON.parse(event.target.result || '{}');
|
||
writeText(targetTextareaId, JSON.stringify(parsed, null, 2));
|
||
if (afterLoad) afterLoad();
|
||
} catch (error) {
|
||
if (window.CrankUi) {
|
||
window.CrankUi.error(error.message, 'JSON не прочитан');
|
||
}
|
||
} finally {
|
||
input.value = '';
|
||
}
|
||
};
|
||
reader.readAsText(file);
|
||
}
|
||
|
||
function bindFileButton(buttonId, inputId) {
|
||
var button = field(buttonId);
|
||
var input = field(inputId);
|
||
if (!button || !input || button.dataset.mappingBound === 'true') return;
|
||
button.dataset.mappingBound = 'true';
|
||
button.addEventListener('click', function(event) {
|
||
event.preventDefault();
|
||
input.click();
|
||
});
|
||
}
|
||
|
||
function bindOnce(id, eventName, handler) {
|
||
var element = field(id);
|
||
if (!element || element.dataset.mappingBound === 'true') return;
|
||
element.dataset.mappingBound = 'true';
|
||
element.addEventListener(eventName, handler);
|
||
}
|
||
|
||
function initializeMappingBuilder() {
|
||
bindOnce('wizard-add-request-mapping-row', 'click', function(event) {
|
||
event.preventDefault();
|
||
field('wizard-request-mapping-rows').appendChild(createRequestRow({
|
||
input: '',
|
||
target: defaultTargetKind(),
|
||
apiName: '',
|
||
}));
|
||
});
|
||
bindOnce('wizard-add-response-mapping-row', 'click', function(event) {
|
||
event.preventDefault();
|
||
field('wizard-response-mapping-rows').appendChild(createResponseRow({
|
||
responsePath: '',
|
||
output: '',
|
||
}));
|
||
});
|
||
bindOnce('wizard-auto-request-mapping', 'click', function(event) {
|
||
event.preventDefault();
|
||
renderRequestRows(suggestedRequestRows());
|
||
});
|
||
bindOnce('wizard-auto-response-mapping', 'click', function(event) {
|
||
event.preventDefault();
|
||
renderResponseRows(suggestedResponseRows());
|
||
renderResponseTree();
|
||
});
|
||
bindOnce('wizard-sync-request-mapping', 'click', function(event) {
|
||
event.preventDefault();
|
||
syncVisualMappingsToYaml();
|
||
});
|
||
bindOnce('wizard-sync-response-mapping', 'click', function(event) {
|
||
event.preventDefault();
|
||
syncVisualMappingsToYaml();
|
||
});
|
||
bindOnce('wizard-format-samples', 'click', function(event) {
|
||
event.preventDefault();
|
||
formatSamplesAndInferSchemas();
|
||
});
|
||
|
||
bindFileButton('wizard-load-input-sample-file', 'wizard-input-sample-file');
|
||
bindFileButton('wizard-load-output-sample-file', 'wizard-output-sample-file');
|
||
bindOnce('wizard-input-sample-file', 'change', function() {
|
||
loadJsonFile('wizard-input-sample-file', 'wizard-input-sample', function() {
|
||
renderRequestRows(suggestedRequestRows());
|
||
});
|
||
});
|
||
bindOnce('wizard-output-sample-file', 'change', function() {
|
||
loadJsonFile('wizard-output-sample-file', 'wizard-output-sample', function() {
|
||
renderResponseRows(suggestedResponseRows());
|
||
renderResponseTree();
|
||
});
|
||
});
|
||
|
||
['wizard-input-sample', 'tool-input-schema', 'endpoint-path'].forEach(function(id) {
|
||
var element = field(id);
|
||
if (!element || element.dataset.mappingRefreshBound === 'true') return;
|
||
element.dataset.mappingRefreshBound = 'true';
|
||
element.addEventListener('change', function() {
|
||
renderRequestRows(requestRowsFromEditor());
|
||
renderMappingWarnings();
|
||
});
|
||
});
|
||
['wizard-output-sample', 'tool-output-schema'].forEach(function(id) {
|
||
var element = field(id);
|
||
if (!element || element.dataset.mappingRefreshBound === 'true') return;
|
||
element.dataset.mappingRefreshBound = 'true';
|
||
element.addEventListener('change', function() {
|
||
renderResponseRows(responseRowsFromEditor());
|
||
renderResponseTree();
|
||
renderMappingWarnings();
|
||
});
|
||
});
|
||
|
||
renderRequestRows(requestRowsFromEditor());
|
||
renderResponseRows(responseRowsFromEditor());
|
||
renderResponseTree();
|
||
renderMappingWarnings();
|
||
}
|
||
|
||
window.CrankWizardMapping = {
|
||
initialize: initializeMappingBuilder,
|
||
sync: syncVisualMappingsToYaml,
|
||
renderFromEditors: function() {
|
||
suspendSync = true;
|
||
renderRequestRows(requestRowsFromEditor());
|
||
renderResponseRows(responseRowsFromEditor());
|
||
suspendSync = false;
|
||
syncVisualMappingsToYaml();
|
||
renderResponseTree();
|
||
renderMappingWarnings();
|
||
},
|
||
formatSamplesAndInferSchemas: formatSamplesAndInferSchemas,
|
||
renderWarnings: renderMappingWarnings,
|
||
};
|
||
})();
|