mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 21:43:07 +00:00
- Update n8n-version tests: 'v' prefix now supported in version strings
- Update n8n-validation tests: empty settings now return minimal defaults
{ executionOrder: 'v1' } instead of {} to avoid API rejection (Issue #431)
Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Romuald Członkowski <romualdczlonkowski@MacBook-Pro-Romuald.local>
Co-authored-by: Claude <noreply@anthropic.com>
151 lines
5.3 KiB
JavaScript
151 lines
5.3 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.VERSION_THRESHOLDS = void 0;
|
|
exports.parseVersion = parseVersion;
|
|
exports.compareVersions = compareVersions;
|
|
exports.versionAtLeast = versionAtLeast;
|
|
exports.getSupportedSettingsProperties = getSupportedSettingsProperties;
|
|
exports.fetchN8nVersion = fetchN8nVersion;
|
|
exports.clearVersionCache = clearVersionCache;
|
|
exports.getCachedVersion = getCachedVersion;
|
|
exports.setCachedVersion = setCachedVersion;
|
|
exports.cleanSettingsForVersion = cleanSettingsForVersion;
|
|
const axios_1 = __importDefault(require("axios"));
|
|
const logger_1 = require("../utils/logger");
|
|
const VERSION_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
const versionCache = new Map();
|
|
const SETTINGS_BY_VERSION = {
|
|
core: [
|
|
'saveExecutionProgress',
|
|
'saveManualExecutions',
|
|
'saveDataErrorExecution',
|
|
'saveDataSuccessExecution',
|
|
'executionTimeout',
|
|
'errorWorkflow',
|
|
'timezone',
|
|
],
|
|
v1_37_0: [
|
|
'executionOrder',
|
|
],
|
|
v1_119_0: [
|
|
'callerPolicy',
|
|
'callerIds',
|
|
'timeSavedPerExecution',
|
|
'availableInMCP',
|
|
],
|
|
};
|
|
function parseVersion(versionString) {
|
|
const match = versionString.match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
if (!match) {
|
|
return null;
|
|
}
|
|
return {
|
|
version: versionString,
|
|
major: parseInt(match[1], 10),
|
|
minor: parseInt(match[2], 10),
|
|
patch: parseInt(match[3], 10),
|
|
};
|
|
}
|
|
function compareVersions(a, b) {
|
|
if (a.major !== b.major)
|
|
return a.major - b.major;
|
|
if (a.minor !== b.minor)
|
|
return a.minor - b.minor;
|
|
return a.patch - b.patch;
|
|
}
|
|
function versionAtLeast(version, major, minor, patch = 0) {
|
|
const target = { version: '', major, minor, patch };
|
|
return compareVersions(version, target) >= 0;
|
|
}
|
|
function getSupportedSettingsProperties(version) {
|
|
const supported = new Set(SETTINGS_BY_VERSION.core);
|
|
if (versionAtLeast(version, 1, 37, 0)) {
|
|
SETTINGS_BY_VERSION.v1_37_0.forEach(prop => supported.add(prop));
|
|
}
|
|
if (versionAtLeast(version, 1, 119, 0)) {
|
|
SETTINGS_BY_VERSION.v1_119_0.forEach(prop => supported.add(prop));
|
|
}
|
|
return supported;
|
|
}
|
|
async function fetchN8nVersion(baseUrl) {
|
|
const cached = versionCache.get(baseUrl);
|
|
if (cached && Date.now() - cached.fetchedAt < VERSION_CACHE_TTL_MS) {
|
|
logger_1.logger.debug(`Using cached n8n version for ${baseUrl}: ${cached.info.version}`);
|
|
return cached.info;
|
|
}
|
|
try {
|
|
const cleanBaseUrl = baseUrl.replace(/\/api\/v\d+\/?$/, '').replace(/\/$/, '');
|
|
const settingsUrl = `${cleanBaseUrl}/rest/settings`;
|
|
logger_1.logger.debug(`Fetching n8n version from ${settingsUrl}`);
|
|
const response = await axios_1.default.get(settingsUrl, {
|
|
timeout: 5000,
|
|
validateStatus: (status) => status < 500,
|
|
});
|
|
if (response.status === 200 && response.data) {
|
|
const settings = response.data.data;
|
|
if (!settings) {
|
|
logger_1.logger.warn('No data in settings response');
|
|
return null;
|
|
}
|
|
const versionString = typeof settings.n8nVersion === 'string'
|
|
? settings.n8nVersion
|
|
: typeof settings.versionCli === 'string'
|
|
? settings.versionCli
|
|
: null;
|
|
if (versionString) {
|
|
const versionInfo = parseVersion(versionString);
|
|
if (versionInfo) {
|
|
versionCache.set(baseUrl, { info: versionInfo, fetchedAt: Date.now() });
|
|
logger_1.logger.debug(`Detected n8n version: ${versionInfo.version}`);
|
|
return versionInfo;
|
|
}
|
|
}
|
|
}
|
|
logger_1.logger.warn(`Could not determine n8n version from ${settingsUrl}`);
|
|
return null;
|
|
}
|
|
catch (error) {
|
|
logger_1.logger.warn(`Failed to fetch n8n version: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
return null;
|
|
}
|
|
}
|
|
function clearVersionCache() {
|
|
versionCache.clear();
|
|
}
|
|
function getCachedVersion(baseUrl) {
|
|
const cached = versionCache.get(baseUrl);
|
|
if (cached && Date.now() - cached.fetchedAt < VERSION_CACHE_TTL_MS) {
|
|
return cached.info;
|
|
}
|
|
return null;
|
|
}
|
|
function setCachedVersion(baseUrl, version) {
|
|
versionCache.set(baseUrl, { info: version, fetchedAt: Date.now() });
|
|
}
|
|
function cleanSettingsForVersion(settings, version) {
|
|
if (!settings || typeof settings !== 'object') {
|
|
return {};
|
|
}
|
|
if (!version) {
|
|
return settings;
|
|
}
|
|
const supportedProperties = getSupportedSettingsProperties(version);
|
|
const cleaned = {};
|
|
for (const [key, value] of Object.entries(settings)) {
|
|
if (supportedProperties.has(key)) {
|
|
cleaned[key] = value;
|
|
}
|
|
else {
|
|
logger_1.logger.debug(`Filtered out unsupported settings property: ${key} (n8n ${version.version})`);
|
|
}
|
|
}
|
|
return cleaned;
|
|
}
|
|
exports.VERSION_THRESHOLDS = {
|
|
EXECUTION_ORDER: { major: 1, minor: 37, patch: 0 },
|
|
CALLER_POLICY: { major: 1, minor: 119, patch: 0 },
|
|
};
|
|
//# sourceMappingURL=n8n-version.js.map
|