n8n-mcp 2.77.0 → 2.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/nodes.db +0 -0
- package/dist/database/node-repository.d.ts +3 -18
- package/dist/database/node-repository.d.ts.map +1 -1
- package/dist/database/node-repository.js +66 -79
- package/dist/database/node-repository.js.map +1 -1
- package/dist/mcp/handlers-n8n-manager.js +1 -1
- package/dist/mcp/handlers-n8n-manager.js.map +1 -1
- package/dist/mcp/param-aliases.d.ts +9 -0
- package/dist/mcp/param-aliases.d.ts.map +1 -0
- package/dist/mcp/param-aliases.js +84 -0
- package/dist/mcp/param-aliases.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +149 -61
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-docs/configuration/get-node.js +3 -3
- package/dist/mcp/tool-docs/configuration/get-node.js.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-executions.js +2 -2
- package/dist/mcp/tool-docs/workflow_management/n8n-executions.js.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js.map +1 -1
- package/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js +2 -2
- package/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js.map +1 -1
- package/dist/mcp/tools-n8n-manager.d.ts.map +1 -1
- package/dist/mcp/tools-n8n-manager.js +10 -8
- package/dist/mcp/tools-n8n-manager.js.map +1 -1
- package/dist/parsers/node-parser.d.ts +17 -0
- package/dist/parsers/node-parser.d.ts.map +1 -1
- package/dist/parsers/node-parser.js +59 -0
- package/dist/parsers/node-parser.js.map +1 -1
- package/dist/parsers/property-extractor.d.ts +5 -0
- package/dist/parsers/property-extractor.d.ts.map +1 -1
- package/dist/parsers/property-extractor.js +9 -0
- package/dist/parsers/property-extractor.js.map +1 -1
- package/dist/parsers/version-display-gate.d.ts +3 -0
- package/dist/parsers/version-display-gate.d.ts.map +1 -0
- package/dist/parsers/version-display-gate.js +60 -0
- package/dist/parsers/version-display-gate.js.map +1 -0
- package/dist/scripts/rebuild.js +40 -5
- package/dist/scripts/rebuild.js.map +1 -1
- package/dist/services/breaking-change-detector.d.ts +2 -0
- package/dist/services/breaking-change-detector.d.ts.map +1 -1
- package/dist/services/breaking-change-detector.js +50 -19
- package/dist/services/breaking-change-detector.js.map +1 -1
- package/dist/services/breaking-changes-registry.d.ts.map +1 -1
- package/dist/services/breaking-changes-registry.js +3 -8
- package/dist/services/breaking-changes-registry.js.map +1 -1
- package/dist/services/node-version-service.d.ts.map +1 -1
- package/dist/services/node-version-service.js +3 -2
- package/dist/services/node-version-service.js.map +1 -1
- package/dist/services/workflow-auto-fixer.d.ts.map +1 -1
- package/dist/services/workflow-auto-fixer.js +6 -0
- package/dist/services/workflow-auto-fixer.js.map +1 -1
- package/dist/telemetry/config-manager.d.ts.map +1 -1
- package/dist/telemetry/config-manager.js +44 -39
- package/dist/telemetry/config-manager.js.map +1 -1
- package/dist/telemetry/event-validator.d.ts +2 -2
- package/dist/telemetry/telemetry-cli.js +2 -2
- package/dist/templates/metadata-generator.d.ts +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveGetNodeAliases = resolveGetNodeAliases;
|
|
4
|
+
exports.suggestExecutionsAction = suggestExecutionsAction;
|
|
5
|
+
exports.withWorkflowIdAlias = withWorkflowIdAlias;
|
|
6
|
+
exports.hasText = hasText;
|
|
7
|
+
const logger_1 = require("../utils/logger");
|
|
8
|
+
const GET_NODE_MODE_ALIASES = {
|
|
9
|
+
essentials: { mode: 'info', detail: 'standard' },
|
|
10
|
+
minimal: { mode: 'info', detail: 'minimal' },
|
|
11
|
+
standard: { mode: 'info', detail: 'standard' },
|
|
12
|
+
full: { mode: 'info', detail: 'full' },
|
|
13
|
+
operations: { mode: 'info', detail: 'standard' },
|
|
14
|
+
properties: { mode: 'search_properties' },
|
|
15
|
+
search: { mode: 'search_properties' },
|
|
16
|
+
};
|
|
17
|
+
const GET_NODE_DETAIL_ALIASES = {
|
|
18
|
+
essentials: 'standard',
|
|
19
|
+
summary: 'minimal',
|
|
20
|
+
short: 'minimal',
|
|
21
|
+
};
|
|
22
|
+
function resolveGetNodeAliases(mode, detail) {
|
|
23
|
+
const aliased = [];
|
|
24
|
+
let resolvedMode = mode;
|
|
25
|
+
let resolvedDetail = detail;
|
|
26
|
+
if (typeof resolvedDetail === 'string') {
|
|
27
|
+
const detailAlias = GET_NODE_DETAIL_ALIASES[resolvedDetail.toLowerCase()];
|
|
28
|
+
if (detailAlias) {
|
|
29
|
+
aliased.push(`detail=${resolvedDetail}→${detailAlias}`);
|
|
30
|
+
resolvedDetail = detailAlias;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (typeof resolvedMode === 'string') {
|
|
34
|
+
const modeAlias = GET_NODE_MODE_ALIASES[resolvedMode.toLowerCase()];
|
|
35
|
+
if (modeAlias) {
|
|
36
|
+
const target = modeAlias.detail
|
|
37
|
+
? `mode=${modeAlias.mode}, detail=${modeAlias.detail}`
|
|
38
|
+
: `mode=${modeAlias.mode}`;
|
|
39
|
+
aliased.push(`mode=${resolvedMode}→${target}`);
|
|
40
|
+
resolvedMode = modeAlias.mode;
|
|
41
|
+
if (modeAlias.detail)
|
|
42
|
+
resolvedDetail = modeAlias.detail;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (aliased.length > 0) {
|
|
46
|
+
logger_1.logger.debug(`get_node: retired parameter vocabulary aliased (${aliased.join('; ')})`);
|
|
47
|
+
}
|
|
48
|
+
return { mode: resolvedMode, detail: resolvedDetail };
|
|
49
|
+
}
|
|
50
|
+
const EXECUTIONS_ACTION_HINTS = {
|
|
51
|
+
get_many: "Did you mean action='list'?",
|
|
52
|
+
getmany: "Did you mean action='list'?",
|
|
53
|
+
getall: "Did you mean action='list'?",
|
|
54
|
+
get_all: "Did you mean action='list'?",
|
|
55
|
+
list_executions: "Did you mean action='list'?",
|
|
56
|
+
listexecutions: "Did you mean action='list'?",
|
|
57
|
+
search: "Did you mean action='list'?",
|
|
58
|
+
get_execution: "Did you mean action='get'?",
|
|
59
|
+
getexecution: "Did you mean action='get'?",
|
|
60
|
+
retry: "Retrying an execution is not supported; re-run the workflow with n8n_test_workflow.",
|
|
61
|
+
list_runs: 'Evaluation test runs are managed by n8n_evaluations.',
|
|
62
|
+
get_run: 'Evaluation test runs are managed by n8n_evaluations.',
|
|
63
|
+
getrows: 'Data table rows are managed by n8n_manage_datatable.',
|
|
64
|
+
get_rows: 'Data table rows are managed by n8n_manage_datatable.',
|
|
65
|
+
};
|
|
66
|
+
function suggestExecutionsAction(action) {
|
|
67
|
+
return EXECUTIONS_ACTION_HINTS[action.toLowerCase()];
|
|
68
|
+
}
|
|
69
|
+
function withWorkflowIdAlias(args) {
|
|
70
|
+
const workflowIdMissing = args.workflowId === undefined || args.workflowId === null
|
|
71
|
+
|| (typeof args.workflowId === 'string' && args.workflowId.trim() === '');
|
|
72
|
+
if (!workflowIdMissing) {
|
|
73
|
+
return args;
|
|
74
|
+
}
|
|
75
|
+
const id = typeof args.id === 'number' ? String(args.id) : args.id;
|
|
76
|
+
if (typeof id !== 'string' || id.trim() === '') {
|
|
77
|
+
return typeof args.workflowId === 'string' ? { ...args, workflowId: undefined } : args;
|
|
78
|
+
}
|
|
79
|
+
return { ...args, workflowId: id };
|
|
80
|
+
}
|
|
81
|
+
function hasText(value) {
|
|
82
|
+
return typeof value === 'string' && value.trim() !== '';
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=param-aliases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"param-aliases.js","sourceRoot":"","sources":["../../src/mcp/param-aliases.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare class N8NDocumentationMCPServer {
|
|
|
8
8
|
private server;
|
|
9
9
|
private db;
|
|
10
10
|
private repository;
|
|
11
|
+
private breakingChangeDetector;
|
|
11
12
|
private templateService;
|
|
12
13
|
private initialized;
|
|
13
14
|
private cache;
|
|
@@ -43,6 +44,7 @@ export declare class N8NDocumentationMCPServer {
|
|
|
43
44
|
private validateToolParamsBasic;
|
|
44
45
|
private validateExtractedArgs;
|
|
45
46
|
private coerceStringifiedJsonParams;
|
|
47
|
+
private listExecutionsInsteadOfGet;
|
|
46
48
|
private listNodes;
|
|
47
49
|
private getNodeInfo;
|
|
48
50
|
private searchNodes;
|
|
@@ -66,6 +68,8 @@ export declare class N8NDocumentationMCPServer {
|
|
|
66
68
|
private getVersionSummary;
|
|
67
69
|
private versionMetadataUnavailable;
|
|
68
70
|
private getVersionHistory;
|
|
71
|
+
private analyzeVersionUpgrade;
|
|
72
|
+
private defaultTargetVersion;
|
|
69
73
|
private compareVersions;
|
|
70
74
|
private getBreakingChanges;
|
|
71
75
|
private getMigrations;
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -50,6 +50,7 @@ const tool_policy_1 = require("./tool-policy");
|
|
|
50
50
|
const tools_n8n_friendly_1 = require("./tools-n8n-friendly");
|
|
51
51
|
const workflow_examples_1 = require("./workflow-examples");
|
|
52
52
|
const logger_1 = require("../utils/logger");
|
|
53
|
+
const param_aliases_1 = require("./param-aliases");
|
|
53
54
|
const stdio_guard_1 = require("../utils/stdio-guard");
|
|
54
55
|
const redaction_1 = require("../utils/redaction");
|
|
55
56
|
const node_repository_1 = require("../database/node-repository");
|
|
@@ -76,6 +77,8 @@ const node_type_normalizer_1 = require("../utils/node-type-normalizer");
|
|
|
76
77
|
const typeversion_1 = require("../utils/typeversion");
|
|
77
78
|
const validation_schemas_1 = require("../utils/validation-schemas");
|
|
78
79
|
const protocol_version_1 = require("../utils/protocol-version");
|
|
80
|
+
const breaking_change_detector_1 = require("../services/breaking-change-detector");
|
|
81
|
+
const node_parser_1 = require("../parsers/node-parser");
|
|
79
82
|
const telemetry_1 = require("../telemetry");
|
|
80
83
|
const startup_checkpoints_1 = require("../telemetry/startup-checkpoints");
|
|
81
84
|
const STDIO_MAX_BUFFER_SIZE = Math.max(1024 * 1024, parseInt(process.env.N8N_MCP_STDIO_MAX_BUFFER_SIZE || '', 10) || 64 * 1024 * 1024);
|
|
@@ -86,6 +89,7 @@ class N8NDocumentationMCPServer {
|
|
|
86
89
|
constructor(instanceContext, earlyLogger, options) {
|
|
87
90
|
this.db = null;
|
|
88
91
|
this.repository = null;
|
|
92
|
+
this.breakingChangeDetector = null;
|
|
89
93
|
this.templateService = null;
|
|
90
94
|
this.cache = new simple_cache_1.SimpleCache();
|
|
91
95
|
this.clientInfo = null;
|
|
@@ -399,8 +403,13 @@ class N8NDocumentationMCPServer {
|
|
|
399
403
|
const cloned = JSON.parse(JSON.stringify(original));
|
|
400
404
|
const remaining = [...(0, tool_policy_1.getValidOperations)(toolName)].filter(v => !ops.has(v));
|
|
401
405
|
const param = cloned.inputSchema?.properties?.[paramName];
|
|
406
|
+
let defaultRemoved = false;
|
|
402
407
|
if (param?.enum) {
|
|
403
408
|
param.enum = param.enum.filter(v => !ops.has(v.toLowerCase()));
|
|
409
|
+
if (typeof param.default === 'string' && ops.has(param.default.toLowerCase())) {
|
|
410
|
+
delete param.default;
|
|
411
|
+
defaultRemoved = true;
|
|
412
|
+
}
|
|
404
413
|
if (param.enum.length === 0) {
|
|
405
414
|
logger_1.logger.warn(`DISABLED_TOOL_OPERATIONS: all operations for '${toolName}' are disabled ` +
|
|
406
415
|
`but the tool still appears in ListTools. ` +
|
|
@@ -408,11 +417,13 @@ class N8NDocumentationMCPServer {
|
|
|
408
417
|
}
|
|
409
418
|
if (param.description) {
|
|
410
419
|
const disabledList = [...ops].join(', ');
|
|
411
|
-
param.description = `${param.description} (disabled by server policy: ${disabledList}
|
|
420
|
+
param.description = `${param.description} (disabled by server policy: ${disabledList}`
|
|
421
|
+
+ `${defaultRemoved ? '; no default, pass a value' : ''})`;
|
|
412
422
|
}
|
|
413
423
|
}
|
|
414
424
|
const disabledList = [...ops].join(', ');
|
|
415
|
-
cloned.description = `${cloned.description}\n\n> Operations disabled by server policy: ${disabledList}
|
|
425
|
+
cloned.description = `${cloned.description}\n\n> Operations disabled by server policy: ${disabledList}`
|
|
426
|
+
+ (defaultRemoved ? `. The default for ${paramName} was one of them, so ${paramName} must be passed explicitly.` : '');
|
|
416
427
|
const destructive = tools_n8n_manager_1.DESTRUCTIVE_TOOL_OPERATIONS[toolName];
|
|
417
428
|
if (destructive && cloned.annotations) {
|
|
418
429
|
const stillDestructive = remaining.some(v => destructive.has(String(v).toLowerCase()));
|
|
@@ -857,9 +868,18 @@ class N8NDocumentationMCPServer {
|
|
|
857
868
|
validationResult = validation_schemas_1.ToolValidation.validateWorkflowId(args);
|
|
858
869
|
break;
|
|
859
870
|
case 'n8n_executions':
|
|
860
|
-
validationResult =
|
|
871
|
+
validationResult = { valid: true, errors: [] };
|
|
872
|
+
break;
|
|
873
|
+
case 'n8n_test_workflow':
|
|
874
|
+
validationResult = (0, param_aliases_1.hasText)(args.workflowId)
|
|
861
875
|
? { valid: true, errors: [] }
|
|
862
|
-
: {
|
|
876
|
+
: {
|
|
877
|
+
valid: false,
|
|
878
|
+
errors: [{
|
|
879
|
+
field: 'workflowId',
|
|
880
|
+
message: 'workflowId is required: the ID of the workflow to run ("id" is accepted as an alias)'
|
|
881
|
+
}]
|
|
882
|
+
};
|
|
863
883
|
break;
|
|
864
884
|
case 'n8n_evaluations': {
|
|
865
885
|
const evalErrors = [];
|
|
@@ -1083,6 +1103,19 @@ class N8NDocumentationMCPServer {
|
|
|
1083
1103
|
}
|
|
1084
1104
|
return coerced;
|
|
1085
1105
|
}
|
|
1106
|
+
async listExecutionsInsteadOfGet(args) {
|
|
1107
|
+
if ((0, tool_policy_1.isOperationDisabled)('n8n_executions', 'list')) {
|
|
1108
|
+
throw new Error('id is required for action=get');
|
|
1109
|
+
}
|
|
1110
|
+
const result = await n8nHandlers.handleListExecutions(args, this.instanceContext);
|
|
1111
|
+
if (!result.success)
|
|
1112
|
+
return result;
|
|
1113
|
+
const scope = (0, param_aliases_1.hasText)(args.workflowId) ? `executions of workflow ${args.workflowId}` : 'recent executions';
|
|
1114
|
+
return {
|
|
1115
|
+
...result,
|
|
1116
|
+
message: `action=get was called without an execution id, so ${scope} were listed instead. Pass id to get one execution.`
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1086
1119
|
async executeTool(name, args) {
|
|
1087
1120
|
args = args || {};
|
|
1088
1121
|
const disabledTools = this.getDisabledTools();
|
|
@@ -1120,19 +1153,21 @@ class N8NDocumentationMCPServer {
|
|
|
1120
1153
|
includeOperations: args.includeOperations,
|
|
1121
1154
|
source: args.source
|
|
1122
1155
|
});
|
|
1123
|
-
case 'get_node':
|
|
1156
|
+
case 'get_node': {
|
|
1124
1157
|
this.validateToolParams(name, args, ['nodeType']);
|
|
1125
|
-
|
|
1158
|
+
const { mode: nodeMode, detail: nodeDetail } = (0, param_aliases_1.resolveGetNodeAliases)(args.mode, args.detail);
|
|
1159
|
+
if (nodeMode === 'docs') {
|
|
1126
1160
|
return this.getNodeDocumentation(args.nodeType);
|
|
1127
1161
|
}
|
|
1128
|
-
if (
|
|
1162
|
+
if (nodeMode === 'search_properties') {
|
|
1129
1163
|
if (!args.propertyQuery) {
|
|
1130
1164
|
throw new Error('propertyQuery is required for mode=search_properties');
|
|
1131
1165
|
}
|
|
1132
1166
|
const maxResults = args.maxPropertyResults !== undefined ? Number(args.maxPropertyResults) || 20 : 20;
|
|
1133
1167
|
return this.searchNodeProperties(args.nodeType, args.propertyQuery, maxResults);
|
|
1134
1168
|
}
|
|
1135
|
-
return this.getNode(args.nodeType,
|
|
1169
|
+
return this.getNode(args.nodeType, nodeDetail, nodeMode, args.includeTypeInfo, args.includeExamples, args.fromVersion, args.toVersion);
|
|
1170
|
+
}
|
|
1136
1171
|
case 'validate_node':
|
|
1137
1172
|
this.validateToolParams(name, args, ['nodeType', 'config']);
|
|
1138
1173
|
if (typeof args.config !== 'object' || args.config === null) {
|
|
@@ -1268,27 +1303,32 @@ class N8NDocumentationMCPServer {
|
|
|
1268
1303
|
if (!this.repository)
|
|
1269
1304
|
throw new Error('Repository not initialized');
|
|
1270
1305
|
return n8nHandlers.handleAutofixWorkflow(args, this.repository, this.instanceContext);
|
|
1271
|
-
case 'n8n_test_workflow':
|
|
1272
|
-
|
|
1273
|
-
|
|
1306
|
+
case 'n8n_test_workflow': {
|
|
1307
|
+
const testArgs = (0, param_aliases_1.withWorkflowIdAlias)(args);
|
|
1308
|
+
this.validateToolParams(name, testArgs);
|
|
1309
|
+
return n8nHandlers.handleTestWorkflow(testArgs, this.instanceContext);
|
|
1310
|
+
}
|
|
1274
1311
|
case 'n8n_executions': {
|
|
1275
|
-
this.validateToolParams(name, args
|
|
1276
|
-
const execAction = args
|
|
1312
|
+
this.validateToolParams(name, args);
|
|
1313
|
+
const execAction = String((0, tool_policy_1.resolveRequestedOperation)(name, args));
|
|
1277
1314
|
switch (execAction) {
|
|
1278
1315
|
case 'get':
|
|
1279
|
-
if (!args.id) {
|
|
1280
|
-
|
|
1316
|
+
if (!(0, param_aliases_1.hasText)(args.id)) {
|
|
1317
|
+
return this.listExecutionsInsteadOfGet(args);
|
|
1281
1318
|
}
|
|
1282
1319
|
return n8nHandlers.handleGetExecution(args, this.instanceContext);
|
|
1283
1320
|
case 'list':
|
|
1284
1321
|
return n8nHandlers.handleListExecutions(args, this.instanceContext);
|
|
1285
1322
|
case 'delete':
|
|
1286
|
-
if (!args.id) {
|
|
1323
|
+
if (!(0, param_aliases_1.hasText)(args.id)) {
|
|
1287
1324
|
throw new Error('id is required for action=delete');
|
|
1288
1325
|
}
|
|
1289
1326
|
return n8nHandlers.handleDeleteExecution(args, this.instanceContext);
|
|
1290
|
-
default:
|
|
1291
|
-
|
|
1327
|
+
default: {
|
|
1328
|
+
const message = `Unknown action: ${execAction}. Valid actions: get, list, delete.`;
|
|
1329
|
+
const hint = (0, param_aliases_1.suggestExecutionsAction)(execAction);
|
|
1330
|
+
throw new Error(hint ? `${message} ${hint}` : message);
|
|
1331
|
+
}
|
|
1292
1332
|
}
|
|
1293
1333
|
}
|
|
1294
1334
|
case 'n8n_evaluations': {
|
|
@@ -1324,8 +1364,7 @@ class N8NDocumentationMCPServer {
|
|
|
1324
1364
|
}
|
|
1325
1365
|
return n8nHandlers.handleHealthCheck(this.instanceContext);
|
|
1326
1366
|
case 'n8n_workflow_versions':
|
|
1327
|
-
|
|
1328
|
-
return n8nHandlers.handleWorkflowVersions(args, this.repository, this.instanceContext);
|
|
1367
|
+
return n8nHandlers.handleWorkflowVersions((0, param_aliases_1.withWorkflowIdAlias)(args), this.repository, this.instanceContext);
|
|
1329
1368
|
case 'n8n_deploy_template':
|
|
1330
1369
|
this.validateToolParams(name, args, ['templateId']);
|
|
1331
1370
|
await this.ensureInitialized();
|
|
@@ -2410,7 +2449,7 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
2410
2449
|
throw new Error(`get_node: Invalid detail level "${detail}". Valid options: ${validDetailLevels.join(', ')}`);
|
|
2411
2450
|
}
|
|
2412
2451
|
if (!validModes.includes(mode)) {
|
|
2413
|
-
throw new Error(`get_node: Invalid mode "${mode}". Valid options: ${validModes.join(', ')}`);
|
|
2452
|
+
throw new Error(`get_node: Invalid mode "${mode}". Valid options: info, docs, search_properties, ${validModes.slice(1).join(', ')}`);
|
|
2414
2453
|
}
|
|
2415
2454
|
const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(nodeType);
|
|
2416
2455
|
if (mode !== 'info') {
|
|
@@ -2530,28 +2569,75 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
2530
2569
|
...extra
|
|
2531
2570
|
};
|
|
2532
2571
|
}
|
|
2533
|
-
getVersionHistory(nodeType) {
|
|
2572
|
+
async getVersionHistory(nodeType) {
|
|
2534
2573
|
if (!this.repository.hasVersionMetadata(nodeType)) {
|
|
2574
|
+
const node = this.repository.getNode(nodeType);
|
|
2575
|
+
if (node && node.isVersioned === false && node.version) {
|
|
2576
|
+
return {
|
|
2577
|
+
nodeType,
|
|
2578
|
+
available: true,
|
|
2579
|
+
totalVersions: 1,
|
|
2580
|
+
versions: [{
|
|
2581
|
+
version: String(node.version),
|
|
2582
|
+
isCurrent: true,
|
|
2583
|
+
hasBreakingChanges: false,
|
|
2584
|
+
breakingChangesCount: 0,
|
|
2585
|
+
deprecatedProperties: [],
|
|
2586
|
+
addedProperties: []
|
|
2587
|
+
}]
|
|
2588
|
+
};
|
|
2589
|
+
}
|
|
2535
2590
|
return this.versionMetadataUnavailable(nodeType, { totalVersions: 0, versions: [] });
|
|
2536
2591
|
}
|
|
2537
2592
|
const versions = this.repository.getNodeVersions(nodeType);
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2593
|
+
const entries = [];
|
|
2594
|
+
for (let i = 0; i < versions.length; i++) {
|
|
2595
|
+
const v = versions[i];
|
|
2596
|
+
const previous = versions[i + 1];
|
|
2597
|
+
const breakingCount = previous
|
|
2598
|
+
? (await this.analyzeVersionUpgrade(nodeType, previous.version, v.version))
|
|
2599
|
+
.changes.filter(c => c.isBreaking).length
|
|
2600
|
+
: 0;
|
|
2601
|
+
entries.push({
|
|
2543
2602
|
version: v.version,
|
|
2544
2603
|
isCurrent: v.isCurrentMax,
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
hasBreakingChanges: (v.breakingChanges || []).length > 0,
|
|
2548
|
-
breakingChangesCount: (v.breakingChanges || []).length,
|
|
2604
|
+
hasBreakingChanges: breakingCount > 0,
|
|
2605
|
+
breakingChangesCount: breakingCount,
|
|
2549
2606
|
deprecatedProperties: v.deprecatedProperties || [],
|
|
2550
2607
|
addedProperties: v.addedProperties || []
|
|
2551
|
-
})
|
|
2608
|
+
});
|
|
2609
|
+
}
|
|
2610
|
+
return {
|
|
2611
|
+
nodeType,
|
|
2612
|
+
available: true,
|
|
2613
|
+
totalVersions: entries.length,
|
|
2614
|
+
versions: entries
|
|
2552
2615
|
};
|
|
2553
2616
|
}
|
|
2554
|
-
|
|
2617
|
+
async analyzeVersionUpgrade(nodeType, fromVersion, toVersion) {
|
|
2618
|
+
const from = (0, node_parser_1.normalizeNodeVersion)(fromVersion);
|
|
2619
|
+
const to = (0, node_parser_1.normalizeNodeVersion)(toVersion ?? this.defaultTargetVersion(nodeType, from));
|
|
2620
|
+
for (const version of [from, to]) {
|
|
2621
|
+
if (!this.repository.getNodeVersion(nodeType, version)) {
|
|
2622
|
+
const known = this.repository.getNodeVersions(nodeType).map(v => v.version).join(', ');
|
|
2623
|
+
throw new Error(`get_node: version "${version}" is not a recorded version of ${nodeType} (recorded: ${known})`);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
this.breakingChangeDetector ?? (this.breakingChangeDetector = new breaking_change_detector_1.BreakingChangeDetector(this.repository));
|
|
2627
|
+
return this.breakingChangeDetector.analyzeVersionUpgrade(node_type_normalizer_1.NodeTypeNormalizer.toWorkflowFormat(nodeType), from, to);
|
|
2628
|
+
}
|
|
2629
|
+
defaultTargetVersion(nodeType, fromVersion) {
|
|
2630
|
+
const current = this.repository.getLatestNodeVersion(nodeType)?.version
|
|
2631
|
+
?? this.repository.getNode(nodeType)?.version;
|
|
2632
|
+
if (!current) {
|
|
2633
|
+
throw new Error('No target version available');
|
|
2634
|
+
}
|
|
2635
|
+
if (Number(fromVersion) <= Number(current))
|
|
2636
|
+
return current;
|
|
2637
|
+
const newest = this.repository.getNodeVersions(nodeType)[0]?.version;
|
|
2638
|
+
return newest ?? current;
|
|
2639
|
+
}
|
|
2640
|
+
async compareVersions(nodeType, fromVersion, toVersion) {
|
|
2555
2641
|
if (!this.repository.hasVersionMetadata(nodeType)) {
|
|
2556
2642
|
return this.versionMetadataUnavailable(nodeType, {
|
|
2557
2643
|
fromVersion,
|
|
@@ -2560,20 +2646,15 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
2560
2646
|
changes: []
|
|
2561
2647
|
});
|
|
2562
2648
|
}
|
|
2563
|
-
const
|
|
2564
|
-
const targetVersion = toVersion || latest?.version;
|
|
2565
|
-
if (!targetVersion) {
|
|
2566
|
-
throw new Error('No target version available');
|
|
2567
|
-
}
|
|
2568
|
-
const changes = this.repository.getPropertyChanges(nodeType, fromVersion, targetVersion);
|
|
2649
|
+
const analysis = await this.analyzeVersionUpgrade(nodeType, fromVersion, toVersion);
|
|
2569
2650
|
return {
|
|
2570
2651
|
nodeType,
|
|
2571
2652
|
available: true,
|
|
2572
|
-
fromVersion,
|
|
2573
|
-
toVersion:
|
|
2574
|
-
totalChanges: changes.length,
|
|
2575
|
-
breakingChanges: changes.filter(c => c.isBreaking).length,
|
|
2576
|
-
changes: changes.map(c => ({
|
|
2653
|
+
fromVersion: analysis.fromVersion,
|
|
2654
|
+
toVersion: analysis.toVersion,
|
|
2655
|
+
totalChanges: analysis.changes.length,
|
|
2656
|
+
breakingChanges: analysis.changes.filter(c => c.isBreaking).length,
|
|
2657
|
+
changes: analysis.changes.map(c => ({
|
|
2577
2658
|
property: c.propertyName,
|
|
2578
2659
|
changeType: c.changeType,
|
|
2579
2660
|
isBreaking: c.isBreaking,
|
|
@@ -2581,11 +2662,12 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
2581
2662
|
oldValue: c.oldValue,
|
|
2582
2663
|
newValue: c.newValue,
|
|
2583
2664
|
migrationHint: c.migrationHint,
|
|
2584
|
-
autoMigratable: c.autoMigratable
|
|
2665
|
+
autoMigratable: c.autoMigratable,
|
|
2666
|
+
source: c.source
|
|
2585
2667
|
}))
|
|
2586
2668
|
};
|
|
2587
2669
|
}
|
|
2588
|
-
getBreakingChanges(nodeType, fromVersion, toVersion) {
|
|
2670
|
+
async getBreakingChanges(nodeType, fromVersion, toVersion) {
|
|
2589
2671
|
if (!this.repository.hasVersionMetadata(nodeType)) {
|
|
2590
2672
|
return this.versionMetadataUnavailable(nodeType, {
|
|
2591
2673
|
fromVersion,
|
|
@@ -2594,27 +2676,30 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
2594
2676
|
changes: []
|
|
2595
2677
|
});
|
|
2596
2678
|
}
|
|
2597
|
-
const
|
|
2679
|
+
const analysis = await this.analyzeVersionUpgrade(nodeType, fromVersion, toVersion);
|
|
2680
|
+
const breakingChanges = analysis.changes.filter(c => c.isBreaking);
|
|
2598
2681
|
return {
|
|
2599
2682
|
nodeType,
|
|
2600
2683
|
available: true,
|
|
2601
|
-
fromVersion,
|
|
2602
|
-
toVersion: toVersion
|
|
2684
|
+
fromVersion: analysis.fromVersion,
|
|
2685
|
+
toVersion: analysis.toVersion,
|
|
2603
2686
|
totalBreakingChanges: breakingChanges.length,
|
|
2604
2687
|
changes: breakingChanges.map(c => ({
|
|
2605
|
-
fromVersion: c.fromVersion,
|
|
2606
|
-
toVersion: c.toVersion,
|
|
2688
|
+
fromVersion: c.fromVersion ?? analysis.fromVersion,
|
|
2689
|
+
toVersion: c.toVersion ?? analysis.toVersion,
|
|
2607
2690
|
property: c.propertyName,
|
|
2608
2691
|
changeType: c.changeType,
|
|
2609
2692
|
severity: c.severity,
|
|
2610
2693
|
migrationHint: c.migrationHint,
|
|
2611
2694
|
oldValue: c.oldValue,
|
|
2612
|
-
newValue: c.newValue
|
|
2695
|
+
newValue: c.newValue,
|
|
2696
|
+
source: c.source
|
|
2613
2697
|
})),
|
|
2614
|
-
upgradeSafe: breakingChanges.length === 0
|
|
2698
|
+
upgradeSafe: breakingChanges.length === 0,
|
|
2699
|
+
recommendations: analysis.recommendations
|
|
2615
2700
|
};
|
|
2616
2701
|
}
|
|
2617
|
-
getMigrations(nodeType, fromVersion, toVersion) {
|
|
2702
|
+
async getMigrations(nodeType, fromVersion, toVersion) {
|
|
2618
2703
|
if (!this.repository.hasVersionMetadata(nodeType)) {
|
|
2619
2704
|
return this.versionMetadataUnavailable(nodeType, {
|
|
2620
2705
|
fromVersion,
|
|
@@ -2624,22 +2709,25 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|
|
2624
2709
|
migrations: []
|
|
2625
2710
|
});
|
|
2626
2711
|
}
|
|
2627
|
-
const
|
|
2628
|
-
const
|
|
2712
|
+
const analysis = await this.analyzeVersionUpgrade(nodeType, fromVersion, toVersion);
|
|
2713
|
+
const migrations = analysis.changes.filter(c => c.autoMigratable && c.migrationStrategy);
|
|
2714
|
+
const noActionRequired = analysis.changes.filter(c => c.autoMigratable && !c.migrationStrategy).length;
|
|
2629
2715
|
return {
|
|
2630
2716
|
nodeType,
|
|
2631
2717
|
available: true,
|
|
2632
|
-
fromVersion,
|
|
2633
|
-
toVersion,
|
|
2718
|
+
fromVersion: analysis.fromVersion,
|
|
2719
|
+
toVersion: analysis.toVersion,
|
|
2634
2720
|
autoMigratableChanges: migrations.length,
|
|
2635
|
-
|
|
2721
|
+
noActionRequired,
|
|
2722
|
+
totalChanges: analysis.changes.length,
|
|
2636
2723
|
migrations: migrations.map(m => ({
|
|
2637
2724
|
property: m.propertyName,
|
|
2638
2725
|
changeType: m.changeType,
|
|
2639
2726
|
migrationStrategy: m.migrationStrategy,
|
|
2640
|
-
severity: m.severity
|
|
2727
|
+
severity: m.severity,
|
|
2728
|
+
source: m.source
|
|
2641
2729
|
})),
|
|
2642
|
-
requiresManualMigration:
|
|
2730
|
+
requiresManualMigration: analysis.manualRequiredCount > 0
|
|
2643
2731
|
};
|
|
2644
2732
|
}
|
|
2645
2733
|
enrichPropertyWithTypeInfo(property) {
|