n8n-mcp 2.12.2 → 2.13.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.
Files changed (72) hide show
  1. package/README.md +6 -4
  2. package/data/nodes.db +0 -0
  3. package/dist/mcp/handlers-n8n-manager.d.ts +1 -0
  4. package/dist/mcp/handlers-n8n-manager.d.ts.map +1 -1
  5. package/dist/mcp/handlers-n8n-manager.js +144 -1
  6. package/dist/mcp/handlers-n8n-manager.js.map +1 -1
  7. package/dist/mcp/server.d.ts.map +1 -1
  8. package/dist/mcp/server.js +7 -0
  9. package/dist/mcp/server.js.map +1 -1
  10. package/dist/mcp/tool-docs/index.d.ts.map +1 -1
  11. package/dist/mcp/tool-docs/index.js +1 -0
  12. package/dist/mcp/tool-docs/index.js.map +1 -1
  13. package/dist/mcp/tool-docs/validation/validate-workflow.js +1 -1
  14. package/dist/mcp/tool-docs/validation/validate-workflow.js.map +1 -1
  15. package/dist/mcp/tool-docs/workflow_management/index.d.ts +1 -0
  16. package/dist/mcp/tool-docs/workflow_management/index.d.ts.map +1 -1
  17. package/dist/mcp/tool-docs/workflow_management/index.js +3 -1
  18. package/dist/mcp/tool-docs/workflow_management/index.js.map +1 -1
  19. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts +3 -0
  20. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts.map +1 -0
  21. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js +127 -0
  22. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js.map +1 -0
  23. package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js +1 -1
  24. package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js.map +1 -1
  25. package/dist/mcp/tools-n8n-manager.d.ts.map +1 -1
  26. package/dist/mcp/tools-n8n-manager.js +35 -0
  27. package/dist/mcp/tools-n8n-manager.js.map +1 -1
  28. package/dist/scripts/debug-http-search.d.ts +3 -0
  29. package/dist/scripts/debug-http-search.d.ts.map +1 -0
  30. package/dist/scripts/debug-http-search.js +57 -0
  31. package/dist/scripts/debug-http-search.js.map +1 -0
  32. package/dist/scripts/test-autofix-documentation.d.ts +3 -0
  33. package/dist/scripts/test-autofix-documentation.d.ts.map +1 -0
  34. package/dist/scripts/test-autofix-documentation.js +103 -0
  35. package/dist/scripts/test-autofix-documentation.js.map +1 -0
  36. package/dist/scripts/test-autofix-workflow.d.ts +2 -0
  37. package/dist/scripts/test-autofix-workflow.d.ts.map +1 -0
  38. package/dist/scripts/test-autofix-workflow.js +223 -0
  39. package/dist/scripts/test-autofix-workflow.js.map +1 -0
  40. package/dist/scripts/test-node-suggestions.d.ts +3 -0
  41. package/dist/scripts/test-node-suggestions.d.ts.map +1 -0
  42. package/dist/scripts/test-node-suggestions.js +165 -0
  43. package/dist/scripts/test-node-suggestions.js.map +1 -0
  44. package/dist/scripts/test-summary.d.ts +3 -0
  45. package/dist/scripts/test-summary.d.ts.map +1 -0
  46. package/dist/scripts/test-summary.js +77 -0
  47. package/dist/scripts/test-summary.js.map +1 -0
  48. package/dist/scripts/test-validation-parity.d.ts +2 -0
  49. package/dist/scripts/test-validation-parity.d.ts.map +1 -0
  50. package/dist/scripts/test-validation-parity.js +153 -0
  51. package/dist/scripts/test-validation-parity.js.map +1 -0
  52. package/dist/scripts/test-webhook-autofix.d.ts +3 -0
  53. package/dist/scripts/test-webhook-autofix.d.ts.map +1 -0
  54. package/dist/scripts/test-webhook-autofix.js +117 -0
  55. package/dist/scripts/test-webhook-autofix.js.map +1 -0
  56. package/dist/services/node-similarity-service.d.ts +51 -0
  57. package/dist/services/node-similarity-service.d.ts.map +1 -0
  58. package/dist/services/node-similarity-service.js +335 -0
  59. package/dist/services/node-similarity-service.js.map +1 -0
  60. package/dist/services/workflow-auto-fixer.d.ts +65 -0
  61. package/dist/services/workflow-auto-fixer.d.ts.map +1 -0
  62. package/dist/services/workflow-auto-fixer.js +394 -0
  63. package/dist/services/workflow-auto-fixer.js.map +1 -0
  64. package/dist/services/workflow-validator.d.ts +1 -1
  65. package/dist/services/workflow-validator.d.ts.map +1 -1
  66. package/dist/services/workflow-validator.js +37 -89
  67. package/dist/services/workflow-validator.js.map +1 -1
  68. package/dist/utils/node-type-utils.d.ts +9 -0
  69. package/dist/utils/node-type-utils.d.ts.map +1 -0
  70. package/dist/utils/node-type-utils.js +78 -0
  71. package/dist/utils/node-type-utils.js.map +1 -0
  72. package/package.json +1 -1
