n8n-atom-mcp 0.0.1

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 (794) hide show
  1. package/.env.example +220 -0
  2. package/LICENSE +21 -0
  3. package/README.md +78 -0
  4. package/data/nodes.db +0 -0
  5. package/dist/community/community-node-fetcher.d.ts +118 -0
  6. package/dist/community/community-node-fetcher.d.ts.map +1 -0
  7. package/dist/community/community-node-fetcher.js +239 -0
  8. package/dist/community/community-node-fetcher.js.map +1 -0
  9. package/dist/community/community-node-service.d.ts +42 -0
  10. package/dist/community/community-node-service.d.ts.map +1 -0
  11. package/dist/community/community-node-service.js +210 -0
  12. package/dist/community/community-node-service.js.map +1 -0
  13. package/dist/community/documentation-batch-processor.d.ts +33 -0
  14. package/dist/community/documentation-batch-processor.d.ts.map +1 -0
  15. package/dist/community/documentation-batch-processor.js +156 -0
  16. package/dist/community/documentation-batch-processor.js.map +1 -0
  17. package/dist/community/documentation-generator.d.ts +65 -0
  18. package/dist/community/documentation-generator.d.ts.map +1 -0
  19. package/dist/community/documentation-generator.js +220 -0
  20. package/dist/community/documentation-generator.js.map +1 -0
  21. package/dist/community/index.d.ts +5 -0
  22. package/dist/community/index.d.ts.map +1 -0
  23. package/dist/community/index.js +14 -0
  24. package/dist/community/index.js.map +1 -0
  25. package/dist/config/n8n-api.d.ts +15 -0
  26. package/dist/config/n8n-api.d.ts.map +1 -0
  27. package/dist/config/n8n-api.js +53 -0
  28. package/dist/config/n8n-api.js.map +1 -0
  29. package/dist/constants/type-structures.d.ts +123 -0
  30. package/dist/constants/type-structures.d.ts.map +1 -0
  31. package/dist/constants/type-structures.js +654 -0
  32. package/dist/constants/type-structures.js.map +1 -0
  33. package/dist/database/database-adapter.d.ts +33 -0
  34. package/dist/database/database-adapter.d.ts.map +1 -0
  35. package/dist/database/database-adapter.js +420 -0
  36. package/dist/database/database-adapter.js.map +1 -0
  37. package/dist/database/node-repository.d.ts +152 -0
  38. package/dist/database/node-repository.d.ts.map +1 -0
  39. package/dist/database/node-repository.js +791 -0
  40. package/dist/database/node-repository.js.map +1 -0
  41. package/dist/errors/validation-service-error.d.ts +10 -0
  42. package/dist/errors/validation-service-error.d.ts.map +1 -0
  43. package/dist/errors/validation-service-error.js +26 -0
  44. package/dist/errors/validation-service-error.js.map +1 -0
  45. package/dist/http-server-single-session.d.ts +52 -0
  46. package/dist/http-server-single-session.d.ts.map +1 -0
  47. package/dist/http-server-single-session.js +1180 -0
  48. package/dist/http-server-single-session.js.map +1 -0
  49. package/dist/http-server.d.ts +9 -0
  50. package/dist/http-server.d.ts.map +1 -0
  51. package/dist/http-server.js +481 -0
  52. package/dist/http-server.js.map +1 -0
  53. package/dist/index.d.ts +11 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +20 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/loaders/node-loader.d.ts +11 -0
  58. package/dist/loaders/node-loader.d.ts.map +1 -0
  59. package/dist/loaders/node-loader.js +79 -0
  60. package/dist/loaders/node-loader.js.map +1 -0
  61. package/dist/mappers/docs-mapper.d.ts +7 -0
  62. package/dist/mappers/docs-mapper.d.ts.map +1 -0
  63. package/dist/mappers/docs-mapper.js +106 -0
  64. package/dist/mappers/docs-mapper.js.map +1 -0
  65. package/dist/mcp/handlers-n8n-manager.d.ts +58 -0
  66. package/dist/mcp/handlers-n8n-manager.d.ts.map +1 -0
  67. package/dist/mcp/handlers-n8n-manager.js +3299 -0
  68. package/dist/mcp/handlers-n8n-manager.js.map +1 -0
  69. package/dist/mcp/handlers-workflow-diff.d.ts +5 -0
  70. package/dist/mcp/handlers-workflow-diff.d.ts.map +1 -0
  71. package/dist/mcp/handlers-workflow-diff.js +461 -0
  72. package/dist/mcp/handlers-workflow-diff.js.map +1 -0
  73. package/dist/mcp/index.d.ts +3 -0
  74. package/dist/mcp/index.d.ts.map +1 -0
  75. package/dist/mcp/index.js +228 -0
  76. package/dist/mcp/index.js.map +1 -0
  77. package/dist/mcp/server.d.ts +82 -0
  78. package/dist/mcp/server.d.ts.map +1 -0
  79. package/dist/mcp/server.js +3006 -0
  80. package/dist/mcp/server.js.map +1 -0
  81. package/dist/mcp/stdio-wrapper.d.ts +3 -0
  82. package/dist/mcp/stdio-wrapper.d.ts.map +1 -0
  83. package/dist/mcp/stdio-wrapper.js +81 -0
  84. package/dist/mcp/stdio-wrapper.js.map +1 -0
  85. package/dist/mcp/tool-docs/configuration/get-node.d.ts +3 -0
  86. package/dist/mcp/tool-docs/configuration/get-node.d.ts.map +1 -0
  87. package/dist/mcp/tool-docs/configuration/get-node.js +90 -0
  88. package/dist/mcp/tool-docs/configuration/get-node.js.map +1 -0
  89. package/dist/mcp/tool-docs/configuration/index.d.ts +2 -0
  90. package/dist/mcp/tool-docs/configuration/index.d.ts.map +1 -0
  91. package/dist/mcp/tool-docs/configuration/index.js +6 -0
  92. package/dist/mcp/tool-docs/configuration/index.js.map +1 -0
  93. package/dist/mcp/tool-docs/discovery/index.d.ts +2 -0
  94. package/dist/mcp/tool-docs/discovery/index.d.ts.map +1 -0
  95. package/dist/mcp/tool-docs/discovery/index.js +6 -0
  96. package/dist/mcp/tool-docs/discovery/index.js.map +1 -0
  97. package/dist/mcp/tool-docs/discovery/search-nodes.d.ts +3 -0
  98. package/dist/mcp/tool-docs/discovery/search-nodes.d.ts.map +1 -0
  99. package/dist/mcp/tool-docs/discovery/search-nodes.js +70 -0
  100. package/dist/mcp/tool-docs/discovery/search-nodes.js.map +1 -0
  101. package/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts +3 -0
  102. package/dist/mcp/tool-docs/guides/ai-agents-guide.d.ts.map +1 -0
  103. package/dist/mcp/tool-docs/guides/ai-agents-guide.js +739 -0
  104. package/dist/mcp/tool-docs/guides/ai-agents-guide.js.map +1 -0
  105. package/dist/mcp/tool-docs/guides/index.d.ts +2 -0
  106. package/dist/mcp/tool-docs/guides/index.d.ts.map +1 -0
  107. package/dist/mcp/tool-docs/guides/index.js +6 -0
  108. package/dist/mcp/tool-docs/guides/index.js.map +1 -0
  109. package/dist/mcp/tool-docs/index.d.ts +4 -0
  110. package/dist/mcp/tool-docs/index.d.ts.map +1 -0
  111. package/dist/mcp/tool-docs/index.js +34 -0
  112. package/dist/mcp/tool-docs/index.js.map +1 -0
  113. package/dist/mcp/tool-docs/system/index.d.ts +3 -0
  114. package/dist/mcp/tool-docs/system/index.d.ts.map +1 -0
  115. package/dist/mcp/tool-docs/system/index.js +8 -0
  116. package/dist/mcp/tool-docs/system/index.js.map +1 -0
  117. package/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts +3 -0
  118. package/dist/mcp/tool-docs/system/n8n-diagnostic.d.ts.map +1 -0
  119. package/dist/mcp/tool-docs/system/n8n-diagnostic.js +99 -0
  120. package/dist/mcp/tool-docs/system/n8n-diagnostic.js.map +1 -0
  121. package/dist/mcp/tool-docs/system/n8n-health-check.d.ts +3 -0
  122. package/dist/mcp/tool-docs/system/n8n-health-check.d.ts.map +1 -0
  123. package/dist/mcp/tool-docs/system/n8n-health-check.js +102 -0
  124. package/dist/mcp/tool-docs/system/n8n-health-check.js.map +1 -0
  125. package/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts +3 -0
  126. package/dist/mcp/tool-docs/system/n8n-list-available-tools.d.ts.map +1 -0
  127. package/dist/mcp/tool-docs/system/n8n-list-available-tools.js +75 -0
  128. package/dist/mcp/tool-docs/system/n8n-list-available-tools.js.map +1 -0
  129. package/dist/mcp/tool-docs/system/tools-documentation.d.ts +3 -0
  130. package/dist/mcp/tool-docs/system/tools-documentation.d.ts.map +1 -0
  131. package/dist/mcp/tool-docs/system/tools-documentation.js +65 -0
  132. package/dist/mcp/tool-docs/system/tools-documentation.js.map +1 -0
  133. package/dist/mcp/tool-docs/templates/get-template.d.ts +3 -0
  134. package/dist/mcp/tool-docs/templates/get-template.d.ts.map +1 -0
  135. package/dist/mcp/tool-docs/templates/get-template.js +84 -0
  136. package/dist/mcp/tool-docs/templates/get-template.js.map +1 -0
  137. package/dist/mcp/tool-docs/templates/index.d.ts +3 -0
  138. package/dist/mcp/tool-docs/templates/index.d.ts.map +1 -0
  139. package/dist/mcp/tool-docs/templates/index.js +8 -0
  140. package/dist/mcp/tool-docs/templates/index.js.map +1 -0
  141. package/dist/mcp/tool-docs/templates/search-templates.d.ts +3 -0
  142. package/dist/mcp/tool-docs/templates/search-templates.d.ts.map +1 -0
  143. package/dist/mcp/tool-docs/templates/search-templates.js +143 -0
  144. package/dist/mcp/tool-docs/templates/search-templates.js.map +1 -0
  145. package/dist/mcp/tool-docs/types.d.ts +32 -0
  146. package/dist/mcp/tool-docs/types.d.ts.map +1 -0
  147. package/dist/mcp/tool-docs/types.js +3 -0
  148. package/dist/mcp/tool-docs/types.js.map +1 -0
  149. package/dist/mcp/tool-docs/validation/index.d.ts +3 -0
  150. package/dist/mcp/tool-docs/validation/index.d.ts.map +1 -0
  151. package/dist/mcp/tool-docs/validation/index.js +8 -0
  152. package/dist/mcp/tool-docs/validation/index.js.map +1 -0
  153. package/dist/mcp/tool-docs/validation/validate-node.d.ts +3 -0
  154. package/dist/mcp/tool-docs/validation/validate-node.d.ts.map +1 -0
  155. package/dist/mcp/tool-docs/validation/validate-node.js +82 -0
  156. package/dist/mcp/tool-docs/validation/validate-node.js.map +1 -0
  157. package/dist/mcp/tool-docs/validation/validate-workflow.d.ts +3 -0
  158. package/dist/mcp/tool-docs/validation/validate-workflow.d.ts.map +1 -0
  159. package/dist/mcp/tool-docs/validation/validate-workflow.js +86 -0
  160. package/dist/mcp/tool-docs/validation/validate-workflow.js.map +1 -0
  161. package/dist/mcp/tool-docs/workflow_management/index.d.ts +13 -0
  162. package/dist/mcp/tool-docs/workflow_management/index.d.ts.map +1 -0
  163. package/dist/mcp/tool-docs/workflow_management/index.js +28 -0
  164. package/dist/mcp/tool-docs/workflow_management/index.js.map +1 -0
  165. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts +3 -0
  166. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.d.ts.map +1 -0
  167. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js +162 -0
  168. package/dist/mcp/tool-docs/workflow_management/n8n-autofix-workflow.js.map +1 -0
  169. package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts +3 -0
  170. package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.d.ts.map +1 -0
  171. package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js +102 -0
  172. package/dist/mcp/tool-docs/workflow_management/n8n-create-workflow.js.map +1 -0
  173. package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts +3 -0
  174. package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.d.ts.map +1 -0
  175. package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js +52 -0
  176. package/dist/mcp/tool-docs/workflow_management/n8n-delete-workflow.js.map +1 -0
  177. package/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts +3 -0
  178. package/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.d.ts.map +1 -0
  179. package/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js +73 -0
  180. package/dist/mcp/tool-docs/workflow_management/n8n-deploy-template.js.map +1 -0
  181. package/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts +3 -0
  182. package/dist/mcp/tool-docs/workflow_management/n8n-executions.d.ts.map +1 -0
  183. package/dist/mcp/tool-docs/workflow_management/n8n-executions.js +109 -0
  184. package/dist/mcp/tool-docs/workflow_management/n8n-executions.js.map +1 -0
  185. package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts +3 -0
  186. package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.d.ts.map +1 -0
  187. package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js +68 -0
  188. package/dist/mcp/tool-docs/workflow_management/n8n-get-workflow.js.map +1 -0
  189. package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts +3 -0
  190. package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.d.ts.map +1 -0
  191. package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js +57 -0
  192. package/dist/mcp/tool-docs/workflow_management/n8n-list-workflows.js.map +1 -0
  193. package/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts +3 -0
  194. package/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.d.ts.map +1 -0
  195. package/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js +140 -0
  196. package/dist/mcp/tool-docs/workflow_management/n8n-test-workflow.js.map +1 -0
  197. package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts +3 -0
  198. package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.d.ts.map +1 -0
  199. package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js +61 -0
  200. package/dist/mcp/tool-docs/workflow_management/n8n-update-full-workflow.js.map +1 -0
  201. package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts +3 -0
  202. package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.d.ts.map +1 -0
  203. package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js +420 -0
  204. package/dist/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.js.map +1 -0
  205. package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts +3 -0
  206. package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.d.ts.map +1 -0
  207. package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js +73 -0
  208. package/dist/mcp/tool-docs/workflow_management/n8n-validate-workflow.js.map +1 -0
  209. package/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts +3 -0
  210. package/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.d.ts.map +1 -0
  211. package/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js +170 -0
  212. package/dist/mcp/tool-docs/workflow_management/n8n-workflow-versions.js.map +1 -0
  213. package/dist/mcp/tools-documentation.d.ts +6 -0
  214. package/dist/mcp/tools-documentation.d.ts.map +1 -0
  215. package/dist/mcp/tools-documentation.js +682 -0
  216. package/dist/mcp/tools-documentation.js.map +1 -0
  217. package/dist/mcp/tools-file-operations.d.ts +154 -0
  218. package/dist/mcp/tools-file-operations.d.ts.map +1 -0
  219. package/dist/mcp/tools-file-operations.js +213 -0
  220. package/dist/mcp/tools-file-operations.js.map +1 -0
  221. package/dist/mcp/tools-n8n-friendly.d.ts +6 -0
  222. package/dist/mcp/tools-n8n-friendly.d.ts.map +1 -0
  223. package/dist/mcp/tools-n8n-friendly.js +89 -0
  224. package/dist/mcp/tools-n8n-friendly.js.map +1 -0
  225. package/dist/mcp/tools-n8n-manager.d.ts +3 -0
  226. package/dist/mcp/tools-n8n-manager.d.ts.map +1 -0
  227. package/dist/mcp/tools-n8n-manager.js +1320 -0
  228. package/dist/mcp/tools-n8n-manager.js.map +1 -0
  229. package/dist/mcp/tools.d.ts +3 -0
  230. package/dist/mcp/tools.d.ts.map +1 -0
  231. package/dist/mcp/tools.js +424 -0
  232. package/dist/mcp/tools.js.map +1 -0
  233. package/dist/mcp/workflow-examples.d.ts +76 -0
  234. package/dist/mcp/workflow-examples.d.ts.map +1 -0
  235. package/dist/mcp/workflow-examples.js +111 -0
  236. package/dist/mcp/workflow-examples.js.map +1 -0
  237. package/dist/mcp-engine.d.ts +36 -0
  238. package/dist/mcp-engine.d.ts.map +1 -0
  239. package/dist/mcp-engine.js +77 -0
  240. package/dist/mcp-engine.js.map +1 -0
  241. package/dist/mcp-tools-engine.d.ts +47 -0
  242. package/dist/mcp-tools-engine.d.ts.map +1 -0
  243. package/dist/mcp-tools-engine.js +89 -0
  244. package/dist/mcp-tools-engine.js.map +1 -0
  245. package/dist/n8n/MCPApi.credentials.d.ts +8 -0
  246. package/dist/n8n/MCPApi.credentials.d.ts.map +1 -0
  247. package/dist/n8n/MCPApi.credentials.js +53 -0
  248. package/dist/n8n/MCPApi.credentials.js.map +1 -0
  249. package/dist/n8n/MCPNode.node.d.ts +13 -0
  250. package/dist/n8n/MCPNode.node.d.ts.map +1 -0
  251. package/dist/n8n/MCPNode.node.js +260 -0
  252. package/dist/n8n/MCPNode.node.js.map +1 -0
  253. package/dist/parsers/node-parser.d.ts +38 -0
  254. package/dist/parsers/node-parser.d.ts.map +1 -0
  255. package/dist/parsers/node-parser.js +250 -0
  256. package/dist/parsers/node-parser.js.map +1 -0
  257. package/dist/parsers/property-extractor.d.ts +11 -0
  258. package/dist/parsers/property-extractor.d.ts.map +1 -0
  259. package/dist/parsers/property-extractor.js +172 -0
  260. package/dist/parsers/property-extractor.js.map +1 -0
  261. package/dist/parsers/simple-parser.d.ts +25 -0
  262. package/dist/parsers/simple-parser.d.ts.map +1 -0
  263. package/dist/parsers/simple-parser.js +212 -0
  264. package/dist/parsers/simple-parser.js.map +1 -0
  265. package/dist/scripts/debug-http-search.d.ts +3 -0
  266. package/dist/scripts/debug-http-search.d.ts.map +1 -0
  267. package/dist/scripts/debug-http-search.js +57 -0
  268. package/dist/scripts/debug-http-search.js.map +1 -0
  269. package/dist/scripts/extract-from-docker.d.ts +3 -0
  270. package/dist/scripts/extract-from-docker.d.ts.map +1 -0
  271. package/dist/scripts/extract-from-docker.js +210 -0
  272. package/dist/scripts/extract-from-docker.js.map +1 -0
  273. package/dist/scripts/fetch-community-nodes.d.ts +3 -0
  274. package/dist/scripts/fetch-community-nodes.d.ts.map +1 -0
  275. package/dist/scripts/fetch-community-nodes.js +114 -0
  276. package/dist/scripts/fetch-community-nodes.js.map +1 -0
  277. package/dist/scripts/fetch-templates-robust.d.ts +4 -0
  278. package/dist/scripts/fetch-templates-robust.d.ts.map +1 -0
  279. package/dist/scripts/fetch-templates-robust.js +132 -0
  280. package/dist/scripts/fetch-templates-robust.js.map +1 -0
  281. package/dist/scripts/fetch-templates.d.ts +4 -0
  282. package/dist/scripts/fetch-templates.d.ts.map +1 -0
  283. package/dist/scripts/fetch-templates.js +411 -0
  284. package/dist/scripts/fetch-templates.js.map +1 -0
  285. package/dist/scripts/generate-community-docs.d.ts +3 -0
  286. package/dist/scripts/generate-community-docs.d.ts.map +1 -0
  287. package/dist/scripts/generate-community-docs.js +183 -0
  288. package/dist/scripts/generate-community-docs.js.map +1 -0
  289. package/dist/scripts/migrate-readme-columns.d.ts +2 -0
  290. package/dist/scripts/migrate-readme-columns.d.ts.map +1 -0
  291. package/dist/scripts/migrate-readme-columns.js +62 -0
  292. package/dist/scripts/migrate-readme-columns.js.map +1 -0
  293. package/dist/scripts/rebuild-database.d.ts +4 -0
  294. package/dist/scripts/rebuild-database.d.ts.map +1 -0
  295. package/dist/scripts/rebuild-database.js +95 -0
  296. package/dist/scripts/rebuild-database.js.map +1 -0
  297. package/dist/scripts/rebuild-optimized.d.ts +3 -0
  298. package/dist/scripts/rebuild-optimized.d.ts.map +1 -0
  299. package/dist/scripts/rebuild-optimized.js +198 -0
  300. package/dist/scripts/rebuild-optimized.js.map +1 -0
  301. package/dist/scripts/rebuild.d.ts +3 -0
  302. package/dist/scripts/rebuild.d.ts.map +1 -0
  303. package/dist/scripts/rebuild.js +258 -0
  304. package/dist/scripts/rebuild.js.map +1 -0
  305. package/dist/scripts/sanitize-templates.d.ts +3 -0
  306. package/dist/scripts/sanitize-templates.d.ts.map +1 -0
  307. package/dist/scripts/sanitize-templates.js +88 -0
  308. package/dist/scripts/sanitize-templates.js.map +1 -0
  309. package/dist/scripts/seed-canonical-ai-examples.d.ts +4 -0
  310. package/dist/scripts/seed-canonical-ai-examples.d.ts.map +1 -0
  311. package/dist/scripts/seed-canonical-ai-examples.js +121 -0
  312. package/dist/scripts/seed-canonical-ai-examples.js.map +1 -0
  313. package/dist/scripts/test-autofix-documentation.d.ts +3 -0
  314. package/dist/scripts/test-autofix-documentation.d.ts.map +1 -0
  315. package/dist/scripts/test-autofix-documentation.js +103 -0
  316. package/dist/scripts/test-autofix-documentation.js.map +1 -0
  317. package/dist/scripts/test-autofix-workflow.d.ts +2 -0
  318. package/dist/scripts/test-autofix-workflow.d.ts.map +1 -0
  319. package/dist/scripts/test-autofix-workflow.js +223 -0
  320. package/dist/scripts/test-autofix-workflow.js.map +1 -0
  321. package/dist/scripts/test-execution-filtering.d.ts +3 -0
  322. package/dist/scripts/test-execution-filtering.d.ts.map +1 -0
  323. package/dist/scripts/test-execution-filtering.js +206 -0
  324. package/dist/scripts/test-execution-filtering.js.map +1 -0
  325. package/dist/scripts/test-node-suggestions.d.ts +3 -0
  326. package/dist/scripts/test-node-suggestions.d.ts.map +1 -0
  327. package/dist/scripts/test-node-suggestions.js +165 -0
  328. package/dist/scripts/test-node-suggestions.js.map +1 -0
  329. package/dist/scripts/test-protocol-negotiation.d.ts +3 -0
  330. package/dist/scripts/test-protocol-negotiation.d.ts.map +1 -0
  331. package/dist/scripts/test-protocol-negotiation.js +154 -0
  332. package/dist/scripts/test-protocol-negotiation.js.map +1 -0
  333. package/dist/scripts/test-summary.d.ts +3 -0
  334. package/dist/scripts/test-summary.d.ts.map +1 -0
  335. package/dist/scripts/test-summary.js +77 -0
  336. package/dist/scripts/test-summary.js.map +1 -0
  337. package/dist/scripts/test-telemetry-mutations-verbose.d.ts +2 -0
  338. package/dist/scripts/test-telemetry-mutations-verbose.d.ts.map +1 -0
  339. package/dist/scripts/test-telemetry-mutations-verbose.js +133 -0
  340. package/dist/scripts/test-telemetry-mutations-verbose.js.map +1 -0
  341. package/dist/scripts/test-telemetry-mutations.d.ts +2 -0
  342. package/dist/scripts/test-telemetry-mutations.d.ts.map +1 -0
  343. package/dist/scripts/test-telemetry-mutations.js +129 -0
  344. package/dist/scripts/test-telemetry-mutations.js.map +1 -0
  345. package/dist/scripts/test-webhook-autofix.d.ts +3 -0
  346. package/dist/scripts/test-webhook-autofix.d.ts.map +1 -0
  347. package/dist/scripts/test-webhook-autofix.js +117 -0
  348. package/dist/scripts/test-webhook-autofix.js.map +1 -0
  349. package/dist/scripts/validate.d.ts +3 -0
  350. package/dist/scripts/validate.d.ts.map +1 -0
  351. package/dist/scripts/validate.js +121 -0
  352. package/dist/scripts/validate.js.map +1 -0
  353. package/dist/scripts/validation-summary.d.ts +3 -0
  354. package/dist/scripts/validation-summary.d.ts.map +1 -0
  355. package/dist/scripts/validation-summary.js +135 -0
  356. package/dist/scripts/validation-summary.js.map +1 -0
  357. package/dist/services/ai-node-validator.d.ts +12 -0
  358. package/dist/services/ai-node-validator.d.ts.map +1 -0
  359. package/dist/services/ai-node-validator.js +429 -0
  360. package/dist/services/ai-node-validator.js.map +1 -0
  361. package/dist/services/ai-tool-validators.d.ts +58 -0
  362. package/dist/services/ai-tool-validators.d.ts.map +1 -0
  363. package/dist/services/ai-tool-validators.js +438 -0
  364. package/dist/services/ai-tool-validators.js.map +1 -0
  365. package/dist/services/breaking-change-detector.d.ts +38 -0
  366. package/dist/services/breaking-change-detector.d.ts.map +1 -0
  367. package/dist/services/breaking-change-detector.js +184 -0
  368. package/dist/services/breaking-change-detector.js.map +1 -0
  369. package/dist/services/breaking-changes-registry.d.ts +28 -0
  370. package/dist/services/breaking-changes-registry.d.ts.map +1 -0
  371. package/dist/services/breaking-changes-registry.js +200 -0
  372. package/dist/services/breaking-changes-registry.js.map +1 -0
  373. package/dist/services/community-package-service.d.ts +69 -0
  374. package/dist/services/community-package-service.d.ts.map +1 -0
  375. package/dist/services/community-package-service.js +202 -0
  376. package/dist/services/community-package-service.js.map +1 -0
  377. package/dist/services/confidence-scorer.d.ts +24 -0
  378. package/dist/services/confidence-scorer.d.ts.map +1 -0
  379. package/dist/services/confidence-scorer.js +139 -0
  380. package/dist/services/confidence-scorer.js.map +1 -0
  381. package/dist/services/config-validator.d.ts +49 -0
  382. package/dist/services/config-validator.d.ts.map +1 -0
  383. package/dist/services/config-validator.js +724 -0
  384. package/dist/services/config-validator.js.map +1 -0
  385. package/dist/services/enhanced-config-validator.d.ts +54 -0
  386. package/dist/services/enhanced-config-validator.d.ts.map +1 -0
  387. package/dist/services/enhanced-config-validator.js +789 -0
  388. package/dist/services/enhanced-config-validator.js.map +1 -0
  389. package/dist/services/error-execution-processor.d.ts +9 -0
  390. package/dist/services/error-execution-processor.d.ts.map +1 -0
  391. package/dist/services/error-execution-processor.js +380 -0
  392. package/dist/services/error-execution-processor.js.map +1 -0
  393. package/dist/services/example-generator.d.ts +14 -0
  394. package/dist/services/example-generator.d.ts.map +1 -0
  395. package/dist/services/example-generator.js +970 -0
  396. package/dist/services/example-generator.js.map +1 -0
  397. package/dist/services/execution-processor.d.ts +8 -0
  398. package/dist/services/execution-processor.d.ts.map +1 -0
  399. package/dist/services/execution-processor.js +381 -0
  400. package/dist/services/execution-processor.js.map +1 -0
  401. package/dist/services/expression-format-validator.d.ts +33 -0
  402. package/dist/services/expression-format-validator.d.ts.map +1 -0
  403. package/dist/services/expression-format-validator.js +209 -0
  404. package/dist/services/expression-format-validator.js.map +1 -0
  405. package/dist/services/expression-validator.d.ts +27 -0
  406. package/dist/services/expression-validator.d.ts.map +1 -0
  407. package/dist/services/expression-validator.js +187 -0
  408. package/dist/services/expression-validator.js.map +1 -0
  409. package/dist/services/installed-node-sync-service.d.ts +32 -0
  410. package/dist/services/installed-node-sync-service.d.ts.map +1 -0
  411. package/dist/services/installed-node-sync-service.js +190 -0
  412. package/dist/services/installed-node-sync-service.js.map +1 -0
  413. package/dist/services/n8n-api-client.d.ts +48 -0
  414. package/dist/services/n8n-api-client.d.ts.map +1 -0
  415. package/dist/services/n8n-api-client.js +458 -0
  416. package/dist/services/n8n-api-client.js.map +1 -0
  417. package/dist/services/n8n-file-format.d.ts +58 -0
  418. package/dist/services/n8n-file-format.d.ts.map +1 -0
  419. package/dist/services/n8n-file-format.js +203 -0
  420. package/dist/services/n8n-file-format.js.map +1 -0
  421. package/dist/services/n8n-validation.d.ts +273 -0
  422. package/dist/services/n8n-validation.d.ts.map +1 -0
  423. package/dist/services/n8n-validation.js +491 -0
  424. package/dist/services/n8n-validation.js.map +1 -0
  425. package/dist/services/n8n-version.d.ts +23 -0
  426. package/dist/services/n8n-version.d.ts.map +1 -0
  427. package/dist/services/n8n-version.js +151 -0
  428. package/dist/services/n8n-version.js.map +1 -0
  429. package/dist/services/node-documentation-service.d.ts +70 -0
  430. package/dist/services/node-documentation-service.d.ts.map +1 -0
  431. package/dist/services/node-documentation-service.js +518 -0
  432. package/dist/services/node-documentation-service.js.map +1 -0
  433. package/dist/services/node-migration-service.d.ts +44 -0
  434. package/dist/services/node-migration-service.d.ts.map +1 -0
  435. package/dist/services/node-migration-service.js +231 -0
  436. package/dist/services/node-migration-service.js.map +1 -0
  437. package/dist/services/node-sanitizer.d.ts +5 -0
  438. package/dist/services/node-sanitizer.d.ts.map +1 -0
  439. package/dist/services/node-sanitizer.js +225 -0
  440. package/dist/services/node-sanitizer.js.map +1 -0
  441. package/dist/services/node-similarity-service.d.ts +51 -0
  442. package/dist/services/node-similarity-service.d.ts.map +1 -0
  443. package/dist/services/node-similarity-service.js +352 -0
  444. package/dist/services/node-similarity-service.js.map +1 -0
  445. package/dist/services/node-specific-validators.d.ts +37 -0
  446. package/dist/services/node-specific-validators.d.ts.map +1 -0
  447. package/dist/services/node-specific-validators.js +1331 -0
  448. package/dist/services/node-specific-validators.js.map +1 -0
  449. package/dist/services/node-version-service.d.ts +63 -0
  450. package/dist/services/node-version-service.d.ts.map +1 -0
  451. package/dist/services/node-version-service.js +215 -0
  452. package/dist/services/node-version-service.js.map +1 -0
  453. package/dist/services/operation-similarity-service.d.ts +32 -0
  454. package/dist/services/operation-similarity-service.d.ts.map +1 -0
  455. package/dist/services/operation-similarity-service.js +341 -0
  456. package/dist/services/operation-similarity-service.js.map +1 -0
  457. package/dist/services/post-update-validator.d.ts +59 -0
  458. package/dist/services/post-update-validator.d.ts.map +1 -0
  459. package/dist/services/post-update-validator.js +231 -0
  460. package/dist/services/post-update-validator.js.map +1 -0
  461. package/dist/services/property-dependencies.d.ts +36 -0
  462. package/dist/services/property-dependencies.d.ts.map +1 -0
  463. package/dist/services/property-dependencies.js +168 -0
  464. package/dist/services/property-dependencies.js.map +1 -0
  465. package/dist/services/property-filter.d.ts +44 -0
  466. package/dist/services/property-filter.d.ts.map +1 -0
  467. package/dist/services/property-filter.js +395 -0
  468. package/dist/services/property-filter.js.map +1 -0
  469. package/dist/services/resource-similarity-service.d.ts +33 -0
  470. package/dist/services/resource-similarity-service.d.ts.map +1 -0
  471. package/dist/services/resource-similarity-service.js +358 -0
  472. package/dist/services/resource-similarity-service.js.map +1 -0
  473. package/dist/services/sqlite-storage-service.d.ts +11 -0
  474. package/dist/services/sqlite-storage-service.d.ts.map +1 -0
  475. package/dist/services/sqlite-storage-service.js +74 -0
  476. package/dist/services/sqlite-storage-service.js.map +1 -0
  477. package/dist/services/task-templates.d.ts +27 -0
  478. package/dist/services/task-templates.d.ts.map +1 -0
  479. package/dist/services/task-templates.js +1397 -0
  480. package/dist/services/task-templates.js.map +1 -0
  481. package/dist/services/tool-variant-generator.d.ts +10 -0
  482. package/dist/services/tool-variant-generator.d.ts.map +1 -0
  483. package/dist/services/tool-variant-generator.js +93 -0
  484. package/dist/services/tool-variant-generator.js.map +1 -0
  485. package/dist/services/type-structure-service.d.ts +23 -0
  486. package/dist/services/type-structure-service.d.ts.map +1 -0
  487. package/dist/services/type-structure-service.js +109 -0
  488. package/dist/services/type-structure-service.js.map +1 -0
  489. package/dist/services/universal-expression-validator.d.ts +20 -0
  490. package/dist/services/universal-expression-validator.d.ts.map +1 -0
  491. package/dist/services/universal-expression-validator.js +192 -0
  492. package/dist/services/universal-expression-validator.js.map +1 -0
  493. package/dist/services/workflow-analytics-service.d.ts +34 -0
  494. package/dist/services/workflow-analytics-service.d.ts.map +1 -0
  495. package/dist/services/workflow-analytics-service.js +144 -0
  496. package/dist/services/workflow-analytics-service.js.map +1 -0
  497. package/dist/services/workflow-auto-fixer.d.ts +74 -0
  498. package/dist/services/workflow-auto-fixer.d.ts.map +1 -0
  499. package/dist/services/workflow-auto-fixer.js +557 -0
  500. package/dist/services/workflow-auto-fixer.js.map +1 -0
  501. package/dist/services/workflow-comparison.d.ts +13 -0
  502. package/dist/services/workflow-comparison.d.ts.map +1 -0
  503. package/dist/services/workflow-comparison.js +306 -0
  504. package/dist/services/workflow-comparison.js.map +1 -0
  505. package/dist/services/workflow-debugging-service.d.ts +62 -0
  506. package/dist/services/workflow-debugging-service.d.ts.map +1 -0
  507. package/dist/services/workflow-debugging-service.js +153 -0
  508. package/dist/services/workflow-debugging-service.js.map +1 -0
  509. package/dist/services/workflow-diff-engine.d.ts +45 -0
  510. package/dist/services/workflow-diff-engine.d.ts.map +1 -0
  511. package/dist/services/workflow-diff-engine.js +830 -0
  512. package/dist/services/workflow-diff-engine.js.map +1 -0
  513. package/dist/services/workflow-validator.d.ts +112 -0
  514. package/dist/services/workflow-validator.d.ts.map +1 -0
  515. package/dist/services/workflow-validator.js +1328 -0
  516. package/dist/services/workflow-validator.js.map +1 -0
  517. package/dist/services/workflow-versioning-service.d.ts +102 -0
  518. package/dist/services/workflow-versioning-service.d.ts.map +1 -0
  519. package/dist/services/workflow-versioning-service.js +264 -0
  520. package/dist/services/workflow-versioning-service.js.map +1 -0
  521. package/dist/telemetry/batch-processor.d.ts +34 -0
  522. package/dist/telemetry/batch-processor.d.ts.map +1 -0
  523. package/dist/telemetry/batch-processor.js +337 -0
  524. package/dist/telemetry/batch-processor.js.map +1 -0
  525. package/dist/telemetry/config-manager.d.ts +32 -0
  526. package/dist/telemetry/config-manager.d.ts.map +1 -0
  527. package/dist/telemetry/config-manager.js +289 -0
  528. package/dist/telemetry/config-manager.js.map +1 -0
  529. package/dist/telemetry/early-error-logger.d.ts +26 -0
  530. package/dist/telemetry/early-error-logger.d.ts.map +1 -0
  531. package/dist/telemetry/early-error-logger.js +187 -0
  532. package/dist/telemetry/early-error-logger.js.map +1 -0
  533. package/dist/telemetry/error-sanitization-utils.d.ts +2 -0
  534. package/dist/telemetry/error-sanitization-utils.d.ts.map +1 -0
  535. package/dist/telemetry/error-sanitization-utils.js +37 -0
  536. package/dist/telemetry/error-sanitization-utils.js.map +1 -0
  537. package/dist/telemetry/error-sanitizer.d.ts +4 -0
  538. package/dist/telemetry/error-sanitizer.d.ts.map +1 -0
  539. package/dist/telemetry/error-sanitizer.js +45 -0
  540. package/dist/telemetry/error-sanitizer.js.map +1 -0
  541. package/dist/telemetry/event-tracker.d.ts +71 -0
  542. package/dist/telemetry/event-tracker.d.ts.map +1 -0
  543. package/dist/telemetry/event-tracker.js +356 -0
  544. package/dist/telemetry/event-tracker.js.map +1 -0
  545. package/dist/telemetry/event-validator.d.ts +78 -0
  546. package/dist/telemetry/event-validator.d.ts.map +1 -0
  547. package/dist/telemetry/event-validator.js +227 -0
  548. package/dist/telemetry/event-validator.js.map +1 -0
  549. package/dist/telemetry/index.d.ts +5 -0
  550. package/dist/telemetry/index.d.ts.map +1 -0
  551. package/dist/telemetry/index.js +11 -0
  552. package/dist/telemetry/index.js.map +1 -0
  553. package/dist/telemetry/intent-classifier.d.ts +11 -0
  554. package/dist/telemetry/intent-classifier.d.ts.map +1 -0
  555. package/dist/telemetry/intent-classifier.js +141 -0
  556. package/dist/telemetry/intent-classifier.js.map +1 -0
  557. package/dist/telemetry/intent-sanitizer.d.ts +9 -0
  558. package/dist/telemetry/intent-sanitizer.d.ts.map +1 -0
  559. package/dist/telemetry/intent-sanitizer.js +103 -0
  560. package/dist/telemetry/intent-sanitizer.js.map +1 -0
  561. package/dist/telemetry/mutation-tracker.d.ts +15 -0
  562. package/dist/telemetry/mutation-tracker.d.ts.map +1 -0
  563. package/dist/telemetry/mutation-tracker.js +177 -0
  564. package/dist/telemetry/mutation-tracker.js.map +1 -0
  565. package/dist/telemetry/mutation-types.d.ts +106 -0
  566. package/dist/telemetry/mutation-types.d.ts.map +1 -0
  567. package/dist/telemetry/mutation-types.js +18 -0
  568. package/dist/telemetry/mutation-types.js.map +1 -0
  569. package/dist/telemetry/mutation-validator.d.ts +20 -0
  570. package/dist/telemetry/mutation-validator.d.ts.map +1 -0
  571. package/dist/telemetry/mutation-validator.js +144 -0
  572. package/dist/telemetry/mutation-validator.js.map +1 -0
  573. package/dist/telemetry/performance-monitor.d.ts +113 -0
  574. package/dist/telemetry/performance-monitor.d.ts.map +1 -0
  575. package/dist/telemetry/performance-monitor.js +208 -0
  576. package/dist/telemetry/performance-monitor.js.map +1 -0
  577. package/dist/telemetry/rate-limiter.d.ts +30 -0
  578. package/dist/telemetry/rate-limiter.d.ts.map +1 -0
  579. package/dist/telemetry/rate-limiter.js +103 -0
  580. package/dist/telemetry/rate-limiter.js.map +1 -0
  581. package/dist/telemetry/startup-checkpoints.d.ts +26 -0
  582. package/dist/telemetry/startup-checkpoints.d.ts.map +1 -0
  583. package/dist/telemetry/startup-checkpoints.js +65 -0
  584. package/dist/telemetry/startup-checkpoints.js.map +1 -0
  585. package/dist/telemetry/telemetry-error.d.ts +44 -0
  586. package/dist/telemetry/telemetry-error.d.ts.map +1 -0
  587. package/dist/telemetry/telemetry-error.js +153 -0
  588. package/dist/telemetry/telemetry-error.js.map +1 -0
  589. package/dist/telemetry/telemetry-manager.d.ts +130 -0
  590. package/dist/telemetry/telemetry-manager.d.ts.map +1 -0
  591. package/dist/telemetry/telemetry-manager.js +257 -0
  592. package/dist/telemetry/telemetry-manager.js.map +1 -0
  593. package/dist/telemetry/telemetry-types.d.ts +103 -0
  594. package/dist/telemetry/telemetry-types.d.ts.map +1 -0
  595. package/dist/telemetry/telemetry-types.js +29 -0
  596. package/dist/telemetry/telemetry-types.js.map +1 -0
  597. package/dist/telemetry/workflow-sanitizer.d.ts +34 -0
  598. package/dist/telemetry/workflow-sanitizer.d.ts.map +1 -0
  599. package/dist/telemetry/workflow-sanitizer.js +242 -0
  600. package/dist/telemetry/workflow-sanitizer.js.map +1 -0
  601. package/dist/templates/batch-processor.d.ts +35 -0
  602. package/dist/templates/batch-processor.d.ts.map +1 -0
  603. package/dist/templates/batch-processor.js +320 -0
  604. package/dist/templates/batch-processor.js.map +1 -0
  605. package/dist/templates/metadata-generator.d.ts +52 -0
  606. package/dist/templates/metadata-generator.d.ts.map +1 -0
  607. package/dist/templates/metadata-generator.js +252 -0
  608. package/dist/templates/metadata-generator.js.map +1 -0
  609. package/dist/templates/template-fetcher.d.ts +45 -0
  610. package/dist/templates/template-fetcher.d.ts.map +1 -0
  611. package/dist/templates/template-fetcher.js +122 -0
  612. package/dist/templates/template-fetcher.js.map +1 -0
  613. package/dist/templates/template-repository.d.ts +93 -0
  614. package/dist/templates/template-repository.d.ts.map +1 -0
  615. package/dist/templates/template-repository.js +644 -0
  616. package/dist/templates/template-repository.js.map +1 -0
  617. package/dist/templates/template-service.d.ts +79 -0
  618. package/dist/templates/template-service.d.ts.map +1 -0
  619. package/dist/templates/template-service.js +300 -0
  620. package/dist/templates/template-service.js.map +1 -0
  621. package/dist/triggers/handlers/base-handler.d.ts +21 -0
  622. package/dist/triggers/handlers/base-handler.d.ts.map +1 -0
  623. package/dist/triggers/handlers/base-handler.js +60 -0
  624. package/dist/triggers/handlers/base-handler.js.map +1 -0
  625. package/dist/triggers/handlers/chat-handler.d.ts +38 -0
  626. package/dist/triggers/handlers/chat-handler.d.ts.map +1 -0
  627. package/dist/triggers/handlers/chat-handler.js +129 -0
  628. package/dist/triggers/handlers/chat-handler.js.map +1 -0
  629. package/dist/triggers/handlers/form-handler.d.ts +35 -0
  630. package/dist/triggers/handlers/form-handler.d.ts.map +1 -0
  631. package/dist/triggers/handlers/form-handler.js +362 -0
  632. package/dist/triggers/handlers/form-handler.js.map +1 -0
  633. package/dist/triggers/handlers/webhook-handler.d.ts +38 -0
  634. package/dist/triggers/handlers/webhook-handler.d.ts.map +1 -0
  635. package/dist/triggers/handlers/webhook-handler.js +115 -0
  636. package/dist/triggers/handlers/webhook-handler.js.map +1 -0
  637. package/dist/triggers/index.d.ts +5 -0
  638. package/dist/triggers/index.d.ts.map +1 -0
  639. package/dist/triggers/index.js +14 -0
  640. package/dist/triggers/index.js.map +1 -0
  641. package/dist/triggers/trigger-detector.d.ts +6 -0
  642. package/dist/triggers/trigger-detector.d.ts.map +1 -0
  643. package/dist/triggers/trigger-detector.js +201 -0
  644. package/dist/triggers/trigger-detector.js.map +1 -0
  645. package/dist/triggers/trigger-registry.d.ts +18 -0
  646. package/dist/triggers/trigger-registry.d.ts.map +1 -0
  647. package/dist/triggers/trigger-registry.js +87 -0
  648. package/dist/triggers/trigger-registry.js.map +1 -0
  649. package/dist/triggers/types.d.ts +76 -0
  650. package/dist/triggers/types.d.ts.map +1 -0
  651. package/dist/triggers/types.js +3 -0
  652. package/dist/triggers/types.js.map +1 -0
  653. package/dist/types/index.d.ts +49 -0
  654. package/dist/types/index.d.ts.map +1 -0
  655. package/dist/types/index.js +21 -0
  656. package/dist/types/index.js.map +1 -0
  657. package/dist/types/instance-context.d.ts +20 -0
  658. package/dist/types/instance-context.d.ts.map +1 -0
  659. package/dist/types/instance-context.js +153 -0
  660. package/dist/types/instance-context.js.map +1 -0
  661. package/dist/types/n8n-api.d.ts +376 -0
  662. package/dist/types/n8n-api.d.ts.map +1 -0
  663. package/dist/types/n8n-api.js +10 -0
  664. package/dist/types/n8n-api.js.map +1 -0
  665. package/dist/types/node-types.d.ts +19 -0
  666. package/dist/types/node-types.d.ts.map +1 -0
  667. package/dist/types/node-types.js +62 -0
  668. package/dist/types/node-types.js.map +1 -0
  669. package/dist/types/session-state.d.ts +15 -0
  670. package/dist/types/session-state.d.ts.map +1 -0
  671. package/dist/types/session-state.js +3 -0
  672. package/dist/types/session-state.js.map +1 -0
  673. package/dist/types/type-structures.d.ts +42 -0
  674. package/dist/types/type-structures.d.ts.map +1 -0
  675. package/dist/types/type-structures.js +32 -0
  676. package/dist/types/type-structures.js.map +1 -0
  677. package/dist/types/workflow-comparison.d.ts +51 -0
  678. package/dist/types/workflow-comparison.d.ts.map +1 -0
  679. package/dist/types/workflow-comparison.js +3 -0
  680. package/dist/types/workflow-comparison.js.map +1 -0
  681. package/dist/types/workflow-diff.d.ts +148 -0
  682. package/dist/types/workflow-diff.d.ts.map +1 -0
  683. package/dist/types/workflow-diff.js +15 -0
  684. package/dist/types/workflow-diff.js.map +1 -0
  685. package/dist/utils/auth.d.ts +13 -0
  686. package/dist/utils/auth.d.ts.map +1 -0
  687. package/dist/utils/auth.js +82 -0
  688. package/dist/utils/auth.js.map +1 -0
  689. package/dist/utils/bridge.d.ts +12 -0
  690. package/dist/utils/bridge.d.ts.map +1 -0
  691. package/dist/utils/bridge.js +127 -0
  692. package/dist/utils/bridge.js.map +1 -0
  693. package/dist/utils/cache-utils.d.ts +58 -0
  694. package/dist/utils/cache-utils.d.ts.map +1 -0
  695. package/dist/utils/cache-utils.js +243 -0
  696. package/dist/utils/cache-utils.js.map +1 -0
  697. package/dist/utils/console-manager.d.ts +10 -0
  698. package/dist/utils/console-manager.d.ts.map +1 -0
  699. package/dist/utils/console-manager.js +63 -0
  700. package/dist/utils/console-manager.js.map +1 -0
  701. package/dist/utils/documentation-fetcher.d.ts +2 -0
  702. package/dist/utils/documentation-fetcher.d.ts.map +1 -0
  703. package/dist/utils/documentation-fetcher.js +18 -0
  704. package/dist/utils/documentation-fetcher.js.map +1 -0
  705. package/dist/utils/enhanced-documentation-fetcher.d.ts +74 -0
  706. package/dist/utils/enhanced-documentation-fetcher.d.ts.map +1 -0
  707. package/dist/utils/enhanced-documentation-fetcher.js +521 -0
  708. package/dist/utils/enhanced-documentation-fetcher.js.map +1 -0
  709. package/dist/utils/error-handler.d.ts +24 -0
  710. package/dist/utils/error-handler.d.ts.map +1 -0
  711. package/dist/utils/error-handler.js +84 -0
  712. package/dist/utils/error-handler.js.map +1 -0
  713. package/dist/utils/example-generator.d.ts +8 -0
  714. package/dist/utils/example-generator.d.ts.map +1 -0
  715. package/dist/utils/example-generator.js +106 -0
  716. package/dist/utils/example-generator.js.map +1 -0
  717. package/dist/utils/expression-utils.d.ts +6 -0
  718. package/dist/utils/expression-utils.d.ts.map +1 -0
  719. package/dist/utils/expression-utils.js +47 -0
  720. package/dist/utils/expression-utils.js.map +1 -0
  721. package/dist/utils/fixed-collection-validator.d.ts +35 -0
  722. package/dist/utils/fixed-collection-validator.d.ts.map +1 -0
  723. package/dist/utils/fixed-collection-validator.js +358 -0
  724. package/dist/utils/fixed-collection-validator.js.map +1 -0
  725. package/dist/utils/logger.d.ts +33 -0
  726. package/dist/utils/logger.d.ts.map +1 -0
  727. package/dist/utils/logger.js +101 -0
  728. package/dist/utils/logger.js.map +1 -0
  729. package/dist/utils/mcp-client.d.ts +21 -0
  730. package/dist/utils/mcp-client.d.ts.map +1 -0
  731. package/dist/utils/mcp-client.js +96 -0
  732. package/dist/utils/mcp-client.js.map +1 -0
  733. package/dist/utils/n8n-errors.d.ts +27 -0
  734. package/dist/utils/n8n-errors.d.ts.map +1 -0
  735. package/dist/utils/n8n-errors.js +138 -0
  736. package/dist/utils/n8n-errors.js.map +1 -0
  737. package/dist/utils/node-classification.d.ts +5 -0
  738. package/dist/utils/node-classification.d.ts.map +1 -0
  739. package/dist/utils/node-classification.js +31 -0
  740. package/dist/utils/node-classification.js.map +1 -0
  741. package/dist/utils/node-source-extractor.d.ts +21 -0
  742. package/dist/utils/node-source-extractor.d.ts.map +1 -0
  743. package/dist/utils/node-source-extractor.js +377 -0
  744. package/dist/utils/node-source-extractor.js.map +1 -0
  745. package/dist/utils/node-type-normalizer.d.ts +17 -0
  746. package/dist/utils/node-type-normalizer.d.ts.map +1 -0
  747. package/dist/utils/node-type-normalizer.js +87 -0
  748. package/dist/utils/node-type-normalizer.js.map +1 -0
  749. package/dist/utils/node-type-utils.d.ts +12 -0
  750. package/dist/utils/node-type-utils.d.ts.map +1 -0
  751. package/dist/utils/node-type-utils.js +126 -0
  752. package/dist/utils/node-type-utils.js.map +1 -0
  753. package/dist/utils/node-utils.d.ts +4 -0
  754. package/dist/utils/node-utils.d.ts.map +1 -0
  755. package/dist/utils/node-utils.js +81 -0
  756. package/dist/utils/node-utils.js.map +1 -0
  757. package/dist/utils/npm-version-checker.d.ts +14 -0
  758. package/dist/utils/npm-version-checker.d.ts.map +1 -0
  759. package/dist/utils/npm-version-checker.js +125 -0
  760. package/dist/utils/npm-version-checker.js.map +1 -0
  761. package/dist/utils/protocol-version.d.ts +19 -0
  762. package/dist/utils/protocol-version.d.ts.map +1 -0
  763. package/dist/utils/protocol-version.js +95 -0
  764. package/dist/utils/protocol-version.js.map +1 -0
  765. package/dist/utils/simple-cache.d.ts +10 -0
  766. package/dist/utils/simple-cache.d.ts.map +1 -0
  767. package/dist/utils/simple-cache.js +42 -0
  768. package/dist/utils/simple-cache.js.map +1 -0
  769. package/dist/utils/ssrf-protection.d.ts +7 -0
  770. package/dist/utils/ssrf-protection.d.ts.map +1 -0
  771. package/dist/utils/ssrf-protection.js +118 -0
  772. package/dist/utils/ssrf-protection.js.map +1 -0
  773. package/dist/utils/template-node-resolver.d.ts +2 -0
  774. package/dist/utils/template-node-resolver.d.ts.map +1 -0
  775. package/dist/utils/template-node-resolver.js +161 -0
  776. package/dist/utils/template-node-resolver.js.map +1 -0
  777. package/dist/utils/template-sanitizer.d.ts +21 -0
  778. package/dist/utils/template-sanitizer.d.ts.map +1 -0
  779. package/dist/utils/template-sanitizer.js +126 -0
  780. package/dist/utils/template-sanitizer.js.map +1 -0
  781. package/dist/utils/url-detector.d.ts +9 -0
  782. package/dist/utils/url-detector.d.ts.map +1 -0
  783. package/dist/utils/url-detector.js +79 -0
  784. package/dist/utils/url-detector.js.map +1 -0
  785. package/dist/utils/validation-schemas.d.ts +32 -0
  786. package/dist/utils/validation-schemas.d.ts.map +1 -0
  787. package/dist/utils/validation-schemas.js +219 -0
  788. package/dist/utils/validation-schemas.js.map +1 -0
  789. package/dist/utils/version.d.ts +2 -0
  790. package/dist/utils/version.d.ts.map +1 -0
  791. package/dist/utils/version.js +18 -0
  792. package/dist/utils/version.js.map +1 -0
  793. package/package.json +178 -0
  794. package/package.runtime.json +24 -0
