@path58/n8n-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_INSTALL.md +223 -0
- package/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/autofix/suggestion-fixers/deprecated-node-fixer.js +465 -0
- package/dist/autofix/suggestion-fixers/deprecated-node-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/fixer-registry.js +495 -0
- package/dist/autofix/suggestion-fixers/fixer-registry.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l1-structure-fixer.js +639 -0
- package/dist/autofix/suggestion-fixers/l1-structure-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l4-connection-fixer.js +449 -0
- package/dist/autofix/suggestion-fixers/l4-connection-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l5-parameter-fixer.js +575 -0
- package/dist/autofix/suggestion-fixers/l5-parameter-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l5-typeversion-fixer.js +431 -0
- package/dist/autofix/suggestion-fixers/l5-typeversion-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l5-webhook-path-fixer.js +356 -0
- package/dist/autofix/suggestion-fixers/l5-webhook-path-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l6-ai-tool-variant-fixer.js +618 -0
- package/dist/autofix/suggestion-fixers/l6-ai-tool-variant-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l6-pattern-fixer.js +1475 -0
- package/dist/autofix/suggestion-fixers/l6-pattern-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/llm-fixer.js +716 -0
- package/dist/autofix/suggestion-fixers/llm-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/missing-credential-fixer.js +336 -0
- package/dist/autofix/suggestion-fixers/missing-credential-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/types.js +29 -0
- package/dist/autofix/suggestion-fixers/types.js.map +1 -0
- package/dist/autofix/suggestion-fixers/typo-fixer.js +197 -0
- package/dist/autofix/suggestion-fixers/typo-fixer.js.map +1 -0
- package/dist/classification/certification-engine.js +208 -0
- package/dist/classification/certification-engine.js.map +1 -0
- package/dist/classification/feedback-collector.js +516 -0
- package/dist/classification/feedback-collector.js.map +1 -0
- package/dist/classification/l5-parameter-analyzer.js +670 -0
- package/dist/classification/l5-parameter-analyzer.js.map +1 -0
- package/dist/classification/l6-graph-analyzer.js +613 -0
- package/dist/classification/l6-graph-analyzer.js.map +1 -0
- package/dist/classification/severity-classifier.js +237 -0
- package/dist/classification/severity-classifier.js.map +1 -0
- package/dist/config/env.js +280 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/env.schema.js +234 -0
- package/dist/config/env.schema.js.map +1 -0
- package/dist/config/scraperEnv.js +55 -0
- package/dist/config/scraperEnv.js.map +1 -0
- package/dist/db/postgresClient.js +38 -0
- package/dist/db/postgresClient.js.map +1 -0
- package/dist/db/scraperDb.js +6 -0
- package/dist/db/scraperDb.js.map +1 -0
- package/dist/db/scraperPostgresClient.js +118 -0
- package/dist/db/scraperPostgresClient.js.map +1 -0
- package/dist/db/validationRepository.js +55 -0
- package/dist/db/validationRepository.js.map +1 -0
- package/dist/db/validatorPostgresClient.js +248 -0
- package/dist/db/validatorPostgresClient.js.map +1 -0
- package/dist/db/workflowInstanceMappingRepository.js +128 -0
- package/dist/db/workflowInstanceMappingRepository.js.map +1 -0
- package/dist/errors/AppError.js +156 -0
- package/dist/errors/AppError.js.map +1 -0
- package/dist/errors/index.js +7 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/factory/error-to-problem-mappers.js +385 -0
- package/dist/factory/error-to-problem-mappers.js.map +1 -0
- package/dist/factory/gap-recorder.js +260 -0
- package/dist/factory/gap-recorder.js.map +1 -0
- package/dist/factory/problem-recorder.js +94 -0
- package/dist/factory/problem-recorder.js.map +1 -0
- package/dist/factory/warning-to-gap-mappers.js +493 -0
- package/dist/factory/warning-to-gap-mappers.js.map +1 -0
- package/dist/factory/workflow-normalizer.js +247 -0
- package/dist/factory/workflow-normalizer.js.map +1 -0
- package/dist/mcp/adapters/catalog.js +13 -0
- package/dist/mcp/adapters/catalog.js.map +1 -0
- package/dist/mcp/adapters/index.js +36 -0
- package/dist/mcp/adapters/index.js.map +1 -0
- package/dist/mcp/adapters/supabase-catalog.js +467 -0
- package/dist/mcp/adapters/supabase-catalog.js.map +1 -0
- package/dist/mcp/adapters/test-catalog-adapter.js +100 -0
- package/dist/mcp/adapters/test-catalog-adapter.js.map +1 -0
- package/dist/mcp/adapters/validation.js +258 -0
- package/dist/mcp/adapters/validation.js.map +1 -0
- package/dist/mcp/build-email-workflow.js +113 -0
- package/dist/mcp/build-email-workflow.js.map +1 -0
- package/dist/mcp/config.js +22 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/formatters/errors.js +217 -0
- package/dist/mcp/formatters/errors.js.map +1 -0
- package/dist/mcp/formatters/index.js +12 -0
- package/dist/mcp/formatters/index.js.map +1 -0
- package/dist/mcp/formatters/response.js +141 -0
- package/dist/mcp/formatters/response.js.map +1 -0
- package/dist/mcp/quick-test.js +33 -0
- package/dist/mcp/quick-test.js.map +1 -0
- package/dist/mcp/server.js +70 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/test-mcp-error.js +81 -0
- package/dist/mcp/test-mcp-error.js.map +1 -0
- package/dist/mcp/test-mcp.js +80 -0
- package/dist/mcp/test-mcp.js.map +1 -0
- package/dist/mcp/tools/fixes/expression-fixes.js +166 -0
- package/dist/mcp/tools/fixes/expression-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/flow-fixes.js +155 -0
- package/dist/mcp/tools/fixes/flow-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/index.js +91 -0
- package/dist/mcp/tools/fixes/index.js.map +1 -0
- package/dist/mcp/tools/fixes/node-fixes.js +233 -0
- package/dist/mcp/tools/fixes/node-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/parameter-fixes.js +277 -0
- package/dist/mcp/tools/fixes/parameter-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/types.js +10 -0
- package/dist/mcp/tools/fixes/types.js.map +1 -0
- package/dist/mcp/tools/handlers/check-parameter.js +300 -0
- package/dist/mcp/tools/handlers/check-parameter.js.map +1 -0
- package/dist/mcp/tools/handlers/find-similar-pattern.js +121 -0
- package/dist/mcp/tools/handlers/find-similar-pattern.js.map +1 -0
- package/dist/mcp/tools/handlers/get-node-info.js +131 -0
- package/dist/mcp/tools/handlers/get-node-info.js.map +1 -0
- package/dist/mcp/tools/handlers/get-operation-schema.js +141 -0
- package/dist/mcp/tools/handlers/get-operation-schema.js.map +1 -0
- package/dist/mcp/tools/handlers/list-nodes.js +126 -0
- package/dist/mcp/tools/handlers/list-nodes.js.map +1 -0
- package/dist/mcp/tools/handlers/list-operations.js +138 -0
- package/dist/mcp/tools/handlers/list-operations.js.map +1 -0
- package/dist/mcp/tools/handlers/suggest-fix.js +120 -0
- package/dist/mcp/tools/handlers/suggest-fix.js.map +1 -0
- package/dist/mcp/tools/handlers/validate-workflow.js +92 -0
- package/dist/mcp/tools/handlers/validate-workflow.js.map +1 -0
- package/dist/mcp/tools/index.js +190 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/schemas.js +195 -0
- package/dist/mcp/tools/schemas.js.map +1 -0
- package/dist/mcp/tools/validate.js +95 -0
- package/dist/mcp/tools/validate.js.map +1 -0
- package/dist/mcp/types/mcp.js +7 -0
- package/dist/mcp/types/mcp.js.map +1 -0
- package/dist/mcp/utils/timeout.js +78 -0
- package/dist/mcp/utils/timeout.js.map +1 -0
- package/dist/services/BatchProcessor.js +433 -0
- package/dist/services/BatchProcessor.js.map +1 -0
- package/dist/services/CheckpointManager.js +281 -0
- package/dist/services/CheckpointManager.js.map +1 -0
- package/dist/services/CostCalculator.js +211 -0
- package/dist/services/CostCalculator.js.map +1 -0
- package/dist/services/EmbeddingCache.js +68 -0
- package/dist/services/EmbeddingCache.js.map +1 -0
- package/dist/services/EmbeddingService.js +143 -0
- package/dist/services/EmbeddingService.js.map +1 -0
- package/dist/services/RankingService.js +81 -0
- package/dist/services/RankingService.js.map +1 -0
- package/dist/services/RedisCache.js +376 -0
- package/dist/services/RedisCache.js.map +1 -0
- package/dist/services/RedisCatalogCache.js +680 -0
- package/dist/services/RedisCatalogCache.js.map +1 -0
- package/dist/services/ResumeManager.js +252 -0
- package/dist/services/ResumeManager.js.map +1 -0
- package/dist/services/SearchService.js +282 -0
- package/dist/services/SearchService.js.map +1 -0
- package/dist/services/SemanticCatalogSearch.js +405 -0
- package/dist/services/SemanticCatalogSearch.js.map +1 -0
- package/dist/services/ValidationCache.js +157 -0
- package/dist/services/ValidationCache.js.map +1 -0
- package/dist/services/WorkflowPipelineService.js +1997 -0
- package/dist/services/WorkflowPipelineService.js.map +1 -0
- package/dist/services/catalog/index.js +34 -0
- package/dist/services/catalog/index.js.map +1 -0
- package/dist/services/catalog/interfaces.js +17 -0
- package/dist/services/catalog/interfaces.js.map +1 -0
- package/dist/services/catalog/loaders.js +169 -0
- package/dist/services/catalog/loaders.js.map +1 -0
- package/dist/services/catalog/types.js +138 -0
- package/dist/services/catalog/types.js.map +1 -0
- package/dist/services/documentation-normalization/docUrlUtils.js +88 -0
- package/dist/services/documentation-normalization/docUrlUtils.js.map +1 -0
- package/dist/services/error-quality/ErrorQualityService.js +262 -0
- package/dist/services/error-quality/ErrorQualityService.js.map +1 -0
- package/dist/services/error-quality/analyzers/CredentialAnalyzer.js +260 -0
- package/dist/services/error-quality/analyzers/CredentialAnalyzer.js.map +1 -0
- package/dist/services/error-quality/analyzers/IssuePredictor.js +380 -0
- package/dist/services/error-quality/analyzers/IssuePredictor.js.map +1 -0
- package/dist/services/error-quality/analyzers/MockCoverageAnalyzer.js +267 -0
- package/dist/services/error-quality/analyzers/MockCoverageAnalyzer.js.map +1 -0
- package/dist/services/error-quality/data/ErrorPatternSeeder.js +963 -0
- package/dist/services/error-quality/data/ErrorPatternSeeder.js.map +1 -0
- package/dist/services/error-quality/index.js +25 -0
- package/dist/services/error-quality/index.js.map +1 -0
- package/dist/services/error-quality/reports/ReportGenerator.js +343 -0
- package/dist/services/error-quality/reports/ReportGenerator.js.map +1 -0
- package/dist/services/error-quality/taxonomy/ErrorTaxonomy.js +698 -0
- package/dist/services/error-quality/taxonomy/ErrorTaxonomy.js.map +1 -0
- package/dist/services/error-quality/types.js +11 -0
- package/dist/services/error-quality/types.js.map +1 -0
- package/dist/services/progress/ProgressTracker.js +288 -0
- package/dist/services/progress/ProgressTracker.js.map +1 -0
- package/dist/services/progress/formatters.js +122 -0
- package/dist/services/progress/formatters.js.map +1 -0
- package/dist/services/progress/index.js +36 -0
- package/dist/services/progress/index.js.map +1 -0
- package/dist/services/progress/types.js +7 -0
- package/dist/services/progress/types.js.map +1 -0
- package/dist/services/search/embeddingGenerator.js +112 -0
- package/dist/services/search/embeddingGenerator.js.map +1 -0
- package/dist/types/aiCapabilities.js +7 -0
- package/dist/types/aiCapabilities.js.map +1 -0
- package/dist/types/aiConfigSchema.js +7 -0
- package/dist/types/aiConfigSchema.js.map +1 -0
- package/dist/utils/bannerLogger.js +186 -0
- package/dist/utils/bannerLogger.js.map +1 -0
- package/dist/utils/bannerService.js +23 -0
- package/dist/utils/bannerService.js.map +1 -0
- package/dist/utils/bannerServiceAdapter.js +54 -0
- package/dist/utils/bannerServiceAdapter.js.map +1 -0
- package/dist/utils/batchLogger.js +171 -0
- package/dist/utils/batchLogger.js.map +1 -0
- package/dist/utils/bottomStickyBanner.js +239 -0
- package/dist/utils/bottomStickyBanner.js.map +1 -0
- package/dist/utils/credentialMatcher.js +206 -0
- package/dist/utils/credentialMatcher.js.map +1 -0
- package/dist/utils/credentialNormalizer.js +442 -0
- package/dist/utils/credentialNormalizer.js.map +1 -0
- package/dist/utils/integratedBannerLogger.js +59 -0
- package/dist/utils/integratedBannerLogger.js.map +1 -0
- package/dist/utils/n8nSourceGit.js +195 -0
- package/dist/utils/n8nSourceGit.js.map +1 -0
- package/dist/utils/nodeTypeNormalizer.js +131 -0
- package/dist/utils/nodeTypeNormalizer.js.map +1 -0
- package/dist/utils/openaiClient.js +397 -0
- package/dist/utils/openaiClient.js.map +1 -0
- package/dist/utils/productionLogger.js +16 -0
- package/dist/utils/productionLogger.js.map +1 -0
- package/dist/utils/progressBarBanner.js +132 -0
- package/dist/utils/progressBarBanner.js.map +1 -0
- package/dist/utils/scriptHeartbeat.js +117 -0
- package/dist/utils/scriptHeartbeat.js.map +1 -0
- package/dist/utils/scriptLogger.js +125 -0
- package/dist/utils/scriptLogger.js.map +1 -0
- package/dist/utils/scriptRunner.js +95 -0
- package/dist/utils/scriptRunner.js.map +1 -0
- package/dist/utils/scriptTimeout.js +128 -0
- package/dist/utils/scriptTimeout.js.map +1 -0
- package/dist/utils/scriptWrapper.js +219 -0
- package/dist/utils/scriptWrapper.js.map +1 -0
- package/dist/utils/stickyBanner.js +226 -0
- package/dist/utils/stickyBanner.js.map +1 -0
- package/dist/utils/terminalSpinner.js +97 -0
- package/dist/utils/terminalSpinner.js.map +1 -0
- package/dist/utils/threeLineBanner.js +427 -0
- package/dist/utils/threeLineBanner.js.map +1 -0
- package/dist/utils/validatorCheckpointManager.js +170 -0
- package/dist/utils/validatorCheckpointManager.js.map +1 -0
- package/dist/utils/validatorConnectionManager.js +124 -0
- package/dist/utils/validatorConnectionManager.js.map +1 -0
- package/dist/validation/catalog.js +56 -0
- package/dist/validation/catalog.js.map +1 -0
- package/dist/validation/config/deprecated-nodes.js +234 -0
- package/dist/validation/config/deprecated-nodes.js.map +1 -0
- package/dist/validation/config/l6-severity.js +227 -0
- package/dist/validation/config/l6-severity.js.map +1 -0
- package/dist/validation/config/terminal-nodes.js +132 -0
- package/dist/validation/config/terminal-nodes.js.map +1 -0
- package/dist/validation/config/unreachable-nodes.js +67 -0
- package/dist/validation/config/unreachable-nodes.js.map +1 -0
- package/dist/validation/core.js +47 -0
- package/dist/validation/core.js.map +1 -0
- package/dist/validation/docExtraction.js +12 -0
- package/dist/validation/docExtraction.js.map +1 -0
- package/dist/validation/dryRunMockRunner.js +128 -0
- package/dist/validation/dryRunMockRunner.js.map +1 -0
- package/dist/validation/fixtureEngine.js +61 -0
- package/dist/validation/fixtureEngine.js.map +1 -0
- package/dist/validation/index.js +15 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/k-levels/k2-blockers.js +222 -0
- package/dist/validation/k-levels/k2-blockers.js.map +1 -0
- package/dist/validation/l1-structure.js +296 -0
- package/dist/validation/l1-structure.js.map +1 -0
- package/dist/validation/l2-nodes.js +282 -0
- package/dist/validation/l2-nodes.js.map +1 -0
- package/dist/validation/l3-credentials.js +322 -0
- package/dist/validation/l3-credentials.js.map +1 -0
- package/dist/validation/l4-connections.js +698 -0
- package/dist/validation/l4-connections.js.map +1 -0
- package/dist/validation/l5-parameters.js +803 -0
- package/dist/validation/l5-parameters.js.map +1 -0
- package/dist/validation/l6-checks/ai-tool-variants.js +407 -0
- package/dist/validation/l6-checks/ai-tool-variants.js.map +1 -0
- package/dist/validation/l6-checks/catalog-checks.js +260 -0
- package/dist/validation/l6-checks/catalog-checks.js.map +1 -0
- package/dist/validation/l6-checks/data-contracts.js +197 -0
- package/dist/validation/l6-checks/data-contracts.js.map +1 -0
- package/dist/validation/l6-checks/deprecation.js +133 -0
- package/dist/validation/l6-checks/deprecation.js.map +1 -0
- package/dist/validation/l6-checks/error-handling.js +193 -0
- package/dist/validation/l6-checks/error-handling.js.map +1 -0
- package/dist/validation/l6-checks/expression-syntax.js +387 -0
- package/dist/validation/l6-checks/expression-syntax.js.map +1 -0
- package/dist/validation/l6-checks/flow-integrity.js +504 -0
- package/dist/validation/l6-checks/flow-integrity.js.map +1 -0
- package/dist/validation/l6-checks/index.js +106 -0
- package/dist/validation/l6-checks/index.js.map +1 -0
- package/dist/validation/l6-checks/loops.js +370 -0
- package/dist/validation/l6-checks/loops.js.map +1 -0
- package/dist/validation/l6-checks/performance.js +182 -0
- package/dist/validation/l6-checks/performance.js.map +1 -0
- package/dist/validation/l6-checks/security.js +273 -0
- package/dist/validation/l6-checks/security.js.map +1 -0
- package/dist/validation/l6-patterns.js +472 -0
- package/dist/validation/l6-patterns.js.map +1 -0
- package/dist/validation/mockLevelResolver.js +95 -0
- package/dist/validation/mockLevelResolver.js.map +1 -0
- package/dist/validation/n8nApiClient.js +21 -0
- package/dist/validation/n8nApiClient.js.map +1 -0
- package/dist/validation/n8nCli.js +87 -0
- package/dist/validation/n8nCli.js.map +1 -0
- package/dist/validation/types.js +8 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/validation/usageStats.js +82 -0
- package/dist/validation/usageStats.js.map +1 -0
- package/package.json +274 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L6 Error Handling Checks
|
|
3
|
+
*
|
|
4
|
+
* RAG-2.2.40: L6 Pattern Validation
|
|
5
|
+
* Created: January 5, 2026
|
|
6
|
+
*
|
|
7
|
+
* Validates error handling configuration (STRICT MODE):
|
|
8
|
+
* - ERROR_OUTPUT_UNCONNECTED: Error output exists but not connected
|
|
9
|
+
* - NO_RETRY_ON_HTTP: HTTP/API nodes without retry configuration
|
|
10
|
+
*
|
|
11
|
+
* Fix for PM bug #7: Check node-level settings (node.continueOnFail, node.retryOnFail)
|
|
12
|
+
* NOT parameters.continueOnFail
|
|
13
|
+
*/
|
|
14
|
+
import { getL6Severity, blocksCertification } from '../config/l6-severity.js';
|
|
15
|
+
/**
|
|
16
|
+
* Check if node has error handling configured
|
|
17
|
+
*
|
|
18
|
+
* n8n error handling settings (at NODE level, not in parameters):
|
|
19
|
+
* - node.continueOnFail: Continue workflow on error
|
|
20
|
+
* - node.retryOnFail: Retry on failure
|
|
21
|
+
* - node.maxTries: Number of retry attempts
|
|
22
|
+
* - node.waitBetweenTries: Delay between retries
|
|
23
|
+
* - node.onError: Error handling behavior
|
|
24
|
+
*/
|
|
25
|
+
function hasErrorHandling(node) {
|
|
26
|
+
return (node.continueOnFail === true ||
|
|
27
|
+
node.retryOnFail === true ||
|
|
28
|
+
node.onError !== undefined);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if node has retry configuration
|
|
32
|
+
*/
|
|
33
|
+
function hasRetryConfig(node) {
|
|
34
|
+
return (node.retryOnFail === true &&
|
|
35
|
+
typeof node.maxTries === 'number' &&
|
|
36
|
+
node.maxTries > 0);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check 1: ERROR_OUTPUT_UNCONNECTED
|
|
40
|
+
*
|
|
41
|
+
* Nodes with error outputs that aren't connected will silently fail.
|
|
42
|
+
* This is critical for error-prone nodes (HTTP, DB, FTP, Email, etc.)
|
|
43
|
+
*
|
|
44
|
+
* Algorithm:
|
|
45
|
+
* 1. Find all error-prone nodes
|
|
46
|
+
* 2. Check if they have error handling configured
|
|
47
|
+
* 3. If they have error outputs, check if connected
|
|
48
|
+
* 4. If unconnected, flag as error (STRICT MODE)
|
|
49
|
+
*/
|
|
50
|
+
export function checkErrorOutputUnconnected(context) {
|
|
51
|
+
const { catalogCache, workflow } = context;
|
|
52
|
+
const errors = [];
|
|
53
|
+
// Guard: malformed workflow JSON (e.g., missing nodes/connections) should not crash L6.
|
|
54
|
+
if (!workflow.nodes || !Array.isArray(workflow.nodes) || !workflow.connections) {
|
|
55
|
+
return errors;
|
|
56
|
+
}
|
|
57
|
+
for (const node of workflow.nodes) {
|
|
58
|
+
// Only check error-prone nodes
|
|
59
|
+
if (!catalogCache.errorProneTypes.has(node.type.toLowerCase())) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// If node already has error handling configured, skip
|
|
63
|
+
if (hasErrorHandling(node)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// Check if error output exists in connections
|
|
67
|
+
const outgoing = workflow.connections[node.name];
|
|
68
|
+
const hasErrorOutput = outgoing && 'error' in outgoing;
|
|
69
|
+
const errorConnected = hasErrorOutput &&
|
|
70
|
+
outgoing.error &&
|
|
71
|
+
outgoing.error.length > 0 &&
|
|
72
|
+
outgoing.error.some(group => group.length > 0);
|
|
73
|
+
// If error output exists but is not connected → ERROR
|
|
74
|
+
if (hasErrorOutput && !errorConnected) {
|
|
75
|
+
const code = 'ERROR_OUTPUT_UNCONNECTED';
|
|
76
|
+
errors.push({
|
|
77
|
+
code: 'ERROR_OUTPUT_UNCONNECTED',
|
|
78
|
+
message: `Node "${node.name}" has an error output but it is not connected. Errors will be silently ignored.`,
|
|
79
|
+
path: `nodes.${node.name}`,
|
|
80
|
+
node_name: node.name,
|
|
81
|
+
node_type: node.type,
|
|
82
|
+
severity: getL6Severity(code),
|
|
83
|
+
blocks_certification: blocksCertification(code),
|
|
84
|
+
suggested_fix: {
|
|
85
|
+
id: `fix-error-output-${node.name}`,
|
|
86
|
+
fix_type: 'connect_error_output',
|
|
87
|
+
confidence: 0.85,
|
|
88
|
+
auto_applicable: false, // Need to know where to connect it
|
|
89
|
+
description: `Connect error output of "${node.name}" to error handler or enable continueOnFail`,
|
|
90
|
+
target_node: node.name,
|
|
91
|
+
patch: {
|
|
92
|
+
// Option 1: Add error handling
|
|
93
|
+
node_settings: {
|
|
94
|
+
continueOnFail: true,
|
|
95
|
+
onError: 'continueRegularOutput',
|
|
96
|
+
},
|
|
97
|
+
// Option 2: Connect error output (requires target)
|
|
98
|
+
new_connection: undefined, // User must specify target
|
|
99
|
+
},
|
|
100
|
+
context: {
|
|
101
|
+
has_error_output: true,
|
|
102
|
+
error_output_connected: false,
|
|
103
|
+
suggestion: 'Either connect error output or enable continueOnFail',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return errors;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Check 2: NO_RETRY_ON_HTTP
|
|
113
|
+
*
|
|
114
|
+
* HTTP/API nodes without retry configuration are prone to transient failures.
|
|
115
|
+
* Data shows 94.2% of HTTP nodes lack retry config.
|
|
116
|
+
*
|
|
117
|
+
* STRICT MODE: Treat missing retry on HTTP as an ERROR (tests and scoring expect this).
|
|
118
|
+
*/
|
|
119
|
+
export function checkNoRetryOnHttp(context) {
|
|
120
|
+
const { catalogCache, workflow } = context;
|
|
121
|
+
const errors = [];
|
|
122
|
+
// Guard: malformed workflow JSON (e.g., missing nodes) should not crash L6.
|
|
123
|
+
if (!workflow.nodes || !Array.isArray(workflow.nodes)) {
|
|
124
|
+
return errors;
|
|
125
|
+
}
|
|
126
|
+
// Common HTTP/API node types
|
|
127
|
+
const httpNodeTypes = new Set([
|
|
128
|
+
'n8n-nodes-base.httprequest',
|
|
129
|
+
'n8n-nodes-base.httpRequest', // Alternative casing
|
|
130
|
+
'httprequest',
|
|
131
|
+
'httpRequest',
|
|
132
|
+
]);
|
|
133
|
+
for (const node of workflow.nodes) {
|
|
134
|
+
const nodeTypeLower = node.type.toLowerCase();
|
|
135
|
+
// Check if it's an HTTP node
|
|
136
|
+
const isHttpNode = httpNodeTypes.has(nodeTypeLower) ||
|
|
137
|
+
catalogCache.errorProneTypes.has(nodeTypeLower) && nodeTypeLower.includes('http');
|
|
138
|
+
if (!isHttpNode) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
// Check if retry is configured
|
|
142
|
+
if (hasRetryConfig(node)) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const code = 'NO_RETRY_ON_HTTP';
|
|
146
|
+
errors.push({
|
|
147
|
+
code: 'NO_RETRY_ON_HTTP',
|
|
148
|
+
message: `HTTP node "${node.name}" has no retry configuration. Consider adding retry for transient failures.`,
|
|
149
|
+
node_name: node.name,
|
|
150
|
+
node_type: node.type,
|
|
151
|
+
severity: getL6Severity(code),
|
|
152
|
+
blocks_certification: blocksCertification(code),
|
|
153
|
+
suggested_fix: {
|
|
154
|
+
id: `fix-no-retry-${node.name}`,
|
|
155
|
+
fix_type: 'add_retry',
|
|
156
|
+
confidence: 0.90, // High confidence - standard retry config
|
|
157
|
+
auto_applicable: true, // Safe to auto-apply standard retry settings
|
|
158
|
+
description: `Add retry configuration to "${node.name}" (3 retries with 1000ms delay)`,
|
|
159
|
+
target_node: node.name,
|
|
160
|
+
patch: {
|
|
161
|
+
node_settings: {
|
|
162
|
+
retryOnFail: true,
|
|
163
|
+
maxTries: 3,
|
|
164
|
+
waitBetweenTries: 1000, // 1 second
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
context: {
|
|
168
|
+
reason: 'HTTP nodes should have retry for transient failures',
|
|
169
|
+
recommended_retries: 3,
|
|
170
|
+
recommended_delay_ms: 1000,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return errors;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Run all error handling checks in parallel
|
|
179
|
+
*/
|
|
180
|
+
export async function checkErrorHandling(context) {
|
|
181
|
+
const startTime = performance.now();
|
|
182
|
+
// Run checks in parallel
|
|
183
|
+
const [errorOutputErrors, noRetryErrors,] = await Promise.all([
|
|
184
|
+
Promise.resolve(checkErrorOutputUnconnected(context)),
|
|
185
|
+
Promise.resolve(checkNoRetryOnHttp(context)),
|
|
186
|
+
]);
|
|
187
|
+
const duration = performance.now() - startTime;
|
|
188
|
+
return {
|
|
189
|
+
errors: [...errorOutputErrors, ...noRetryErrors],
|
|
190
|
+
warnings: [],
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=error-handling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handling.js","sourceRoot":"","sources":["../../../src/validation/l6-checks/error-handling.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L6 Expression Syntax Checks
|
|
3
|
+
*
|
|
4
|
+
* RAG-2.2.40: L6 Pattern Validation
|
|
5
|
+
* Created: January 5, 2026
|
|
6
|
+
*
|
|
7
|
+
* Validates n8n expression syntax:
|
|
8
|
+
* - INVALID_EXPRESSION_SYNTAX: Expression cannot be parsed
|
|
9
|
+
* - UNBALANCED_BRACES: {{ }} braces don't match
|
|
10
|
+
*
|
|
11
|
+
* Fix for PM bug #8: Handle nested braces properly
|
|
12
|
+
* Cannot use simple regex [^}]* - need character-by-character parsing
|
|
13
|
+
*/
|
|
14
|
+
import { getL6Severity, blocksCertification } from '../config/l6-severity.js';
|
|
15
|
+
/**
|
|
16
|
+
* Extract all expressions from a value (string or nested object)
|
|
17
|
+
*/
|
|
18
|
+
function extractExpressions(value, path = '') {
|
|
19
|
+
const expressions = [];
|
|
20
|
+
if (typeof value === 'string') {
|
|
21
|
+
// Find all {{ ... }} patterns
|
|
22
|
+
// Use robust parsing for nested braces
|
|
23
|
+
const matches = findExpressionsInString(value);
|
|
24
|
+
for (const match of matches) {
|
|
25
|
+
expressions.push({ expression: match, path });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else if (Array.isArray(value)) {
|
|
29
|
+
value.forEach((item, index) => {
|
|
30
|
+
expressions.push(...extractExpressions(item, `${path}[${index}]`));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else if (value && typeof value === 'object') {
|
|
34
|
+
for (const [key, val] of Object.entries(value)) {
|
|
35
|
+
const newPath = path ? `${path}.${key}` : key;
|
|
36
|
+
expressions.push(...extractExpressions(val, newPath));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return expressions;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Find all {{ }} expressions in a string, handling nested braces
|
|
43
|
+
*
|
|
44
|
+
* Fix for PM bug #8: Proper nested brace handling
|
|
45
|
+
*
|
|
46
|
+
* Algorithm:
|
|
47
|
+
* 1. Character-by-character scan
|
|
48
|
+
* 2. Track brace depth
|
|
49
|
+
* 3. Extract when depth returns to 0
|
|
50
|
+
*
|
|
51
|
+
* Example: "{{ $json.items.filter(x => { return x.active; }) }}"
|
|
52
|
+
* Should extract the entire expression, not stop at first }
|
|
53
|
+
*/
|
|
54
|
+
function findExpressionsInString(str) {
|
|
55
|
+
const expressions = [];
|
|
56
|
+
let i = 0;
|
|
57
|
+
while (i < str.length - 1) {
|
|
58
|
+
// Look for opening {{
|
|
59
|
+
if (str[i] === '{' && str[i + 1] === '{') {
|
|
60
|
+
const startIndex = i;
|
|
61
|
+
i += 2; // Skip past {{
|
|
62
|
+
let depth = 1; // Start at depth 1 (we've seen {{)
|
|
63
|
+
let braceCount = 0; // Track inner {} pairs
|
|
64
|
+
// Scan until we find matching }}
|
|
65
|
+
while (i < str.length - 1 && depth > 0) {
|
|
66
|
+
if (str[i] === '{' && str[i + 1] === '{') {
|
|
67
|
+
depth++;
|
|
68
|
+
i += 2;
|
|
69
|
+
}
|
|
70
|
+
else if (str[i] === '}' && str[i + 1] === '}') {
|
|
71
|
+
depth--;
|
|
72
|
+
i += 2;
|
|
73
|
+
if (depth === 0) {
|
|
74
|
+
// Found matching }}
|
|
75
|
+
const expression = str.substring(startIndex, i);
|
|
76
|
+
expressions.push(expression);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (str[i] === '{') {
|
|
80
|
+
braceCount++;
|
|
81
|
+
i++;
|
|
82
|
+
}
|
|
83
|
+
else if (str[i] === '}') {
|
|
84
|
+
braceCount--;
|
|
85
|
+
i++;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
i++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// If we exited loop without depth === 0, expression is unbalanced
|
|
92
|
+
if (depth > 0) {
|
|
93
|
+
expressions.push(str.substring(startIndex)); // Include unbalanced expression for error reporting
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
i++;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return expressions;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check if expression has balanced {{ }} pairs
|
|
104
|
+
*/
|
|
105
|
+
function hasBalancedBraces(expression) {
|
|
106
|
+
let outerDepth = 0; // Track {{ }} depth
|
|
107
|
+
let innerDepth = 0; // Track { } depth inside expression
|
|
108
|
+
let i = 0;
|
|
109
|
+
while (i < expression.length - 1) {
|
|
110
|
+
if (expression[i] === '{' && expression[i + 1] === '{') {
|
|
111
|
+
outerDepth++;
|
|
112
|
+
i += 2;
|
|
113
|
+
}
|
|
114
|
+
else if (expression[i] === '}' && expression[i + 1] === '}') {
|
|
115
|
+
outerDepth--;
|
|
116
|
+
i += 2;
|
|
117
|
+
}
|
|
118
|
+
else if (expression[i] === '{') {
|
|
119
|
+
innerDepth++;
|
|
120
|
+
i++;
|
|
121
|
+
}
|
|
122
|
+
else if (expression[i] === '}') {
|
|
123
|
+
innerDepth--;
|
|
124
|
+
i++;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
i++;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return outerDepth === 0 && innerDepth === 0;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Validate expression syntax (basic checks)
|
|
134
|
+
*
|
|
135
|
+
* Full expression validation would require parsing JavaScript,
|
|
136
|
+
* but we can catch common syntax errors:
|
|
137
|
+
* - Unmatched quotes (accounting for escapes and nesting)
|
|
138
|
+
* - Incomplete ternary operators
|
|
139
|
+
* - Missing closing parentheses (accounting for string contexts)
|
|
140
|
+
*
|
|
141
|
+
* RAG-2.2.108.5: Fixed false positives by properly handling:
|
|
142
|
+
* - Escaped quotes: \' and \"
|
|
143
|
+
* - Quotes inside different quote types: "it's" or 'say "hi"'
|
|
144
|
+
* - Parentheses inside strings: .replaceAll(')', '')
|
|
145
|
+
* - Parentheses inside regex: /(?=\(pattern)/
|
|
146
|
+
*/
|
|
147
|
+
function validateExpressionSyntax(expression) {
|
|
148
|
+
// Remove {{ }} wrapper
|
|
149
|
+
const inner = expression.replace(/^\{\{/, '').replace(/\}\}$/, '').trim();
|
|
150
|
+
// State machine to track string/regex context
|
|
151
|
+
let inSingleQuote = false;
|
|
152
|
+
let inDoubleQuote = false;
|
|
153
|
+
let inBacktick = false;
|
|
154
|
+
let inRegex = false;
|
|
155
|
+
let parenDepth = 0;
|
|
156
|
+
for (let i = 0; i < inner.length; i++) {
|
|
157
|
+
const char = inner[i];
|
|
158
|
+
const prevChar = i > 0 ? inner[i - 1] : '';
|
|
159
|
+
const nextChar = i < inner.length - 1 ? inner[i + 1] : '';
|
|
160
|
+
// Skip escaped characters
|
|
161
|
+
if (prevChar === '\\') {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
// Handle string contexts
|
|
165
|
+
if (char === "'" && !inDoubleQuote && !inBacktick && !inRegex) {
|
|
166
|
+
inSingleQuote = !inSingleQuote;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (char === '"' && !inSingleQuote && !inBacktick && !inRegex) {
|
|
170
|
+
inDoubleQuote = !inDoubleQuote;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (char === '`' && !inSingleQuote && !inDoubleQuote && !inRegex) {
|
|
174
|
+
inBacktick = !inBacktick;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
// Handle regex context (simplified: /.../ not preceded by division context)
|
|
178
|
+
// This is a heuristic - true regex detection requires full parsing
|
|
179
|
+
if (char === '/' && !inSingleQuote && !inDoubleQuote && !inBacktick) {
|
|
180
|
+
// Check if this could be start of regex (not division)
|
|
181
|
+
// Regex typically follows: (, [, {, ,, =, :, ;, !, &, |, ?, or start
|
|
182
|
+
if (!inRegex) {
|
|
183
|
+
const regexPrecursors = /[([\]{},=:;!&|?+\-*\n\r\t ]/;
|
|
184
|
+
if (i === 0 || regexPrecursors.test(prevChar)) {
|
|
185
|
+
inRegex = true;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
// End of regex
|
|
191
|
+
inRegex = false;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Only count parentheses outside of strings and regex
|
|
196
|
+
if (!inSingleQuote && !inDoubleQuote && !inBacktick && !inRegex) {
|
|
197
|
+
if (char === '(')
|
|
198
|
+
parenDepth++;
|
|
199
|
+
if (char === ')')
|
|
200
|
+
parenDepth--;
|
|
201
|
+
if (parenDepth < 0) {
|
|
202
|
+
return { valid: false, reason: 'Unmatched closing parenthesis' };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Check for unclosed strings
|
|
207
|
+
if (inSingleQuote) {
|
|
208
|
+
return { valid: false, reason: 'Unmatched single quote' };
|
|
209
|
+
}
|
|
210
|
+
if (inDoubleQuote) {
|
|
211
|
+
return { valid: false, reason: 'Unmatched double quote' };
|
|
212
|
+
}
|
|
213
|
+
if (inBacktick) {
|
|
214
|
+
return { valid: false, reason: 'Unmatched backtick' };
|
|
215
|
+
}
|
|
216
|
+
// Check for unmatched parentheses
|
|
217
|
+
if (parenDepth !== 0) {
|
|
218
|
+
return { valid: false, reason: 'Unmatched opening parenthesis' };
|
|
219
|
+
}
|
|
220
|
+
return { valid: true };
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Check 1: UNBALANCED_BRACES
|
|
224
|
+
* Detect {{ }} expressions with mismatched braces
|
|
225
|
+
*/
|
|
226
|
+
export function checkUnbalancedBraces(context) {
|
|
227
|
+
const { workflow } = context;
|
|
228
|
+
const errors = [];
|
|
229
|
+
for (const node of workflow.nodes) {
|
|
230
|
+
const expressions = extractExpressions(node.parameters, `nodes.${node.name}.parameters`);
|
|
231
|
+
for (const { expression, path } of expressions) {
|
|
232
|
+
if (!hasBalancedBraces(expression)) {
|
|
233
|
+
const code = 'UNBALANCED_BRACES';
|
|
234
|
+
errors.push({
|
|
235
|
+
code: 'UNBALANCED_BRACES',
|
|
236
|
+
message: `Expression has unbalanced {{ }} braces: "${expression.substring(0, 50)}..."`,
|
|
237
|
+
path,
|
|
238
|
+
node_name: node.name,
|
|
239
|
+
node_type: node.type,
|
|
240
|
+
severity: getL6Severity(code),
|
|
241
|
+
blocks_certification: blocksCertification(code),
|
|
242
|
+
suggested_fix: {
|
|
243
|
+
id: `fix-unbalanced-${node.name}-${path}`,
|
|
244
|
+
fix_type: 'fix_expression',
|
|
245
|
+
confidence: 0.60, // Medium confidence - hard to auto-fix without knowing intent
|
|
246
|
+
auto_applicable: false,
|
|
247
|
+
description: `Fix brace balancing in expression at ${path}`,
|
|
248
|
+
target_node: node.name,
|
|
249
|
+
patch: {
|
|
250
|
+
expression_fix: {
|
|
251
|
+
old_value: expression,
|
|
252
|
+
new_value: expression, // Cannot auto-fix without understanding intent
|
|
253
|
+
field_path: path,
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
context: {
|
|
257
|
+
reason: 'Unbalanced {{ }} braces',
|
|
258
|
+
expression_preview: expression.substring(0, 100),
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return errors;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Check 2: INVALID_EXPRESSION_SYNTAX
|
|
269
|
+
* Detect expressions with basic syntax errors
|
|
270
|
+
*/
|
|
271
|
+
export function checkInvalidExpressionSyntax(context) {
|
|
272
|
+
const { workflow } = context;
|
|
273
|
+
const errors = [];
|
|
274
|
+
for (const node of workflow.nodes) {
|
|
275
|
+
const expressions = extractExpressions(node.parameters, `nodes.${node.name}.parameters`);
|
|
276
|
+
for (const { expression, path } of expressions) {
|
|
277
|
+
const validation = validateExpressionSyntax(expression);
|
|
278
|
+
if (!validation.valid) {
|
|
279
|
+
const code = 'INVALID_EXPRESSION_SYNTAX';
|
|
280
|
+
errors.push({
|
|
281
|
+
code: 'INVALID_EXPRESSION_SYNTAX',
|
|
282
|
+
message: `Expression has syntax error: ${validation.reason}`,
|
|
283
|
+
path,
|
|
284
|
+
node_name: node.name,
|
|
285
|
+
node_type: node.type,
|
|
286
|
+
severity: getL6Severity(code),
|
|
287
|
+
blocks_certification: blocksCertification(code),
|
|
288
|
+
details: {
|
|
289
|
+
expression_preview: expression.substring(0, 100),
|
|
290
|
+
error_reason: validation.reason,
|
|
291
|
+
},
|
|
292
|
+
suggested_fix: {
|
|
293
|
+
id: `fix-syntax-${node.name}-${path}`,
|
|
294
|
+
fix_type: 'fix_expression',
|
|
295
|
+
confidence: 0.95, // High confidence for quote/paren fixes
|
|
296
|
+
auto_applicable: !!(validation.reason?.includes('quote') || validation.reason?.includes('parenthesis')),
|
|
297
|
+
description: `Fix ${validation.reason} in expression`,
|
|
298
|
+
target_node: node.name,
|
|
299
|
+
patch: {
|
|
300
|
+
expression_fix: {
|
|
301
|
+
old_value: expression,
|
|
302
|
+
new_value: expression, // Auto-fix would add missing quote/paren
|
|
303
|
+
field_path: path,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
context: {
|
|
307
|
+
syntax_error: validation.reason,
|
|
308
|
+
expression_preview: expression.substring(0, 100),
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return errors;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Check 3: EMPTY_EXPRESSION
|
|
319
|
+
* Detect expressions that contain only whitespace: {{ }} or {{ }}
|
|
320
|
+
*
|
|
321
|
+
* RAG-2.2.77: New pattern check
|
|
322
|
+
*/
|
|
323
|
+
export function checkEmptyExpressions(context) {
|
|
324
|
+
const { workflow } = context;
|
|
325
|
+
const warnings = [];
|
|
326
|
+
// Guard: Ensure workflow.nodes exists
|
|
327
|
+
if (!workflow.nodes || !Array.isArray(workflow.nodes)) {
|
|
328
|
+
return warnings;
|
|
329
|
+
}
|
|
330
|
+
// Pattern to match empty expressions: {{ }} with any whitespace
|
|
331
|
+
const emptyExprPattern = /\{\{\s*\}\}/g;
|
|
332
|
+
for (const node of workflow.nodes) {
|
|
333
|
+
const params = JSON.stringify(node.parameters || {});
|
|
334
|
+
const matches = params.match(emptyExprPattern);
|
|
335
|
+
if (matches && matches.length > 0) {
|
|
336
|
+
const code = 'EMPTY_EXPRESSION';
|
|
337
|
+
warnings.push({
|
|
338
|
+
code: 'EMPTY_EXPRESSION',
|
|
339
|
+
message: `Node "${node.name}" contains ${matches.length} empty expression(s) "{{ }}" - likely unintentional`,
|
|
340
|
+
node_name: node.name,
|
|
341
|
+
node_type: node.type,
|
|
342
|
+
severity: getL6Severity(code),
|
|
343
|
+
blocks_certification: blocksCertification(code),
|
|
344
|
+
details: {
|
|
345
|
+
empty_count: matches.length,
|
|
346
|
+
},
|
|
347
|
+
suggested_fix: {
|
|
348
|
+
id: `fix-empty-expr-${node.name}-${Date.now()}`,
|
|
349
|
+
fix_type: 'remove_expression',
|
|
350
|
+
confidence: 0.7,
|
|
351
|
+
auto_applicable: false,
|
|
352
|
+
description: 'Remove empty expressions or add meaningful content',
|
|
353
|
+
target_node: node.name,
|
|
354
|
+
patch: {},
|
|
355
|
+
context: {
|
|
356
|
+
empty_expression_count: matches.length,
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return warnings;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Run all expression syntax checks in parallel
|
|
366
|
+
*
|
|
367
|
+
* RAG-2.2.77: Added EMPTY_EXPRESSION check
|
|
368
|
+
*/
|
|
369
|
+
export async function checkExpressionSyntax(context) {
|
|
370
|
+
const startTime = performance.now();
|
|
371
|
+
// Run checks in parallel
|
|
372
|
+
// RAG-2.2.77: Added emptyExpressionWarnings
|
|
373
|
+
const [unbalancedErrors, syntaxErrors, emptyExpressionWarnings,] = await Promise.all([
|
|
374
|
+
Promise.resolve(checkUnbalancedBraces(context)),
|
|
375
|
+
Promise.resolve(checkInvalidExpressionSyntax(context)),
|
|
376
|
+
Promise.resolve(checkEmptyExpressions(context)),
|
|
377
|
+
]);
|
|
378
|
+
const duration = performance.now() - startTime;
|
|
379
|
+
return {
|
|
380
|
+
errors: [
|
|
381
|
+
...unbalancedErrors,
|
|
382
|
+
...syntaxErrors,
|
|
383
|
+
],
|
|
384
|
+
warnings: emptyExpressionWarnings,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=expression-syntax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expression-syntax.js","sourceRoot":"","sources":["../../../src/validation/l6-checks/expression-syntax.ts"],"names":[],"mappings":"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"}
|