@@ -0,0 +1,394 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WorkflowAutoFixer = void 0;
7
+ exports.isNodeFormatIssue = isNodeFormatIssue;
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ const node_similarity_service_1 = require("./node-similarity-service");
10
+ const logger_1 = require("../utils/logger");
11
+ const logger = new logger_1.Logger({ prefix: '[WorkflowAutoFixer]' });
12
+ function isNodeFormatIssue(issue) {
13
+ return 'nodeName' in issue && 'nodeId' in issue &&
14
+ typeof issue.nodeName === 'string' &&
15
+ typeof issue.nodeId === 'string';
16
+ }
17
+ class WorkflowAutoFixer {
18
+ constructor(repository) {
19
+ this.defaultConfig = {
20
+ applyFixes: false,
21
+ confidenceThreshold: 'medium',
22
+ maxFixes: 50
23
+ };
24
+ this.similarityService = null;
25
+ if (repository) {
26
+ this.similarityService = new node_similarity_service_1.NodeSimilarityService(repository);
27
+ }
28
+ }
29
+ generateFixes(workflow, validationResult, formatIssues = [], config = {}) {
30
+ const fullConfig = { ...this.defaultConfig, ...config };
31
+ const operations = [];
32
+ const fixes = [];
33
+ const nodeMap = new Map();
34
+ workflow.nodes.forEach(node => {
35
+ nodeMap.set(node.name, node);
36
+ nodeMap.set(node.id, node);
37
+ });
38
+ if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('expression-format')) {
39
+ this.processExpressionFormatFixes(formatIssues, nodeMap, operations, fixes);
40
+ }
41
+ if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('typeversion-correction')) {
42
+ this.processTypeVersionFixes(validationResult, nodeMap, operations, fixes);
43
+ }
44
+ if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('error-output-config')) {
45
+ this.processErrorOutputFixes(validationResult, nodeMap, workflow, operations, fixes);
46
+ }
47
+ if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('node-type-correction')) {
48
+ this.processNodeTypeFixes(validationResult, nodeMap, operations, fixes);
49
+ }
50
+ if (!fullConfig.fixTypes || fullConfig.fixTypes.includes('webhook-missing-path')) {
51
+ this.processWebhookPathFixes(validationResult, nodeMap, operations, fixes);
52
+ }
53
+ const filteredFixes = this.filterByConfidence(fixes, fullConfig.confidenceThreshold);
54
+ const filteredOperations = this.filterOperationsByFixes(operations, filteredFixes, fixes);
55
+ const limitedFixes = filteredFixes.slice(0, fullConfig.maxFixes);
56
+ const limitedOperations = this.filterOperationsByFixes(filteredOperations, limitedFixes, filteredFixes);
57
+ const stats = this.calculateStats(limitedFixes);
58
+ const summary = this.generateSummary(stats);
59
+ return {
60
+ operations: limitedOperations,
61
+ fixes: limitedFixes,
62
+ summary,
63
+ stats
64
+ };
65
+ }
66
+ processExpressionFormatFixes(formatIssues, nodeMap, operations, fixes) {
67
+ const fixesByNode = new Map();
68
+ for (const issue of formatIssues) {
69
+ if (issue.issueType === 'missing-prefix') {
70
+ if (!isNodeFormatIssue(issue)) {
71
+ logger.warn('Expression format issue missing node information', {
72
+ fieldPath: issue.fieldPath,
73
+ issueType: issue.issueType
74
+ });
75
+ continue;
76
+ }
77
+ const nodeName = issue.nodeName;
78
+ if (!fixesByNode.has(nodeName)) {
79
+ fixesByNode.set(nodeName, []);
80
+ }
81
+ fixesByNode.get(nodeName).push(issue);
82
+ }
83
+ }
84
+ for (const [nodeName, nodeIssues] of fixesByNode) {
85
+ const node = nodeMap.get(nodeName);
86
+ if (!node)
87
+ continue;
88
+ const updatedParameters = JSON.parse(JSON.stringify(node.parameters || {}));
89
+ for (const issue of nodeIssues) {
90
+ const fieldPath = issue.fieldPath.split('.');
91
+ this.setNestedValue(updatedParameters, fieldPath, issue.correctedValue);
92
+ fixes.push({
93
+ node: nodeName,
94
+ field: issue.fieldPath,
95
+ type: 'expression-format',
96
+ before: issue.currentValue,
97
+ after: issue.correctedValue,
98
+ confidence: 'high',
99
+ description: issue.explanation
100
+ });
101
+ }
102
+ const operation = {
103
+ type: 'updateNode',
104
+ nodeId: nodeName,
105
+ updates: {
106
+ parameters: updatedParameters
107
+ }
108
+ };
109
+ operations.push(operation);
110
+ }
111
+ }
112
+ processTypeVersionFixes(validationResult, nodeMap, operations, fixes) {
113
+ for (const error of validationResult.errors) {
114
+ if (error.message.includes('typeVersion') && error.message.includes('exceeds maximum')) {
115
+ const versionMatch = error.message.match(/typeVersion (\d+(?:\.\d+)?) exceeds maximum supported version (\d+(?:\.\d+)?)/);
116
+ if (versionMatch) {
117
+ const currentVersion = parseFloat(versionMatch[1]);
118
+ const maxVersion = parseFloat(versionMatch[2]);
119
+ const nodeName = error.nodeName || error.nodeId;
120
+ if (!nodeName)
121
+ continue;
122
+ const node = nodeMap.get(nodeName);
123
+ if (!node)
124
+ continue;
125
+ fixes.push({
126
+ node: nodeName,
127
+ field: 'typeVersion',
128
+ type: 'typeversion-correction',
129
+ before: currentVersion,
130
+ after: maxVersion,
131
+ confidence: 'medium',
132
+ description: `Corrected typeVersion from ${currentVersion} to maximum supported ${maxVersion}`
133
+ });
134
+ const operation = {
135
+ type: 'updateNode',
136
+ nodeId: nodeName,
137
+ updates: {
138
+ typeVersion: maxVersion
139
+ }
140
+ };
141
+ operations.push(operation);
142
+ }
143
+ }
144
+ }
145
+ }
146
+ processErrorOutputFixes(validationResult, nodeMap, workflow, operations, fixes) {
147
+ for (const error of validationResult.errors) {
148
+ if (error.message.includes('onError: \'continueErrorOutput\'') &&
149
+ error.message.includes('no error output connections')) {
150
+ const nodeName = error.nodeName || error.nodeId;
151
+ if (!nodeName)
152
+ continue;
153
+ const node = nodeMap.get(nodeName);
154
+ if (!node)
155
+ continue;
156
+ fixes.push({
157
+ node: nodeName,
158
+ field: 'onError',
159
+ type: 'error-output-config',
160
+ before: 'continueErrorOutput',
161
+ after: undefined,
162
+ confidence: 'medium',
163
+ description: 'Removed onError setting due to missing error output connections'
164
+ });
165
+ const operation = {
166
+ type: 'updateNode',
167
+ nodeId: nodeName,
168
+ updates: {
169
+ onError: undefined
170
+ }
171
+ };
172
+ operations.push(operation);
173
+ }
174
+ }
175
+ }
176
+ processNodeTypeFixes(validationResult, nodeMap, operations, fixes) {
177
+ if (!this.similarityService) {
178
+ return;
179
+ }
180
+ for (const error of validationResult.errors) {
181
+ const nodeError = error;
182
+ if (error.message?.includes('Unknown node type:') && nodeError.suggestions) {
183
+ const highConfidenceSuggestion = nodeError.suggestions.find(s => s.confidence >= 0.9);
184
+ if (highConfidenceSuggestion && nodeError.nodeId) {
185
+ const node = nodeMap.get(nodeError.nodeId) || nodeMap.get(nodeError.nodeName || '');
186
+ if (node) {
187
+ fixes.push({
188
+ node: node.name,
189
+ field: 'type',
190
+ type: 'node-type-correction',
191
+ before: node.type,
192
+ after: highConfidenceSuggestion.nodeType,
193
+ confidence: 'high',
194
+ description: `Fix node type: "${node.type}" → "${highConfidenceSuggestion.nodeType}" (${highConfidenceSuggestion.reason})`
195
+ });
196
+ const operation = {
197
+ type: 'updateNode',
198
+ nodeId: node.name,
199
+ updates: {
200
+ type: highConfidenceSuggestion.nodeType
201
+ }
202
+ };
203
+ operations.push(operation);
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ processWebhookPathFixes(validationResult, nodeMap, operations, fixes) {
210
+ for (const error of validationResult.errors) {
211
+ if (error.message === 'Webhook path is required') {
212
+ const nodeName = error.nodeName || error.nodeId;
213
+ if (!nodeName)
214
+ continue;
215
+ const node = nodeMap.get(nodeName);
216
+ if (!node)
217
+ continue;
218
+ if (!node.type?.includes('webhook'))
219
+ continue;
220
+ const webhookId = crypto_1.default.randomUUID();
221
+ const currentTypeVersion = node.typeVersion || 1;
222
+ const needsVersionUpdate = currentTypeVersion < 2.1;
223
+ fixes.push({
224
+ node: nodeName,
225
+ field: 'path',
226
+ type: 'webhook-missing-path',
227
+ before: undefined,
228
+ after: webhookId,
229
+ confidence: 'high',
230
+ description: needsVersionUpdate
231
+ ? `Generated webhook path and ID: ${webhookId} (also updating typeVersion to 2.1)`
232
+ : `Generated webhook path and ID: ${webhookId}`
233
+ });
234
+ const updates = {
235
+ 'parameters.path': webhookId,
236
+ 'webhookId': webhookId
237
+ };
238
+ if (needsVersionUpdate) {
239
+ updates['typeVersion'] = 2.1;
240
+ }
241
+ const operation = {
242
+ type: 'updateNode',
243
+ nodeId: nodeName,
244
+ updates
245
+ };
246
+ operations.push(operation);
247
+ }
248
+ }
249
+ }
250
+ setNestedValue(obj, path, value) {
251
+ if (!obj || typeof obj !== 'object') {
252
+ throw new Error('Cannot set value on non-object');
253
+ }
254
+ if (path.length === 0) {
255
+ throw new Error('Cannot set value with empty path');
256
+ }
257
+ try {
258
+ let current = obj;
259
+ for (let i = 0; i < path.length - 1; i++) {
260
+ const key = path[i];
261
+ if (key.includes('[')) {
262
+ const matches = key.match(/^([^[]+)\[(\d+)\]$/);
263
+ if (!matches) {
264
+ throw new Error(`Invalid array notation: ${key}`);
265
+ }
266
+ const [, arrayKey, indexStr] = matches;
267
+ const index = parseInt(indexStr, 10);
268
+ if (isNaN(index) || index < 0) {
269
+ throw new Error(`Invalid array index: ${indexStr}`);
270
+ }
271
+ if (!current[arrayKey]) {
272
+ current[arrayKey] = [];
273
+ }
274
+ if (!Array.isArray(current[arrayKey])) {
275
+ throw new Error(`Expected array at ${arrayKey}, got ${typeof current[arrayKey]}`);
276
+ }
277
+ while (current[arrayKey].length <= index) {
278
+ current[arrayKey].push({});
279
+ }
280
+ current = current[arrayKey][index];
281
+ }
282
+ else {
283
+ if (current[key] === null || current[key] === undefined) {
284
+ current[key] = {};
285
+ }
286
+ if (typeof current[key] !== 'object' || Array.isArray(current[key])) {
287
+ throw new Error(`Cannot traverse through ${typeof current[key]} at ${key}`);
288
+ }
289
+ current = current[key];
290
+ }
291
+ }
292
+ const lastKey = path[path.length - 1];
293
+ if (lastKey.includes('[')) {
294
+ const matches = lastKey.match(/^([^[]+)\[(\d+)\]$/);
295
+ if (!matches) {
296
+ throw new Error(`Invalid array notation: ${lastKey}`);
297
+ }
298
+ const [, arrayKey, indexStr] = matches;
299
+ const index = parseInt(indexStr, 10);
300
+ if (isNaN(index) || index < 0) {
301
+ throw new Error(`Invalid array index: ${indexStr}`);
302
+ }
303
+ if (!current[arrayKey]) {
304
+ current[arrayKey] = [];
305
+ }
306
+ if (!Array.isArray(current[arrayKey])) {
307
+ throw new Error(`Expected array at ${arrayKey}, got ${typeof current[arrayKey]}`);
308
+ }
309
+ while (current[arrayKey].length <= index) {
310
+ current[arrayKey].push(null);
311
+ }
312
+ current[arrayKey][index] = value;
313
+ }
314
+ else {
315
+ current[lastKey] = value;
316
+ }
317
+ }
318
+ catch (error) {
319
+ logger.error('Failed to set nested value', {
320
+ path: path.join('.'),
321
+ error: error instanceof Error ? error.message : String(error)
322
+ });
323
+ throw error;
324
+ }
325
+ }
326
+ filterByConfidence(fixes, threshold) {
327
+ if (!threshold)
328
+ return fixes;
329
+ const levels = ['high', 'medium', 'low'];
330
+ const thresholdIndex = levels.indexOf(threshold);
331
+ return fixes.filter(fix => {
332
+ const fixIndex = levels.indexOf(fix.confidence);
333
+ return fixIndex <= thresholdIndex;
334
+ });
335
+ }
336
+ filterOperationsByFixes(operations, filteredFixes, allFixes) {
337
+ const fixedNodes = new Set(filteredFixes.map(f => f.node));
338
+ return operations.filter(op => {
339
+ if (op.type === 'updateNode') {
340
+ return fixedNodes.has(op.nodeId || '');
341
+ }
342
+ return true;
343
+ });
344
+ }
345
+ calculateStats(fixes) {
346
+ const stats = {
347
+ total: fixes.length,
348
+ byType: {
349
+ 'expression-format': 0,
350
+ 'typeversion-correction': 0,
351
+ 'error-output-config': 0,
352
+ 'node-type-correction': 0,
353
+ 'webhook-missing-path': 0
354
+ },
355
+ byConfidence: {
356
+ 'high': 0,
357
+ 'medium': 0,
358
+ 'low': 0
359
+ }
360
+ };
361
+ for (const fix of fixes) {
362
+ stats.byType[fix.type]++;
363
+ stats.byConfidence[fix.confidence]++;
364
+ }
365
+ return stats;
366
+ }
367
+ generateSummary(stats) {
368
+ if (stats.total === 0) {
369
+ return 'No fixes available';
370
+ }
371
+ const parts = [];
372
+ if (stats.byType['expression-format'] > 0) {
373
+ parts.push(`${stats.byType['expression-format']} expression format ${stats.byType['expression-format'] === 1 ? 'error' : 'errors'}`);
374
+ }
375
+ if (stats.byType['typeversion-correction'] > 0) {
376
+ parts.push(`${stats.byType['typeversion-correction']} version ${stats.byType['typeversion-correction'] === 1 ? 'issue' : 'issues'}`);
377
+ }
378
+ if (stats.byType['error-output-config'] > 0) {
379
+ parts.push(`${stats.byType['error-output-config']} error output ${stats.byType['error-output-config'] === 1 ? 'configuration' : 'configurations'}`);
380
+ }
381
+ if (stats.byType['node-type-correction'] > 0) {
382
+ parts.push(`${stats.byType['node-type-correction']} node type ${stats.byType['node-type-correction'] === 1 ? 'correction' : 'corrections'}`);
383
+ }
384
+ if (stats.byType['webhook-missing-path'] > 0) {
385
+ parts.push(`${stats.byType['webhook-missing-path']} webhook ${stats.byType['webhook-missing-path'] === 1 ? 'path' : 'paths'}`);
386
+ }
387
+ if (parts.length === 0) {
388
+ return `Fixed ${stats.total} ${stats.total === 1 ? 'issue' : 'issues'}`;
389
+ }
390
+ return `Fixed ${parts.join(', ')}`;
391
+ }
392
+ }
393
+ exports.WorkflowAutoFixer = WorkflowAutoFixer;
394
+ //# sourceMappingURL=workflow-auto-fixer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-auto-fixer.js","sourceRoot":"","sources":["../../src/services/workflow-auto-fixer.ts"],"names":[],"mappings":"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"}
@@ -72,6 +72,7 @@ export declare class WorkflowValidator {
72
72
  private nodeRepository;
73
73
  private nodeValidator;
74
74
  private currentWorkflow;
75
+ private similarityService;
75
76
  constructor(nodeRepository: NodeRepository, nodeValidator: typeof EnhancedConfigValidator);
76
77
  private isStickyNote;
77
78
  validateWorkflow(workflow: WorkflowJson, options?: {
@@ -92,7 +93,6 @@ export declare class WorkflowValidator {
92
93
  private nodeHasInput;
93
94
  private checkWorkflowPatterns;
94
95
  private getLongestLinearChain;
95
- private findSimilarNodeTypes;
96
96
  private generateSuggestions;
97
97
  private checkNodeErrorHandling;
98
98
  private generateErrorHandlingSuggestions;
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-validator.d.ts","sourceRoot":"","sources":["../../src/services/workflow-validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow-validator.d.ts","sourceRoot":"","sources":["../../src/services/workflow-validator.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WorkflowValidator = void 0;
4
4
  const expression_validator_1 = require("./expression-validator");
5
5
  const expression_format_validator_1 = require("./expression-format-validator");
6
+ const node_similarity_service_1 = require("./node-similarity-service");
7
+ const node_type_utils_1 = require("../utils/node-type-utils");
6
8
  const logger_1 = require("../utils/logger");
7
9
  const logger = new logger_1.Logger({ prefix: '[WorkflowValidator]' });
8
10
  class WorkflowValidator {
@@ -10,6 +12,7 @@ class WorkflowValidator {
10
12
  this.nodeRepository = nodeRepository;
11
13
  this.nodeValidator = nodeValidator;
12
14
  this.currentWorkflow = null;
15
+ this.similarityService = new node_similarity_service_1.NodeSimilarityService(nodeRepository);
13
16
  }
14
17
  isStickyNote(node) {
15
18
  const stickyNoteTypes = [
@@ -116,7 +119,7 @@ class WorkflowValidator {
116
119
  }
117
120
  if (workflow.nodes.length === 1) {
118
121
  const singleNode = workflow.nodes[0];
119
- const normalizedType = singleNode.type.replace('n8n-nodes-base.', 'nodes-base.');
122
+ const normalizedType = (0, node_type_utils_1.normalizeNodeType)(singleNode.type);
120
123
  const isWebhook = normalizedType === 'nodes-base.webhook' ||
121
124
  normalizedType === 'nodes-base.webhookTrigger';
122
125
  if (!isWebhook) {
@@ -164,7 +167,7 @@ class WorkflowValidator {
164
167
  nodeIds.add(node.id);
165
168
  }
166
169
  const triggerNodes = workflow.nodes.filter(n => {
167
- const normalizedType = n.type.replace('n8n-nodes-base.', 'nodes-base.');
170
+ const normalizedType = (0, node_type_utils_1.normalizeNodeType)(n.type);
168
171
  return normalizedType.toLowerCase().includes('trigger') ||
169
172
  normalizedType.toLowerCase().includes('webhook') ||
170
173
  normalizedType === 'nodes-base.start' ||
@@ -224,47 +227,45 @@ class WorkflowValidator {
224
227
  }
225
228
  let nodeInfo = this.nodeRepository.getNode(node.type);
226
229
  if (!nodeInfo) {
227
- let normalizedType = node.type;
228
- if (node.type.startsWith('n8n-nodes-base.')) {
229
- normalizedType = node.type.replace('n8n-nodes-base.', 'nodes-base.');
230
- nodeInfo = this.nodeRepository.getNode(normalizedType);
231
- }
232
- else if (node.type.startsWith('@n8n/n8n-nodes-langchain.')) {
233
- normalizedType = node.type.replace('@n8n/n8n-nodes-langchain.', 'nodes-langchain.');
230
+ const normalizedType = (0, node_type_utils_1.normalizeNodeType)(node.type);
231
+ if (normalizedType !== node.type) {
234
232
  nodeInfo = this.nodeRepository.getNode(normalizedType);
235
233
  }
236
234
  }
237
235
  if (!nodeInfo) {
238
- let suggestion = '';
239
- if (node.type.startsWith('nodes-base.')) {
240
- const withPrefix = node.type.replace('nodes-base.', 'n8n-nodes-base.');
241
- const exists = this.nodeRepository.getNode(withPrefix) ||
242
- this.nodeRepository.getNode(withPrefix.replace('n8n-nodes-base.', 'nodes-base.'));
243
- if (exists) {
244
- suggestion = ` Did you mean "n8n-nodes-base.${node.type.substring(11)}"?`;
236
+ const suggestions = await this.similarityService.findSimilarNodes(node.type, 3);
237
+ let message = `Unknown node type: "${node.type}".`;
238
+ if (suggestions.length > 0) {
239
+ message += '\n\nDid you mean one of these?';
240
+ for (const suggestion of suggestions) {
241
+ const confidence = Math.round(suggestion.confidence * 100);
242
+ message += `\n• ${suggestion.nodeType} (${confidence}% match)`;
243
+ if (suggestion.displayName) {
244
+ message += ` - ${suggestion.displayName}`;
245
+ }
246
+ message += `\n → ${suggestion.reason}`;
247
+ if (suggestion.confidence >= 0.9) {
248
+ message += ' (can be auto-fixed)';
249
+ }
245
250
  }
246
251
  }
247
- else if (!node.type.includes('.')) {
248
- const commonNodes = [
249
- 'webhook', 'httpRequest', 'set', 'code', 'manualTrigger',
250
- 'scheduleTrigger', 'emailSend', 'slack', 'discord'
251
- ];
252
- if (commonNodes.includes(node.type)) {
253
- suggestion = ` Did you mean "n8n-nodes-base.${node.type}"?`;
254
- }
255
- }
256
- if (!suggestion) {
257
- const similarNodes = this.findSimilarNodeTypes(node.type);
258
- if (similarNodes.length > 0) {
259
- suggestion = ` Did you mean: ${similarNodes.map(n => `"${n}"`).join(', ')}?`;
260
- }
252
+ else {
253
+ message += ' No similar nodes found. Node types must include the package prefix (e.g., "n8n-nodes-base.webhook").';
261
254
  }
262
- result.errors.push({
255
+ const error = {
263
256
  type: 'error',
264
257
  nodeId: node.id,
265
258
  nodeName: node.name,
266
- message: `Unknown node type: "${node.type}".${suggestion} Node types must include the package prefix (e.g., "n8n-nodes-base.webhook", not "webhook" or "nodes-base.webhook").`
267
- });
259
+ message
260
+ };
261
+ if (suggestions.length > 0) {
262
+ error.suggestions = suggestions.map(s => ({
263
+ nodeType: s.nodeType,
264
+ confidence: s.confidence,
265
+ reason: s.reason
266
+ }));
267
+ }
268
+ result.errors.push(error);
268
269
  continue;
269
270
  }
270
271
  if (nodeInfo.isVersioned) {
@@ -388,7 +389,7 @@ class WorkflowValidator {
388
389
  for (const node of workflow.nodes) {
389
390
  if (node.disabled || this.isStickyNote(node))
390
391
  continue;
391
- const normalizedType = node.type.replace('n8n-nodes-base.', 'nodes-base.');
392
+ const normalizedType = (0, node_type_utils_1.normalizeNodeType)(node.type);
392
393
  const isTrigger = normalizedType.toLowerCase().includes('trigger') ||
393
394
  normalizedType.toLowerCase().includes('webhook') ||
394
395
  normalizedType === 'nodes-base.start' ||
@@ -539,13 +540,8 @@ class WorkflowValidator {
539
540
  validateAIToolConnection(sourceName, targetNode, result) {
540
541
  let targetNodeInfo = this.nodeRepository.getNode(targetNode.type);
541
542
  if (!targetNodeInfo) {
542
- let normalizedType = targetNode.type;
543
- if (targetNode.type.startsWith('n8n-nodes-base.')) {
544
- normalizedType = targetNode.type.replace('n8n-nodes-base.', 'nodes-base.');
545
- targetNodeInfo = this.nodeRepository.getNode(normalizedType);
546
- }
547
- else if (targetNode.type.startsWith('@n8n/n8n-nodes-langchain.')) {
548
- normalizedType = targetNode.type.replace('@n8n/n8n-nodes-langchain.', 'nodes-langchain.');
543
+ const normalizedType = (0, node_type_utils_1.normalizeNodeType)(targetNode.type);
544
+ if (normalizedType !== targetNode.type) {
549
545
  targetNodeInfo = this.nodeRepository.getNode(normalizedType);
550
546
  }
551
547
  }
@@ -805,54 +801,6 @@ class WorkflowValidator {
805
801
  }
806
802
  return maxChain;
807
803
  }
808
- findSimilarNodeTypes(invalidType) {
809
- const suggestions = [];
810
- const nodeName = invalidType.includes('.') ? invalidType.split('.').pop() : invalidType;
811
- const commonNodeMappings = {
812
- 'webhook': ['nodes-base.webhook'],
813
- 'httpRequest': ['nodes-base.httpRequest'],
814
- 'http': ['nodes-base.httpRequest'],
815
- 'set': ['nodes-base.set'],
816
- 'code': ['nodes-base.code'],
817
- 'manualTrigger': ['nodes-base.manualTrigger'],
818
- 'manual': ['nodes-base.manualTrigger'],
819
- 'scheduleTrigger': ['nodes-base.scheduleTrigger'],
820
- 'schedule': ['nodes-base.scheduleTrigger'],
821
- 'cron': ['nodes-base.scheduleTrigger'],
822
- 'emailSend': ['nodes-base.emailSend'],
823
- 'email': ['nodes-base.emailSend'],
824
- 'slack': ['nodes-base.slack'],
825
- 'discord': ['nodes-base.discord'],
826
- 'postgres': ['nodes-base.postgres'],
827
- 'mysql': ['nodes-base.mySql'],
828
- 'mongodb': ['nodes-base.mongoDb'],
829
- 'redis': ['nodes-base.redis'],
830
- 'if': ['nodes-base.if'],
831
- 'switch': ['nodes-base.switch'],
832
- 'merge': ['nodes-base.merge'],
833
- 'splitInBatches': ['nodes-base.splitInBatches'],
834
- 'loop': ['nodes-base.splitInBatches'],
835
- 'googleSheets': ['nodes-base.googleSheets'],
836
- 'sheets': ['nodes-base.googleSheets'],
837
- 'airtable': ['nodes-base.airtable'],
838
- 'github': ['nodes-base.github'],
839
- 'git': ['nodes-base.github'],
840
- };
841
- const lowerNodeName = nodeName.toLowerCase();
842
- if (commonNodeMappings[lowerNodeName]) {
843
- suggestions.push(...commonNodeMappings[lowerNodeName]);
844
- }
845
- Object.entries(commonNodeMappings).forEach(([key, values]) => {
846
- if (key.includes(lowerNodeName) || lowerNodeName.includes(key)) {
847
- values.forEach(v => {
848
- if (!suggestions.includes(v)) {
849
- suggestions.push(v);
850
- }
851
- });
852
- }
853
- });
854
- return suggestions.slice(0, 3);
855
- }
856
804
  generateSuggestions(workflow, result) {
857
805
  if (result.statistics.triggerNodes === 0) {
858
806
  result.suggestions.push('Add a trigger node (e.g., Webhook, Schedule Trigger) to automate workflow execution');