@@ -0,0 +1,1328 @@
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.WorkflowValidator = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const expression_validator_1 = require("./expression-validator");
9
+ const expression_format_validator_1 = require("./expression-format-validator");
10
+ const node_similarity_service_1 = require("./node-similarity-service");
11
+ const node_type_normalizer_1 = require("../utils/node-type-normalizer");
12
+ const logger_1 = require("../utils/logger");
13
+ const ai_node_validator_1 = require("./ai-node-validator");
14
+ const ai_tool_validators_1 = require("./ai-tool-validators");
15
+ const node_type_utils_1 = require("../utils/node-type-utils");
16
+ const node_classification_1 = require("../utils/node-classification");
17
+ const tool_variant_generator_1 = require("./tool-variant-generator");
18
+ const logger = new logger_1.Logger({ prefix: '[WorkflowValidator]' });
19
+ class WorkflowValidator {
20
+ constructor(nodeRepository, nodeValidator) {
21
+ this.nodeRepository = nodeRepository;
22
+ this.nodeValidator = nodeValidator;
23
+ this.currentWorkflow = null;
24
+ this.similarityService = new node_similarity_service_1.NodeSimilarityService(nodeRepository);
25
+ }
26
+ async validateWorkflow(workflow, options = {}) {
27
+ this.currentWorkflow = workflow;
28
+ const { validateNodes = true, validateConnections = true, validateExpressions = true, profile = 'runtime' } = options;
29
+ const result = {
30
+ valid: true,
31
+ errors: [],
32
+ warnings: [],
33
+ statistics: {
34
+ totalNodes: 0,
35
+ enabledNodes: 0,
36
+ triggerNodes: 0,
37
+ validConnections: 0,
38
+ invalidConnections: 0,
39
+ expressionsValidated: 0,
40
+ },
41
+ suggestions: []
42
+ };
43
+ try {
44
+ if (!workflow) {
45
+ result.errors.push({
46
+ type: 'error',
47
+ message: 'Invalid workflow structure: workflow is null or undefined'
48
+ });
49
+ result.valid = false;
50
+ return result;
51
+ }
52
+ const executableNodes = Array.isArray(workflow.nodes) ? workflow.nodes.filter(n => !(0, node_classification_1.isNonExecutableNode)(n.type)) : [];
53
+ result.statistics.totalNodes = executableNodes.length;
54
+ result.statistics.enabledNodes = executableNodes.filter(n => !n.disabled).length;
55
+ this.validateWorkflowStructure(workflow, result);
56
+ if (workflow.nodes && Array.isArray(workflow.nodes) && workflow.connections && typeof workflow.connections === 'object') {
57
+ if (validateNodes && workflow.nodes.length > 0) {
58
+ await this.validateAllNodes(workflow, result, profile);
59
+ }
60
+ if (validateConnections) {
61
+ this.validateConnections(workflow, result, profile);
62
+ }
63
+ if (validateExpressions && workflow.nodes.length > 0) {
64
+ this.validateExpressions(workflow, result, profile);
65
+ }
66
+ if (workflow.nodes.length > 0) {
67
+ this.checkWorkflowPatterns(workflow, result, profile);
68
+ }
69
+ if (workflow.nodes.length > 0 && (0, ai_node_validator_1.hasAINodes)(workflow)) {
70
+ const aiIssues = (0, ai_node_validator_1.validateAISpecificNodes)(workflow);
71
+ for (const issue of aiIssues) {
72
+ const validationIssue = {
73
+ type: issue.severity === 'error' ? 'error' : 'warning',
74
+ nodeId: issue.nodeId,
75
+ nodeName: issue.nodeName,
76
+ message: issue.message,
77
+ details: issue.code ? { code: issue.code } : undefined
78
+ };
79
+ if (issue.severity === 'error') {
80
+ result.errors.push(validationIssue);
81
+ }
82
+ else {
83
+ result.warnings.push(validationIssue);
84
+ }
85
+ }
86
+ }
87
+ this.generateSuggestions(workflow, result);
88
+ if (result.errors.length > 0) {
89
+ this.addErrorRecoverySuggestions(result);
90
+ }
91
+ }
92
+ }
93
+ catch (error) {
94
+ logger.error('Error validating workflow:', error);
95
+ result.errors.push({
96
+ type: 'error',
97
+ message: `Workflow validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`
98
+ });
99
+ }
100
+ result.valid = result.errors.length === 0;
101
+ return result;
102
+ }
103
+ validateWorkflowStructure(workflow, result) {
104
+ if (!workflow.nodes) {
105
+ result.errors.push({
106
+ type: 'error',
107
+ message: workflow.nodes === null ? 'nodes must be an array' : 'Workflow must have a nodes array'
108
+ });
109
+ return;
110
+ }
111
+ if (!Array.isArray(workflow.nodes)) {
112
+ result.errors.push({
113
+ type: 'error',
114
+ message: 'nodes must be an array'
115
+ });
116
+ return;
117
+ }
118
+ if (!workflow.connections) {
119
+ result.errors.push({
120
+ type: 'error',
121
+ message: workflow.connections === null ? 'connections must be an object' : 'Workflow must have a connections object'
122
+ });
123
+ return;
124
+ }
125
+ if (typeof workflow.connections !== 'object' || Array.isArray(workflow.connections)) {
126
+ result.errors.push({
127
+ type: 'error',
128
+ message: 'connections must be an object'
129
+ });
130
+ return;
131
+ }
132
+ if (workflow.nodes.length === 0) {
133
+ result.warnings.push({
134
+ type: 'warning',
135
+ message: 'Workflow is empty - no nodes defined'
136
+ });
137
+ return;
138
+ }
139
+ if (workflow.nodes.length === 1) {
140
+ const singleNode = workflow.nodes[0];
141
+ const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(singleNode.type);
142
+ const isWebhook = normalizedType === 'nodes-base.webhook' ||
143
+ normalizedType === 'nodes-base.webhookTrigger';
144
+ const isLangchainNode = normalizedType.startsWith('nodes-langchain.');
145
+ if (!isWebhook && !isLangchainNode) {
146
+ result.errors.push({
147
+ type: 'error',
148
+ message: 'Single-node workflows are only valid for webhook endpoints. Add at least one more connected node to create a functional workflow.'
149
+ });
150
+ }
151
+ else if (isWebhook && Object.keys(workflow.connections).length === 0) {
152
+ result.warnings.push({
153
+ type: 'warning',
154
+ message: 'Webhook node has no connections. Consider adding nodes to process the webhook data.'
155
+ });
156
+ }
157
+ }
158
+ if (workflow.nodes.length > 1) {
159
+ const hasEnabledNodes = workflow.nodes.some(n => !n.disabled);
160
+ const hasConnections = Object.keys(workflow.connections).length > 0;
161
+ if (hasEnabledNodes && !hasConnections) {
162
+ result.errors.push({
163
+ type: 'error',
164
+ message: 'Multi-node workflow has no connections. Nodes must be connected to create a workflow. Use connections: { "Source Node Name": { "main": [[{ "node": "Target Node Name", "type": "main", "index": 0 }]] } }'
165
+ });
166
+ }
167
+ }
168
+ const nodeNames = new Set();
169
+ const nodeIds = new Set();
170
+ const nodeIdToIndex = new Map();
171
+ for (let i = 0; i < workflow.nodes.length; i++) {
172
+ const node = workflow.nodes[i];
173
+ if (nodeNames.has(node.name)) {
174
+ result.errors.push({
175
+ type: 'error',
176
+ nodeId: node.id,
177
+ nodeName: node.name,
178
+ message: `Duplicate node name: "${node.name}"`
179
+ });
180
+ }
181
+ nodeNames.add(node.name);
182
+ if (nodeIds.has(node.id)) {
183
+ const firstNodeIndex = nodeIdToIndex.get(node.id);
184
+ const firstNode = firstNodeIndex !== undefined ? workflow.nodes[firstNodeIndex] : undefined;
185
+ result.errors.push({
186
+ type: 'error',
187
+ nodeId: node.id,
188
+ message: `Duplicate node ID: "${node.id}". Node at index ${i} (name: "${node.name}", type: "${node.type}") conflicts with node at index ${firstNodeIndex} (name: "${firstNode?.name || 'unknown'}", type: "${firstNode?.type || 'unknown'}"). Each node must have a unique ID. Generate a new UUID using crypto.randomUUID() - Example: {id: "${crypto_1.default.randomUUID()}", name: "${node.name}", type: "${node.type}", ...}`
189
+ });
190
+ }
191
+ else {
192
+ nodeIds.add(node.id);
193
+ nodeIdToIndex.set(node.id, i);
194
+ }
195
+ }
196
+ const triggerNodes = workflow.nodes.filter(n => (0, node_type_utils_1.isTriggerNode)(n.type));
197
+ result.statistics.triggerNodes = triggerNodes.length;
198
+ if (triggerNodes.length === 0 && workflow.nodes.filter(n => !n.disabled).length > 0) {
199
+ result.warnings.push({
200
+ type: 'warning',
201
+ message: 'Workflow has no trigger nodes. It can only be executed manually.'
202
+ });
203
+ }
204
+ }
205
+ async validateAllNodes(workflow, result, profile) {
206
+ for (const node of workflow.nodes) {
207
+ if (node.disabled || (0, node_classification_1.isNonExecutableNode)(node.type))
208
+ continue;
209
+ try {
210
+ if (node.name && node.name.length > 255) {
211
+ result.warnings.push({
212
+ type: 'warning',
213
+ nodeId: node.id,
214
+ nodeName: node.name,
215
+ message: `Node name is very long (${node.name.length} characters). Consider using a shorter name for better readability.`
216
+ });
217
+ }
218
+ if (!Array.isArray(node.position) || node.position.length !== 2) {
219
+ result.errors.push({
220
+ type: 'error',
221
+ nodeId: node.id,
222
+ nodeName: node.name,
223
+ message: 'Node position must be an array with exactly 2 numbers [x, y]'
224
+ });
225
+ }
226
+ else {
227
+ const [x, y] = node.position;
228
+ if (typeof x !== 'number' || typeof y !== 'number' ||
229
+ !isFinite(x) || !isFinite(y)) {
230
+ result.errors.push({
231
+ type: 'error',
232
+ nodeId: node.id,
233
+ nodeName: node.name,
234
+ message: 'Node position values must be finite numbers'
235
+ });
236
+ }
237
+ }
238
+ const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(node.type);
239
+ let nodeInfo = this.nodeRepository.getNode(normalizedType);
240
+ if (!nodeInfo && tool_variant_generator_1.ToolVariantGenerator.isToolVariantNodeType(normalizedType)) {
241
+ const baseNodeType = tool_variant_generator_1.ToolVariantGenerator.getBaseNodeType(normalizedType);
242
+ if (baseNodeType) {
243
+ const baseNodeInfo = this.nodeRepository.getNode(baseNodeType);
244
+ if (baseNodeInfo) {
245
+ result.warnings.push({
246
+ type: 'warning',
247
+ nodeId: node.id,
248
+ nodeName: node.name,
249
+ message: `Node type "${node.type}" is inferred as a dynamic AI Tool variant of "${baseNodeType}". ` +
250
+ `This Tool variant is created by n8n at runtime when connecting "${baseNodeInfo.displayName}" to an AI Agent.`,
251
+ code: 'INFERRED_TOOL_VARIANT'
252
+ });
253
+ nodeInfo = {
254
+ ...baseNodeInfo,
255
+ nodeType: normalizedType,
256
+ displayName: `${baseNodeInfo.displayName} Tool`,
257
+ isToolVariant: true,
258
+ toolVariantOf: baseNodeType,
259
+ isInferred: true
260
+ };
261
+ }
262
+ }
263
+ }
264
+ if (!nodeInfo) {
265
+ const suggestions = await this.similarityService.findSimilarNodes(node.type, 3);
266
+ let message = `Unknown node type: "${node.type}".`;
267
+ if (suggestions.length > 0) {
268
+ message += '\n\nDid you mean one of these?';
269
+ for (const suggestion of suggestions) {
270
+ const confidence = Math.round(suggestion.confidence * 100);
271
+ message += `\n• ${suggestion.nodeType} (${confidence}% match)`;
272
+ if (suggestion.displayName) {
273
+ message += ` - ${suggestion.displayName}`;
274
+ }
275
+ message += `\n → ${suggestion.reason}`;
276
+ if (suggestion.confidence >= 0.9) {
277
+ message += ' (can be auto-fixed)';
278
+ }
279
+ }
280
+ }
281
+ else {
282
+ message += ' No similar nodes found. Node types must include the package prefix (e.g., "n8n-nodes-base.webhook").';
283
+ }
284
+ const error = {
285
+ type: 'error',
286
+ nodeId: node.id,
287
+ nodeName: node.name,
288
+ message
289
+ };
290
+ if (suggestions.length > 0) {
291
+ error.suggestions = suggestions.map(s => ({
292
+ nodeType: s.nodeType,
293
+ confidence: s.confidence,
294
+ reason: s.reason
295
+ }));
296
+ }
297
+ result.errors.push(error);
298
+ continue;
299
+ }
300
+ if (nodeInfo.isVersioned) {
301
+ if (!node.typeVersion) {
302
+ result.errors.push({
303
+ type: 'error',
304
+ nodeId: node.id,
305
+ nodeName: node.name,
306
+ message: `Missing required property 'typeVersion'. Add typeVersion: ${nodeInfo.version || 1}`
307
+ });
308
+ }
309
+ else if (typeof node.typeVersion !== 'number' || node.typeVersion < 0) {
310
+ result.errors.push({
311
+ type: 'error',
312
+ nodeId: node.id,
313
+ nodeName: node.name,
314
+ message: `Invalid typeVersion: ${node.typeVersion}. Must be a non-negative number`
315
+ });
316
+ }
317
+ else if (nodeInfo.version && node.typeVersion < nodeInfo.version) {
318
+ result.warnings.push({
319
+ type: 'warning',
320
+ nodeId: node.id,
321
+ nodeName: node.name,
322
+ message: `Outdated typeVersion: ${node.typeVersion}. Latest is ${nodeInfo.version}`
323
+ });
324
+ }
325
+ else if (nodeInfo.version && node.typeVersion > nodeInfo.version) {
326
+ result.errors.push({
327
+ type: 'error',
328
+ nodeId: node.id,
329
+ nodeName: node.name,
330
+ message: `typeVersion ${node.typeVersion} exceeds maximum supported version ${nodeInfo.version}`
331
+ });
332
+ }
333
+ }
334
+ if (normalizedType.startsWith('nodes-langchain.')) {
335
+ continue;
336
+ }
337
+ if (nodeInfo.isInferred) {
338
+ continue;
339
+ }
340
+ const paramsWithVersion = {
341
+ '@version': node.typeVersion || 1,
342
+ ...node.parameters
343
+ };
344
+ const nodeValidation = this.nodeValidator.validateWithMode(node.type, paramsWithVersion, nodeInfo.properties || [], 'operation', profile);
345
+ nodeValidation.errors.forEach((error) => {
346
+ result.errors.push({
347
+ type: 'error',
348
+ nodeId: node.id,
349
+ nodeName: node.name,
350
+ message: typeof error === 'string' ? error : error.message || String(error)
351
+ });
352
+ });
353
+ nodeValidation.warnings.forEach((warning) => {
354
+ result.warnings.push({
355
+ type: 'warning',
356
+ nodeId: node.id,
357
+ nodeName: node.name,
358
+ message: typeof warning === 'string' ? warning : warning.message || String(warning)
359
+ });
360
+ });
361
+ }
362
+ catch (error) {
363
+ result.errors.push({
364
+ type: 'error',
365
+ nodeId: node.id,
366
+ nodeName: node.name,
367
+ message: `Failed to validate node: ${error instanceof Error ? error.message : 'Unknown error'}`
368
+ });
369
+ }
370
+ }
371
+ }
372
+ validateConnections(workflow, result, profile = 'runtime') {
373
+ const nodeMap = new Map(workflow.nodes.map(n => [n.name, n]));
374
+ const nodeIdMap = new Map(workflow.nodes.map(n => [n.id, n]));
375
+ for (const [sourceName, outputs] of Object.entries(workflow.connections)) {
376
+ const sourceNode = nodeMap.get(sourceName);
377
+ if (!sourceNode) {
378
+ const nodeById = nodeIdMap.get(sourceName);
379
+ if (nodeById) {
380
+ result.errors.push({
381
+ type: 'error',
382
+ nodeId: nodeById.id,
383
+ nodeName: nodeById.name,
384
+ message: `Connection uses node ID '${sourceName}' instead of node name '${nodeById.name}'. In n8n, connections must use node names, not IDs.`
385
+ });
386
+ }
387
+ else {
388
+ result.errors.push({
389
+ type: 'error',
390
+ message: `Connection from non-existent node: "${sourceName}"`
391
+ });
392
+ }
393
+ result.statistics.invalidConnections++;
394
+ continue;
395
+ }
396
+ if (outputs.main) {
397
+ this.validateConnectionOutputs(sourceName, outputs.main, nodeMap, nodeIdMap, result, 'main');
398
+ }
399
+ if (outputs.error) {
400
+ this.validateConnectionOutputs(sourceName, outputs.error, nodeMap, nodeIdMap, result, 'error');
401
+ }
402
+ if (outputs.ai_tool) {
403
+ this.validateAIToolSource(sourceNode, result);
404
+ this.validateConnectionOutputs(sourceName, outputs.ai_tool, nodeMap, nodeIdMap, result, 'ai_tool');
405
+ }
406
+ }
407
+ const connectedNodes = new Set();
408
+ Object.keys(workflow.connections).forEach(name => connectedNodes.add(name));
409
+ Object.values(workflow.connections).forEach(outputs => {
410
+ if (outputs.main) {
411
+ outputs.main.flat().forEach(conn => {
412
+ if (conn)
413
+ connectedNodes.add(conn.node);
414
+ });
415
+ }
416
+ if (outputs.error) {
417
+ outputs.error.flat().forEach(conn => {
418
+ if (conn)
419
+ connectedNodes.add(conn.node);
420
+ });
421
+ }
422
+ if (outputs.ai_tool) {
423
+ outputs.ai_tool.flat().forEach(conn => {
424
+ if (conn)
425
+ connectedNodes.add(conn.node);
426
+ });
427
+ }
428
+ });
429
+ for (const node of workflow.nodes) {
430
+ if (node.disabled || (0, node_classification_1.isNonExecutableNode)(node.type))
431
+ continue;
432
+ const isNodeTrigger = (0, node_type_utils_1.isTriggerNode)(node.type);
433
+ if (!connectedNodes.has(node.name) && !isNodeTrigger) {
434
+ result.warnings.push({
435
+ type: 'warning',
436
+ nodeId: node.id,
437
+ nodeName: node.name,
438
+ message: 'Node is not connected to any other nodes'
439
+ });
440
+ }
441
+ }
442
+ if (profile !== 'minimal' && this.hasCycle(workflow)) {
443
+ result.errors.push({
444
+ type: 'error',
445
+ message: 'Workflow contains a cycle (infinite loop)'
446
+ });
447
+ }
448
+ }
449
+ validateConnectionOutputs(sourceName, outputs, nodeMap, nodeIdMap, result, outputType) {
450
+ const sourceNode = nodeMap.get(sourceName);
451
+ if (outputType === 'main' && sourceNode) {
452
+ this.validateErrorOutputConfiguration(sourceName, sourceNode, outputs, nodeMap, result);
453
+ }
454
+ outputs.forEach((outputConnections, outputIndex) => {
455
+ if (!outputConnections)
456
+ return;
457
+ outputConnections.forEach(connection => {
458
+ if (connection.index < 0) {
459
+ result.errors.push({
460
+ type: 'error',
461
+ message: `Invalid connection index ${connection.index} from "${sourceName}". Connection indices must be non-negative.`
462
+ });
463
+ result.statistics.invalidConnections++;
464
+ return;
465
+ }
466
+ const isSplitInBatches = sourceNode && (sourceNode.type === 'n8n-nodes-base.splitInBatches' ||
467
+ sourceNode.type === 'nodes-base.splitInBatches');
468
+ if (isSplitInBatches) {
469
+ this.validateSplitInBatchesConnection(sourceNode, outputIndex, connection, nodeMap, result);
470
+ }
471
+ if (connection.node === sourceName) {
472
+ if (sourceNode && !isSplitInBatches) {
473
+ result.warnings.push({
474
+ type: 'warning',
475
+ message: `Node "${sourceName}" has a self-referencing connection. This can cause infinite loops.`
476
+ });
477
+ }
478
+ }
479
+ const targetNode = nodeMap.get(connection.node);
480
+ if (!targetNode) {
481
+ const nodeById = nodeIdMap.get(connection.node);
482
+ if (nodeById) {
483
+ result.errors.push({
484
+ type: 'error',
485
+ nodeId: nodeById.id,
486
+ nodeName: nodeById.name,
487
+ message: `Connection target uses node ID '${connection.node}' instead of node name '${nodeById.name}' (from ${sourceName}). In n8n, connections must use node names, not IDs.`
488
+ });
489
+ }
490
+ else {
491
+ result.errors.push({
492
+ type: 'error',
493
+ message: `Connection to non-existent node: "${connection.node}" from "${sourceName}"`
494
+ });
495
+ }
496
+ result.statistics.invalidConnections++;
497
+ }
498
+ else if (targetNode.disabled) {
499
+ result.warnings.push({
500
+ type: 'warning',
501
+ message: `Connection to disabled node: "${connection.node}" from "${sourceName}"`
502
+ });
503
+ }
504
+ else {
505
+ result.statistics.validConnections++;
506
+ if (outputType === 'ai_tool') {
507
+ this.validateAIToolConnection(sourceName, targetNode, result);
508
+ }
509
+ }
510
+ });
511
+ });
512
+ }
513
+ validateErrorOutputConfiguration(sourceName, sourceNode, outputs, nodeMap, result) {
514
+ const hasErrorOutputSetting = sourceNode.onError === 'continueErrorOutput';
515
+ const hasErrorConnections = outputs.length > 1 && outputs[1] && outputs[1].length > 0;
516
+ if (hasErrorOutputSetting && !hasErrorConnections) {
517
+ result.errors.push({
518
+ type: 'error',
519
+ nodeId: sourceNode.id,
520
+ nodeName: sourceNode.name,
521
+ message: `Node has onError: 'continueErrorOutput' but no error output connections in main[1]. Add error handler connections to main[1] or change onError to 'continueRegularOutput' or 'stopWorkflow'.`
522
+ });
523
+ }
524
+ if (!hasErrorOutputSetting && hasErrorConnections) {
525
+ result.warnings.push({
526
+ type: 'warning',
527
+ nodeId: sourceNode.id,
528
+ nodeName: sourceNode.name,
529
+ message: `Node has error output connections in main[1] but missing onError: 'continueErrorOutput'. Add this property to properly handle errors.`
530
+ });
531
+ }
532
+ if (outputs.length >= 1 && outputs[0] && outputs[0].length > 1) {
533
+ const potentialErrorHandlers = outputs[0].filter(conn => {
534
+ const targetNode = nodeMap.get(conn.node);
535
+ if (!targetNode)
536
+ return false;
537
+ const nodeName = targetNode.name.toLowerCase();
538
+ const nodeType = targetNode.type.toLowerCase();
539
+ return nodeName.includes('error') ||
540
+ nodeName.includes('fail') ||
541
+ nodeName.includes('catch') ||
542
+ nodeName.includes('exception') ||
543
+ nodeType.includes('respondtowebhook') ||
544
+ nodeType.includes('emailsend');
545
+ });
546
+ if (potentialErrorHandlers.length > 0) {
547
+ const errorHandlerNames = potentialErrorHandlers.map(conn => `"${conn.node}"`).join(', ');
548
+ result.errors.push({
549
+ type: 'error',
550
+ nodeId: sourceNode.id,
551
+ nodeName: sourceNode.name,
552
+ message: `Incorrect error output configuration. Nodes ${errorHandlerNames} appear to be error handlers but are in main[0] (success output) along with other nodes.\n\n` +
553
+ `INCORRECT (current):\n` +
554
+ `"${sourceName}": {\n` +
555
+ ` "main": [\n` +
556
+ ` [ // main[0] has multiple nodes mixed together\n` +
557
+ outputs[0].map(conn => ` {"node": "${conn.node}", "type": "${conn.type}", "index": ${conn.index}}`).join(',\n') + '\n' +
558
+ ` ]\n` +
559
+ ` ]\n` +
560
+ `}\n\n` +
561
+ `CORRECT (should be):\n` +
562
+ `"${sourceName}": {\n` +
563
+ ` "main": [\n` +
564
+ ` [ // main[0] = success output\n` +
565
+ outputs[0].filter(conn => !potentialErrorHandlers.includes(conn)).map(conn => ` {"node": "${conn.node}", "type": "${conn.type}", "index": ${conn.index}}`).join(',\n') + '\n' +
566
+ ` ],\n` +
567
+ ` [ // main[1] = error output\n` +
568
+ potentialErrorHandlers.map(conn => ` {"node": "${conn.node}", "type": "${conn.type}", "index": ${conn.index}}`).join(',\n') + '\n' +
569
+ ` ]\n` +
570
+ ` ]\n` +
571
+ `}\n\n` +
572
+ `Also add: "onError": "continueErrorOutput" to the "${sourceName}" node.`
573
+ });
574
+ }
575
+ }
576
+ }
577
+ validateAIToolConnection(sourceName, targetNode, result) {
578
+ const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(targetNode.type);
579
+ let targetNodeInfo = this.nodeRepository.getNode(normalizedType);
580
+ if (!targetNodeInfo && normalizedType !== targetNode.type) {
581
+ targetNodeInfo = this.nodeRepository.getNode(targetNode.type);
582
+ }
583
+ if (targetNodeInfo && !targetNodeInfo.isAITool && targetNodeInfo.package !== 'n8n-nodes-base') {
584
+ result.warnings.push({
585
+ type: 'warning',
586
+ nodeId: targetNode.id,
587
+ nodeName: targetNode.name,
588
+ message: `Community node "${targetNode.name}" is being used as an AI tool. Ensure N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true is set.`
589
+ });
590
+ }
591
+ }
592
+ validateAIToolSource(sourceNode, result) {
593
+ const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(sourceNode.type);
594
+ if ((0, ai_tool_validators_1.isAIToolSubNode)(normalizedType)) {
595
+ return;
596
+ }
597
+ const nodeInfo = this.nodeRepository.getNode(normalizedType);
598
+ if (tool_variant_generator_1.ToolVariantGenerator.isToolVariantNodeType(normalizedType)) {
599
+ if (nodeInfo?.isToolVariant) {
600
+ return;
601
+ }
602
+ }
603
+ if (!nodeInfo) {
604
+ return;
605
+ }
606
+ if (nodeInfo.hasToolVariant) {
607
+ const toolVariantType = tool_variant_generator_1.ToolVariantGenerator.getToolVariantNodeType(normalizedType);
608
+ const workflowToolVariantType = node_type_normalizer_1.NodeTypeNormalizer.toWorkflowFormat(toolVariantType);
609
+ result.errors.push({
610
+ type: 'error',
611
+ nodeId: sourceNode.id,
612
+ nodeName: sourceNode.name,
613
+ message: `Node "${sourceNode.name}" uses "${sourceNode.type}" which cannot output ai_tool connections. ` +
614
+ `Use the Tool variant "${workflowToolVariantType}" instead for AI Agent integration.`,
615
+ code: 'WRONG_NODE_TYPE_FOR_AI_TOOL',
616
+ fix: {
617
+ type: 'tool-variant-correction',
618
+ currentType: sourceNode.type,
619
+ suggestedType: workflowToolVariantType,
620
+ description: `Change node type from "${sourceNode.type}" to "${workflowToolVariantType}"`
621
+ }
622
+ });
623
+ return;
624
+ }
625
+ if (nodeInfo.isAITool) {
626
+ return;
627
+ }
628
+ result.errors.push({
629
+ type: 'error',
630
+ nodeId: sourceNode.id,
631
+ nodeName: sourceNode.name,
632
+ message: `Node "${sourceNode.name}" of type "${sourceNode.type}" cannot output ai_tool connections. ` +
633
+ `Only AI tool nodes (e.g., Calculator, HTTP Request Tool) or Tool variants (e.g., *Tool suffix nodes) can be connected to AI Agents as tools.`,
634
+ code: 'INVALID_AI_TOOL_SOURCE'
635
+ });
636
+ }
637
+ hasCycle(workflow) {
638
+ const visited = new Set();
639
+ const recursionStack = new Set();
640
+ const nodeTypeMap = new Map();
641
+ workflow.nodes.forEach(node => {
642
+ if (!(0, node_classification_1.isNonExecutableNode)(node.type)) {
643
+ nodeTypeMap.set(node.name, node.type);
644
+ }
645
+ });
646
+ const loopNodeTypes = [
647
+ 'n8n-nodes-base.splitInBatches',
648
+ 'nodes-base.splitInBatches',
649
+ 'n8n-nodes-base.itemLists',
650
+ 'nodes-base.itemLists',
651
+ 'n8n-nodes-base.loop',
652
+ 'nodes-base.loop'
653
+ ];
654
+ const hasCycleDFS = (nodeName, pathFromLoopNode = false) => {
655
+ visited.add(nodeName);
656
+ recursionStack.add(nodeName);
657
+ const connections = workflow.connections[nodeName];
658
+ if (connections) {
659
+ const allTargets = [];
660
+ if (connections.main) {
661
+ connections.main.flat().forEach(conn => {
662
+ if (conn)
663
+ allTargets.push(conn.node);
664
+ });
665
+ }
666
+ if (connections.error) {
667
+ connections.error.flat().forEach(conn => {
668
+ if (conn)
669
+ allTargets.push(conn.node);
670
+ });
671
+ }
672
+ if (connections.ai_tool) {
673
+ connections.ai_tool.flat().forEach(conn => {
674
+ if (conn)
675
+ allTargets.push(conn.node);
676
+ });
677
+ }
678
+ const currentNodeType = nodeTypeMap.get(nodeName);
679
+ const isLoopNode = loopNodeTypes.includes(currentNodeType || '');
680
+ for (const target of allTargets) {
681
+ if (!visited.has(target)) {
682
+ if (hasCycleDFS(target, pathFromLoopNode || isLoopNode))
683
+ return true;
684
+ }
685
+ else if (recursionStack.has(target)) {
686
+ const targetNodeType = nodeTypeMap.get(target);
687
+ const isTargetLoopNode = loopNodeTypes.includes(targetNodeType || '');
688
+ if (isTargetLoopNode || pathFromLoopNode || isLoopNode) {
689
+ continue;
690
+ }
691
+ return true;
692
+ }
693
+ }
694
+ }
695
+ recursionStack.delete(nodeName);
696
+ return false;
697
+ };
698
+ for (const node of workflow.nodes) {
699
+ if (!(0, node_classification_1.isNonExecutableNode)(node.type) && !visited.has(node.name)) {
700
+ if (hasCycleDFS(node.name))
701
+ return true;
702
+ }
703
+ }
704
+ return false;
705
+ }
706
+ validateExpressions(workflow, result, profile = 'runtime') {
707
+ const nodeNames = workflow.nodes.map(n => n.name);
708
+ for (const node of workflow.nodes) {
709
+ if (node.disabled || (0, node_classification_1.isNonExecutableNode)(node.type))
710
+ continue;
711
+ const normalizedType = node_type_normalizer_1.NodeTypeNormalizer.normalizeToFullForm(node.type);
712
+ if (normalizedType.startsWith('nodes-langchain.')) {
713
+ continue;
714
+ }
715
+ const context = {
716
+ availableNodes: nodeNames.filter(n => n !== node.name),
717
+ currentNodeName: node.name,
718
+ hasInputData: this.nodeHasInput(node.name, workflow),
719
+ isInLoop: false
720
+ };
721
+ const exprValidation = expression_validator_1.ExpressionValidator.validateNodeExpressions(node.parameters, context);
722
+ const expressionCount = this.countExpressionsInObject(node.parameters);
723
+ result.statistics.expressionsValidated += expressionCount;
724
+ exprValidation.errors.forEach(error => {
725
+ result.errors.push({
726
+ type: 'error',
727
+ nodeId: node.id,
728
+ nodeName: node.name,
729
+ message: `Expression error: ${error}`
730
+ });
731
+ });
732
+ exprValidation.warnings.forEach(warning => {
733
+ result.warnings.push({
734
+ type: 'warning',
735
+ nodeId: node.id,
736
+ nodeName: node.name,
737
+ message: `Expression warning: ${warning}`
738
+ });
739
+ });
740
+ const formatContext = {
741
+ nodeType: node.type,
742
+ nodeName: node.name,
743
+ nodeId: node.id
744
+ };
745
+ const formatIssues = expression_format_validator_1.ExpressionFormatValidator.validateNodeParameters(node.parameters, formatContext);
746
+ formatIssues.forEach(issue => {
747
+ const formattedMessage = expression_format_validator_1.ExpressionFormatValidator.formatErrorMessage(issue, formatContext);
748
+ if (issue.severity === 'error') {
749
+ result.errors.push({
750
+ type: 'error',
751
+ nodeId: node.id,
752
+ nodeName: node.name,
753
+ message: formattedMessage
754
+ });
755
+ }
756
+ else {
757
+ result.warnings.push({
758
+ type: 'warning',
759
+ nodeId: node.id,
760
+ nodeName: node.name,
761
+ message: formattedMessage
762
+ });
763
+ }
764
+ });
765
+ }
766
+ }
767
+ countExpressionsInObject(obj) {
768
+ let count = 0;
769
+ if (typeof obj === 'string') {
770
+ const matches = obj.match(/\{\{[\s\S]+?\}\}/g);
771
+ if (matches) {
772
+ count += matches.length;
773
+ }
774
+ }
775
+ else if (Array.isArray(obj)) {
776
+ for (const item of obj) {
777
+ count += this.countExpressionsInObject(item);
778
+ }
779
+ }
780
+ else if (obj && typeof obj === 'object') {
781
+ for (const value of Object.values(obj)) {
782
+ count += this.countExpressionsInObject(value);
783
+ }
784
+ }
785
+ return count;
786
+ }
787
+ nodeHasInput(nodeName, workflow) {
788
+ for (const [sourceName, outputs] of Object.entries(workflow.connections)) {
789
+ if (outputs.main) {
790
+ for (const outputConnections of outputs.main) {
791
+ if (outputConnections?.some(conn => conn.node === nodeName)) {
792
+ return true;
793
+ }
794
+ }
795
+ }
796
+ }
797
+ return false;
798
+ }
799
+ checkWorkflowPatterns(workflow, result, profile = 'runtime') {
800
+ const hasErrorHandling = Object.values(workflow.connections).some(outputs => outputs.main && outputs.main.length > 1 && outputs.main[1] && outputs.main[1].length > 0);
801
+ if (!hasErrorHandling && workflow.nodes.length > 3 && profile !== 'minimal') {
802
+ result.warnings.push({
803
+ type: 'warning',
804
+ message: 'Consider adding error handling to your workflow'
805
+ });
806
+ }
807
+ for (const node of workflow.nodes) {
808
+ if (!(0, node_classification_1.isNonExecutableNode)(node.type)) {
809
+ this.checkNodeErrorHandling(node, workflow, result);
810
+ }
811
+ }
812
+ const linearChainLength = this.getLongestLinearChain(workflow);
813
+ if (linearChainLength > 10) {
814
+ result.warnings.push({
815
+ type: 'warning',
816
+ message: `Long linear chain detected (${linearChainLength} nodes). Consider breaking into sub-workflows.`
817
+ });
818
+ }
819
+ this.generateErrorHandlingSuggestions(workflow, result);
820
+ for (const node of workflow.nodes) {
821
+ if (node.credentials && Object.keys(node.credentials).length > 0) {
822
+ for (const [credType, credConfig] of Object.entries(node.credentials)) {
823
+ if (!credConfig || (typeof credConfig === 'object' && !('id' in credConfig))) {
824
+ result.warnings.push({
825
+ type: 'warning',
826
+ nodeId: node.id,
827
+ nodeName: node.name,
828
+ message: `Missing credentials configuration for ${credType}`
829
+ });
830
+ }
831
+ }
832
+ }
833
+ }
834
+ const aiAgentNodes = workflow.nodes.filter(n => n.type.toLowerCase().includes('agent') ||
835
+ n.type.includes('langchain.agent'));
836
+ if (aiAgentNodes.length > 0) {
837
+ for (const agentNode of aiAgentNodes) {
838
+ const hasToolConnected = Object.values(workflow.connections).some(sourceOutputs => {
839
+ const aiToolConnections = sourceOutputs.ai_tool;
840
+ if (!aiToolConnections)
841
+ return false;
842
+ return aiToolConnections.flat().some(conn => conn && conn.node === agentNode.name);
843
+ });
844
+ if (!hasToolConnected) {
845
+ result.warnings.push({
846
+ type: 'warning',
847
+ nodeId: agentNode.id,
848
+ nodeName: agentNode.name,
849
+ message: 'AI Agent has no tools connected. Consider adding tools to enhance agent capabilities.'
850
+ });
851
+ }
852
+ }
853
+ const hasAIToolConnections = Object.values(workflow.connections).some(outputs => outputs.ai_tool && outputs.ai_tool.length > 0);
854
+ if (hasAIToolConnections) {
855
+ result.suggestions.push('For community nodes used as AI tools, ensure N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true is set');
856
+ }
857
+ }
858
+ }
859
+ getLongestLinearChain(workflow) {
860
+ const memo = new Map();
861
+ const visiting = new Set();
862
+ const getChainLength = (nodeName) => {
863
+ if (visiting.has(nodeName))
864
+ return 0;
865
+ if (memo.has(nodeName))
866
+ return memo.get(nodeName);
867
+ visiting.add(nodeName);
868
+ let maxLength = 0;
869
+ const connections = workflow.connections[nodeName];
870
+ if (connections?.main) {
871
+ for (const outputConnections of connections.main) {
872
+ if (outputConnections) {
873
+ for (const conn of outputConnections) {
874
+ const length = getChainLength(conn.node);
875
+ maxLength = Math.max(maxLength, length);
876
+ }
877
+ }
878
+ }
879
+ }
880
+ visiting.delete(nodeName);
881
+ const result = maxLength + 1;
882
+ memo.set(nodeName, result);
883
+ return result;
884
+ };
885
+ let maxChain = 0;
886
+ for (const node of workflow.nodes) {
887
+ if (!this.nodeHasInput(node.name, workflow)) {
888
+ maxChain = Math.max(maxChain, getChainLength(node.name));
889
+ }
890
+ }
891
+ return maxChain;
892
+ }
893
+ generateSuggestions(workflow, result) {
894
+ if (result.statistics.triggerNodes === 0) {
895
+ result.suggestions.push('Add a trigger node (e.g., Webhook, Schedule Trigger) to automate workflow execution');
896
+ }
897
+ const hasConnectionErrors = result.errors.some(e => typeof e.message === 'string' && (e.message.includes('connection') ||
898
+ e.message.includes('Connection') ||
899
+ e.message.includes('Multi-node workflow has no connections')));
900
+ if (hasConnectionErrors) {
901
+ result.suggestions.push('Example connection structure: connections: { "Manual Trigger": { "main": [[{ "node": "Set", "type": "main", "index": 0 }]] } }');
902
+ result.suggestions.push('Remember: Use node NAMES (not IDs) in connections. The name is what you see in the UI, not the node type.');
903
+ }
904
+ if (!Object.values(workflow.connections).some(o => o.error)) {
905
+ result.suggestions.push('Add error handling using the error output of nodes or an Error Trigger node');
906
+ }
907
+ if (workflow.nodes.length > 20) {
908
+ result.suggestions.push('Consider breaking this workflow into smaller sub-workflows for better maintainability');
909
+ }
910
+ const complexExpressionNodes = workflow.nodes.filter(node => {
911
+ const jsonString = JSON.stringify(node.parameters);
912
+ const expressionCount = (jsonString.match(/\{\{/g) || []).length;
913
+ return expressionCount > 5;
914
+ });
915
+ if (complexExpressionNodes.length > 0) {
916
+ result.suggestions.push('Consider using a Code node for complex data transformations instead of multiple expressions');
917
+ }
918
+ if (workflow.nodes.length === 1 && Object.keys(workflow.connections).length === 0) {
919
+ result.suggestions.push('A minimal workflow needs: 1) A trigger node (e.g., Manual Trigger), 2) An action node (e.g., Set, HTTP Request), 3) A connection between them');
920
+ }
921
+ }
922
+ checkNodeErrorHandling(node, workflow, result) {
923
+ if (node.disabled === true)
924
+ return;
925
+ const errorProneNodeTypes = [
926
+ 'httprequest',
927
+ 'webhook',
928
+ 'emailsend',
929
+ 'slack',
930
+ 'discord',
931
+ 'telegram',
932
+ 'postgres',
933
+ 'mysql',
934
+ 'mongodb',
935
+ 'redis',
936
+ 'github',
937
+ 'gitlab',
938
+ 'jira',
939
+ 'salesforce',
940
+ 'hubspot',
941
+ 'airtable',
942
+ 'googlesheets',
943
+ 'googledrive',
944
+ 'dropbox',
945
+ 's3',
946
+ 'ftp',
947
+ 'ssh',
948
+ 'mqtt',
949
+ 'kafka',
950
+ 'rabbitmq',
951
+ 'graphql',
952
+ 'openai',
953
+ 'anthropic'
954
+ ];
955
+ const normalizedType = node.type.toLowerCase();
956
+ const isErrorProne = errorProneNodeTypes.some(type => normalizedType.includes(type));
957
+ const nodeLevelProps = [
958
+ 'onError', 'continueOnFail', 'retryOnFail', 'maxTries', 'waitBetweenTries', 'alwaysOutputData',
959
+ 'executeOnce', 'disabled', 'notes', 'notesInFlow', 'credentials'
960
+ ];
961
+ const misplacedProps = [];
962
+ if (node.parameters) {
963
+ for (const prop of nodeLevelProps) {
964
+ if (node.parameters[prop] !== undefined) {
965
+ misplacedProps.push(prop);
966
+ }
967
+ }
968
+ }
969
+ if (misplacedProps.length > 0) {
970
+ result.errors.push({
971
+ type: 'error',
972
+ nodeId: node.id,
973
+ nodeName: node.name,
974
+ message: `Node-level properties ${misplacedProps.join(', ')} are in the wrong location. They must be at the node level, not inside parameters.`,
975
+ details: {
976
+ fix: `Move these properties from node.parameters to the node level. Example:\n` +
977
+ `{\n` +
978
+ ` "name": "${node.name}",\n` +
979
+ ` "type": "${node.type}",\n` +
980
+ ` "parameters": { /* operation-specific params */ },\n` +
981
+ ` "onError": "continueErrorOutput", // ✅ Correct location\n` +
982
+ ` "retryOnFail": true, // ✅ Correct location\n` +
983
+ ` "executeOnce": true, // ✅ Correct location\n` +
984
+ ` "disabled": false, // ✅ Correct location\n` +
985
+ ` "credentials": { /* ... */ } // ✅ Correct location\n` +
986
+ `}`
987
+ }
988
+ });
989
+ }
990
+ if (node.onError !== undefined) {
991
+ const validOnErrorValues = ['continueRegularOutput', 'continueErrorOutput', 'stopWorkflow'];
992
+ if (!validOnErrorValues.includes(node.onError)) {
993
+ result.errors.push({
994
+ type: 'error',
995
+ nodeId: node.id,
996
+ nodeName: node.name,
997
+ message: `Invalid onError value: "${node.onError}". Must be one of: ${validOnErrorValues.join(', ')}`
998
+ });
999
+ }
1000
+ }
1001
+ if (node.continueOnFail !== undefined) {
1002
+ if (typeof node.continueOnFail !== 'boolean') {
1003
+ result.errors.push({
1004
+ type: 'error',
1005
+ nodeId: node.id,
1006
+ nodeName: node.name,
1007
+ message: 'continueOnFail must be a boolean value'
1008
+ });
1009
+ }
1010
+ else if (node.continueOnFail === true) {
1011
+ result.warnings.push({
1012
+ type: 'warning',
1013
+ nodeId: node.id,
1014
+ nodeName: node.name,
1015
+ message: 'Using deprecated "continueOnFail: true". Use "onError: \'continueRegularOutput\'" instead for better control and UI compatibility.'
1016
+ });
1017
+ }
1018
+ }
1019
+ if (node.continueOnFail !== undefined && node.onError !== undefined) {
1020
+ result.errors.push({
1021
+ type: 'error',
1022
+ nodeId: node.id,
1023
+ nodeName: node.name,
1024
+ message: 'Cannot use both "continueOnFail" and "onError" properties. Use only "onError" for modern workflows.'
1025
+ });
1026
+ }
1027
+ if (node.retryOnFail !== undefined) {
1028
+ if (typeof node.retryOnFail !== 'boolean') {
1029
+ result.errors.push({
1030
+ type: 'error',
1031
+ nodeId: node.id,
1032
+ nodeName: node.name,
1033
+ message: 'retryOnFail must be a boolean value'
1034
+ });
1035
+ }
1036
+ if (node.retryOnFail === true) {
1037
+ if (node.maxTries !== undefined) {
1038
+ if (typeof node.maxTries !== 'number' || node.maxTries < 1) {
1039
+ result.errors.push({
1040
+ type: 'error',
1041
+ nodeId: node.id,
1042
+ nodeName: node.name,
1043
+ message: 'maxTries must be a positive number when retryOnFail is enabled'
1044
+ });
1045
+ }
1046
+ else if (node.maxTries > 10) {
1047
+ result.warnings.push({
1048
+ type: 'warning',
1049
+ nodeId: node.id,
1050
+ nodeName: node.name,
1051
+ message: `maxTries is set to ${node.maxTries}. Consider if this many retries is necessary.`
1052
+ });
1053
+ }
1054
+ }
1055
+ else {
1056
+ result.warnings.push({
1057
+ type: 'warning',
1058
+ nodeId: node.id,
1059
+ nodeName: node.name,
1060
+ message: 'retryOnFail is enabled but maxTries is not specified. Default is 3 attempts.'
1061
+ });
1062
+ }
1063
+ if (node.waitBetweenTries !== undefined) {
1064
+ if (typeof node.waitBetweenTries !== 'number' || node.waitBetweenTries < 0) {
1065
+ result.errors.push({
1066
+ type: 'error',
1067
+ nodeId: node.id,
1068
+ nodeName: node.name,
1069
+ message: 'waitBetweenTries must be a non-negative number (milliseconds)'
1070
+ });
1071
+ }
1072
+ else if (node.waitBetweenTries > 300000) {
1073
+ result.warnings.push({
1074
+ type: 'warning',
1075
+ nodeId: node.id,
1076
+ nodeName: node.name,
1077
+ message: `waitBetweenTries is set to ${node.waitBetweenTries}ms (${(node.waitBetweenTries / 1000).toFixed(1)}s). This seems excessive.`
1078
+ });
1079
+ }
1080
+ }
1081
+ }
1082
+ }
1083
+ if (node.alwaysOutputData !== undefined && typeof node.alwaysOutputData !== 'boolean') {
1084
+ result.errors.push({
1085
+ type: 'error',
1086
+ nodeId: node.id,
1087
+ nodeName: node.name,
1088
+ message: 'alwaysOutputData must be a boolean value'
1089
+ });
1090
+ }
1091
+ const hasErrorHandling = node.onError || node.continueOnFail || node.retryOnFail;
1092
+ if (isErrorProne && !hasErrorHandling) {
1093
+ const nodeTypeSimple = normalizedType.split('.').pop() || normalizedType;
1094
+ if (normalizedType.includes('httprequest')) {
1095
+ result.warnings.push({
1096
+ type: 'warning',
1097
+ nodeId: node.id,
1098
+ nodeName: node.name,
1099
+ message: 'HTTP Request node without error handling. Consider adding "onError: \'continueRegularOutput\'" for non-critical requests or "retryOnFail: true" for transient failures.'
1100
+ });
1101
+ }
1102
+ else if (normalizedType.includes('webhook')) {
1103
+ this.checkWebhookErrorHandling(node, normalizedType, result);
1104
+ }
1105
+ else if (errorProneNodeTypes.some(db => normalizedType.includes(db) && ['postgres', 'mysql', 'mongodb'].includes(db))) {
1106
+ result.warnings.push({
1107
+ type: 'warning',
1108
+ nodeId: node.id,
1109
+ nodeName: node.name,
1110
+ message: `Database operation without error handling. Consider adding "retryOnFail: true" for connection issues or "onError: \'continueRegularOutput\'" for non-critical queries.`
1111
+ });
1112
+ }
1113
+ else {
1114
+ result.warnings.push({
1115
+ type: 'warning',
1116
+ nodeId: node.id,
1117
+ nodeName: node.name,
1118
+ message: `${nodeTypeSimple} node without error handling. Consider using "onError" property for better error management.`
1119
+ });
1120
+ }
1121
+ }
1122
+ if (node.continueOnFail && node.retryOnFail) {
1123
+ result.warnings.push({
1124
+ type: 'warning',
1125
+ nodeId: node.id,
1126
+ nodeName: node.name,
1127
+ message: 'Both continueOnFail and retryOnFail are enabled. The node will retry first, then continue on failure.'
1128
+ });
1129
+ }
1130
+ if (node.executeOnce !== undefined && typeof node.executeOnce !== 'boolean') {
1131
+ result.errors.push({
1132
+ type: 'error',
1133
+ nodeId: node.id,
1134
+ nodeName: node.name,
1135
+ message: 'executeOnce must be a boolean value'
1136
+ });
1137
+ }
1138
+ if (node.disabled !== undefined && typeof node.disabled !== 'boolean') {
1139
+ result.errors.push({
1140
+ type: 'error',
1141
+ nodeId: node.id,
1142
+ nodeName: node.name,
1143
+ message: 'disabled must be a boolean value'
1144
+ });
1145
+ }
1146
+ if (node.notesInFlow !== undefined && typeof node.notesInFlow !== 'boolean') {
1147
+ result.errors.push({
1148
+ type: 'error',
1149
+ nodeId: node.id,
1150
+ nodeName: node.name,
1151
+ message: 'notesInFlow must be a boolean value'
1152
+ });
1153
+ }
1154
+ if (node.notes !== undefined && typeof node.notes !== 'string') {
1155
+ result.errors.push({
1156
+ type: 'error',
1157
+ nodeId: node.id,
1158
+ nodeName: node.name,
1159
+ message: 'notes must be a string value'
1160
+ });
1161
+ }
1162
+ if (node.executeOnce === true) {
1163
+ result.warnings.push({
1164
+ type: 'warning',
1165
+ nodeId: node.id,
1166
+ nodeName: node.name,
1167
+ message: 'executeOnce is enabled. This node will execute only once regardless of input items.'
1168
+ });
1169
+ }
1170
+ if ((node.continueOnFail || node.retryOnFail) && !node.alwaysOutputData) {
1171
+ if (normalizedType.includes('httprequest') || normalizedType.includes('webhook')) {
1172
+ result.suggestions.push(`Consider enabling alwaysOutputData on "${node.name}" to capture error responses for debugging`);
1173
+ }
1174
+ }
1175
+ }
1176
+ checkWebhookErrorHandling(node, normalizedType, result) {
1177
+ if (normalizedType.includes('respondtowebhook')) {
1178
+ return;
1179
+ }
1180
+ if (node.parameters?.responseMode === 'responseNode') {
1181
+ if (!node.onError && !node.continueOnFail) {
1182
+ result.errors.push({
1183
+ type: 'error',
1184
+ nodeId: node.id,
1185
+ nodeName: node.name,
1186
+ message: 'responseNode mode requires onError: "continueRegularOutput"'
1187
+ });
1188
+ }
1189
+ return;
1190
+ }
1191
+ result.warnings.push({
1192
+ type: 'warning',
1193
+ nodeId: node.id,
1194
+ nodeName: node.name,
1195
+ message: 'Webhook node without error handling. Consider adding "onError: \'continueRegularOutput\'" to prevent workflow failures from blocking webhook responses.'
1196
+ });
1197
+ }
1198
+ generateErrorHandlingSuggestions(workflow, result) {
1199
+ const nodesWithoutErrorHandling = workflow.nodes.filter(n => !n.disabled && !n.onError && !n.continueOnFail && !n.retryOnFail).length;
1200
+ if (nodesWithoutErrorHandling > 5 && workflow.nodes.length > 5) {
1201
+ result.suggestions.push('Most nodes lack error handling. Use "onError" property for modern error handling: "continueRegularOutput" (continue on error), "continueErrorOutput" (use error output), or "stopWorkflow" (stop execution).');
1202
+ }
1203
+ const nodesWithDeprecatedErrorHandling = workflow.nodes.filter(n => !n.disabled && n.continueOnFail === true).length;
1204
+ if (nodesWithDeprecatedErrorHandling > 0) {
1205
+ result.suggestions.push('Replace "continueOnFail: true" with "onError: \'continueRegularOutput\'" for better UI compatibility and control.');
1206
+ }
1207
+ }
1208
+ validateSplitInBatchesConnection(sourceNode, outputIndex, connection, nodeMap, result) {
1209
+ const targetNode = nodeMap.get(connection.node);
1210
+ if (!targetNode)
1211
+ return;
1212
+ if (outputIndex === 0) {
1213
+ const targetType = targetNode.type.toLowerCase();
1214
+ const targetName = targetNode.name.toLowerCase();
1215
+ if (targetType.includes('function') ||
1216
+ targetType.includes('code') ||
1217
+ targetType.includes('item') ||
1218
+ targetName.includes('process') ||
1219
+ targetName.includes('transform') ||
1220
+ targetName.includes('handle')) {
1221
+ const hasLoopBack = this.checkForLoopBack(targetNode.name, sourceNode.name, nodeMap);
1222
+ if (hasLoopBack) {
1223
+ result.errors.push({
1224
+ type: 'error',
1225
+ nodeId: sourceNode.id,
1226
+ nodeName: sourceNode.name,
1227
+ message: `SplitInBatches outputs appear reversed! Node "${targetNode.name}" is connected to output 0 ("done") but connects back to the loop. It should be connected to output 1 ("loop") instead. Remember: Output 0 = "done" (post-loop), Output 1 = "loop" (inside loop).`
1228
+ });
1229
+ }
1230
+ else {
1231
+ result.warnings.push({
1232
+ type: 'warning',
1233
+ nodeId: sourceNode.id,
1234
+ nodeName: sourceNode.name,
1235
+ message: `Node "${targetNode.name}" is connected to the "done" output (index 0) but appears to be a processing node. Consider connecting it to the "loop" output (index 1) if it should process items inside the loop.`
1236
+ });
1237
+ }
1238
+ }
1239
+ }
1240
+ else if (outputIndex === 1) {
1241
+ const targetType = targetNode.type.toLowerCase();
1242
+ const targetName = targetNode.name.toLowerCase();
1243
+ if (targetType.includes('aggregate') ||
1244
+ targetType.includes('merge') ||
1245
+ targetType.includes('email') ||
1246
+ targetType.includes('slack') ||
1247
+ targetName.includes('final') ||
1248
+ targetName.includes('complete') ||
1249
+ targetName.includes('summary') ||
1250
+ targetName.includes('report')) {
1251
+ result.warnings.push({
1252
+ type: 'warning',
1253
+ nodeId: sourceNode.id,
1254
+ nodeName: sourceNode.name,
1255
+ message: `Node "${targetNode.name}" is connected to the "loop" output (index 1) but appears to be a post-processing node. Consider connecting it to the "done" output (index 0) if it should run after all iterations complete.`
1256
+ });
1257
+ }
1258
+ const hasLoopBack = this.checkForLoopBack(targetNode.name, sourceNode.name, nodeMap);
1259
+ if (!hasLoopBack) {
1260
+ result.warnings.push({
1261
+ type: 'warning',
1262
+ nodeId: sourceNode.id,
1263
+ nodeName: sourceNode.name,
1264
+ message: `The "loop" output connects to "${targetNode.name}" but doesn't connect back to the SplitInBatches node. The last node in the loop should connect back to complete the iteration.`
1265
+ });
1266
+ }
1267
+ }
1268
+ }
1269
+ checkForLoopBack(startNode, targetNode, nodeMap, visited = new Set(), maxDepth = 50) {
1270
+ if (maxDepth <= 0)
1271
+ return false;
1272
+ if (visited.has(startNode))
1273
+ return false;
1274
+ visited.add(startNode);
1275
+ const node = nodeMap.get(startNode);
1276
+ if (!node)
1277
+ return false;
1278
+ const connections = this.currentWorkflow?.connections[startNode];
1279
+ if (!connections)
1280
+ return false;
1281
+ for (const [outputType, outputs] of Object.entries(connections)) {
1282
+ if (!Array.isArray(outputs))
1283
+ continue;
1284
+ for (const outputConnections of outputs) {
1285
+ if (!Array.isArray(outputConnections))
1286
+ continue;
1287
+ for (const conn of outputConnections) {
1288
+ if (conn.node === targetNode) {
1289
+ return true;
1290
+ }
1291
+ if (this.checkForLoopBack(conn.node, targetNode, nodeMap, visited, maxDepth - 1)) {
1292
+ return true;
1293
+ }
1294
+ }
1295
+ }
1296
+ }
1297
+ return false;
1298
+ }
1299
+ addErrorRecoverySuggestions(result) {
1300
+ const errorTypes = {
1301
+ nodeType: result.errors.filter(e => e.message.includes('node type') || e.message.includes('Node type')),
1302
+ connection: result.errors.filter(e => e.message.includes('connection') || e.message.includes('Connection')),
1303
+ structure: result.errors.filter(e => e.message.includes('structure') || e.message.includes('nodes must be')),
1304
+ configuration: result.errors.filter(e => e.message.includes('property') || e.message.includes('field')),
1305
+ typeVersion: result.errors.filter(e => e.message.includes('typeVersion'))
1306
+ };
1307
+ if (errorTypes.nodeType.length > 0) {
1308
+ result.suggestions.unshift('🔧 RECOVERY: Invalid node types detected. Use these patterns:', ' • For core nodes: "n8n-nodes-base.nodeName" (e.g., "n8n-nodes-base.webhook")', ' • For AI nodes: "@n8n/n8n-nodes-langchain.nodeName"', ' • Never use just the node name without package prefix');
1309
+ }
1310
+ if (errorTypes.connection.length > 0) {
1311
+ result.suggestions.unshift('🔧 RECOVERY: Connection errors detected. Fix with:', ' • Use node NAMES in connections, not IDs or types', ' • Structure: { "Source Node Name": { "main": [[{ "node": "Target Node Name", "type": "main", "index": 0 }]] } }', ' • Ensure all referenced nodes exist in the workflow');
1312
+ }
1313
+ if (errorTypes.structure.length > 0) {
1314
+ result.suggestions.unshift('🔧 RECOVERY: Workflow structure errors. Fix with:', ' • Ensure "nodes" is an array: "nodes": [...]', ' • Ensure "connections" is an object: "connections": {...}', ' • Add at least one node to create a valid workflow');
1315
+ }
1316
+ if (errorTypes.configuration.length > 0) {
1317
+ result.suggestions.unshift('🔧 RECOVERY: Node configuration errors. Fix with:', ' • Check required fields using validate_node_minimal first', ' • Use get_node_essentials to see what fields are needed', ' • Ensure operation-specific fields match the node\'s requirements');
1318
+ }
1319
+ if (errorTypes.typeVersion.length > 0) {
1320
+ result.suggestions.unshift('🔧 RECOVERY: TypeVersion errors. Fix with:', ' • Add "typeVersion": 1 (or latest version) to each node', ' • Use get_node_info to check the correct version for each node type');
1321
+ }
1322
+ if (result.errors.length > 3) {
1323
+ result.suggestions.push('📋 SUGGESTED WORKFLOW: Too many errors detected. Try this approach:', ' 1. Fix structural issues first (nodes array, connections object)', ' 2. Validate node types and fix invalid ones', ' 3. Add required typeVersion to all nodes', ' 4. Test connections step by step', ' 5. Use validate_node_minimal on individual nodes to verify configuration');
1324
+ }
1325
+ }
1326
+ }
1327
+ exports.WorkflowValidator = WorkflowValidator;
1328
+ //# sourceMappingURL=workflow-validator.js.map