n8n-mcp 2.7.7
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/.env.example +79 -0
- package/LICENSE +21 -0
- package/README.md +670 -0
- package/data/nodes.db +0 -0
- package/dist/config/n8n-api.d.ts +9 -0
- package/dist/config/n8n-api.d.ts.map +1 -0
- package/dist/config/n8n-api.js +41 -0
- package/dist/config/n8n-api.js.map +1 -0
- package/dist/database/database-adapter.d.ts +32 -0
- package/dist/database/database-adapter.d.ts.map +1 -0
- package/dist/database/database-adapter.js +328 -0
- package/dist/database/database-adapter.js.map +1 -0
- package/dist/database/node-repository.d.ts +11 -0
- package/dist/database/node-repository.d.ts.map +1 -0
- package/dist/database/node-repository.js +67 -0
- package/dist/database/node-repository.js.map +1 -0
- package/dist/http-server-single-session.d.ts +21 -0
- package/dist/http-server-single-session.d.ts.map +1 -0
- package/dist/http-server-single-session.js +279 -0
- package/dist/http-server-single-session.js.map +1 -0
- package/dist/http-server.d.ts +9 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +342 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/loaders/node-loader.d.ts +11 -0
- package/dist/loaders/node-loader.d.ts.map +1 -0
- package/dist/loaders/node-loader.js +79 -0
- package/dist/loaders/node-loader.js.map +1 -0
- package/dist/mappers/docs-mapper.d.ts +6 -0
- package/dist/mappers/docs-mapper.d.ts.map +1 -0
- package/dist/mappers/docs-mapper.js +59 -0
- package/dist/mappers/docs-mapper.js.map +1 -0
- package/dist/mcp/absolute-minimal.d.ts +4 -0
- package/dist/mcp/absolute-minimal.d.ts.map +1 -0
- package/dist/mcp/absolute-minimal.js +34 -0
- package/dist/mcp/absolute-minimal.js.map +1 -0
- package/dist/mcp/fixed-protocol.d.ts +17 -0
- package/dist/mcp/fixed-protocol.d.ts.map +1 -0
- package/dist/mcp/fixed-protocol.js +162 -0
- package/dist/mcp/fixed-protocol.js.map +1 -0
- package/dist/mcp/handlers-documentation.d.ts +18 -0
- package/dist/mcp/handlers-documentation.d.ts.map +1 -0
- package/dist/mcp/handlers-documentation.js +113 -0
- package/dist/mcp/handlers-documentation.js.map +1 -0
- package/dist/mcp/handlers-n8n-manager.d.ts +21 -0
- package/dist/mcp/handlers-n8n-manager.d.ts.map +1 -0
- package/dist/mcp/handlers-n8n-manager.js +827 -0
- package/dist/mcp/handlers-n8n-manager.js.map +1 -0
- package/dist/mcp/handlers-workflow-diff.d.ts +3 -0
- package/dist/mcp/handlers-workflow-diff.d.ts.map +1 -0
- package/dist/mcp/handlers-workflow-diff.js +125 -0
- package/dist/mcp/handlers-workflow-diff.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +106 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/minimal-test.d.ts +3 -0
- package/dist/mcp/minimal-test.d.ts.map +1 -0
- package/dist/mcp/minimal-test.js +83 -0
- package/dist/mcp/minimal-test.js.map +1 -0
- package/dist/mcp/server.d.ts +42 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +1258 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stderr-test.d.ts +2 -0
- package/dist/mcp/stderr-test.d.ts.map +1 -0
- package/dist/mcp/stderr-test.js +32 -0
- package/dist/mcp/stderr-test.js.map +1 -0
- package/dist/mcp/stdio-wrapper.d.ts +3 -0
- package/dist/mcp/stdio-wrapper.d.ts.map +1 -0
- package/dist/mcp/stdio-wrapper.js +52 -0
- package/dist/mcp/stdio-wrapper.js.map +1 -0
- package/dist/mcp/tools-documentation.d.ts +34 -0
- package/dist/mcp/tools-documentation.d.ts.map +1 -0
- package/dist/mcp/tools-documentation.js +609 -0
- package/dist/mcp/tools-documentation.js.map +1 -0
- package/dist/mcp/tools-n8n-manager.d.ts +3 -0
- package/dist/mcp/tools-n8n-manager.d.ts.map +1 -0
- package/dist/mcp/tools-n8n-manager.js +496 -0
- package/dist/mcp/tools-n8n-manager.js.map +1 -0
- package/dist/mcp/tools.d.ts +3 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +405 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/ultra-minimal.d.ts +8 -0
- package/dist/mcp/ultra-minimal.d.ts.map +1 -0
- package/dist/mcp/ultra-minimal.js +93 -0
- package/dist/mcp/ultra-minimal.js.map +1 -0
- package/dist/mcp/working-test.d.ts +3 -0
- package/dist/mcp/working-test.d.ts.map +1 -0
- package/dist/mcp/working-test.js +48 -0
- package/dist/mcp/working-test.js.map +1 -0
- package/dist/mcp/wrapper.sh +28 -0
- package/dist/mcp-engine.d.ts +32 -0
- package/dist/mcp-engine.d.ts.map +1 -0
- package/dist/mcp-engine.js +63 -0
- package/dist/mcp-engine.js.map +1 -0
- package/dist/n8n/MCPApi.credentials.d.ts +8 -0
- package/dist/n8n/MCPApi.credentials.d.ts.map +1 -0
- package/dist/n8n/MCPApi.credentials.js +53 -0
- package/dist/n8n/MCPApi.credentials.js.map +1 -0
- package/dist/n8n/MCPNode.node.d.ts +13 -0
- package/dist/n8n/MCPNode.node.d.ts.map +1 -0
- package/dist/n8n/MCPNode.node.js +260 -0
- package/dist/n8n/MCPNode.node.js.map +1 -0
- package/dist/parsers/node-parser.d.ts +30 -0
- package/dist/parsers/node-parser.d.ts.map +1 -0
- package/dist/parsers/node-parser.js +152 -0
- package/dist/parsers/node-parser.js.map +1 -0
- package/dist/parsers/property-extractor.d.ts +10 -0
- package/dist/parsers/property-extractor.d.ts.map +1 -0
- package/dist/parsers/property-extractor.js +155 -0
- package/dist/parsers/property-extractor.js.map +1 -0
- package/dist/parsers/simple-parser.d.ts +24 -0
- package/dist/parsers/simple-parser.d.ts.map +1 -0
- package/dist/parsers/simple-parser.js +160 -0
- package/dist/parsers/simple-parser.js.map +1 -0
- package/dist/scripts/debug-n8n-auth.d.ts +3 -0
- package/dist/scripts/debug-n8n-auth.d.ts.map +1 -0
- package/dist/scripts/debug-n8n-auth.js +97 -0
- package/dist/scripts/debug-n8n-auth.js.map +1 -0
- package/dist/scripts/debug-node.d.ts +3 -0
- package/dist/scripts/debug-node.d.ts.map +1 -0
- package/dist/scripts/debug-node.js +59 -0
- package/dist/scripts/debug-node.js.map +1 -0
- package/dist/scripts/extract-from-docker.d.ts +3 -0
- package/dist/scripts/extract-from-docker.d.ts.map +1 -0
- package/dist/scripts/extract-from-docker.js +210 -0
- package/dist/scripts/extract-from-docker.js.map +1 -0
- package/dist/scripts/fetch-templates-robust.d.ts +4 -0
- package/dist/scripts/fetch-templates-robust.d.ts.map +1 -0
- package/dist/scripts/fetch-templates-robust.js +126 -0
- package/dist/scripts/fetch-templates-robust.js.map +1 -0
- package/dist/scripts/fetch-templates.d.ts +4 -0
- package/dist/scripts/fetch-templates.d.ts.map +1 -0
- package/dist/scripts/fetch-templates.js +94 -0
- package/dist/scripts/fetch-templates.js.map +1 -0
- package/dist/scripts/rebuild-database.d.ts +4 -0
- package/dist/scripts/rebuild-database.d.ts.map +1 -0
- package/dist/scripts/rebuild-database.js +95 -0
- package/dist/scripts/rebuild-database.js.map +1 -0
- package/dist/scripts/rebuild-optimized.d.ts +3 -0
- package/dist/scripts/rebuild-optimized.d.ts.map +1 -0
- package/dist/scripts/rebuild-optimized.js +198 -0
- package/dist/scripts/rebuild-optimized.js.map +1 -0
- package/dist/scripts/rebuild.d.ts +3 -0
- package/dist/scripts/rebuild.d.ts.map +1 -0
- package/dist/scripts/rebuild.js +163 -0
- package/dist/scripts/rebuild.js.map +1 -0
- package/dist/scripts/sanitize-templates.d.ts +3 -0
- package/dist/scripts/sanitize-templates.d.ts.map +1 -0
- package/dist/scripts/sanitize-templates.js +56 -0
- package/dist/scripts/sanitize-templates.js.map +1 -0
- package/dist/scripts/test-ai-workflow-validation.d.ts +3 -0
- package/dist/scripts/test-ai-workflow-validation.d.ts.map +1 -0
- package/dist/scripts/test-ai-workflow-validation.js +191 -0
- package/dist/scripts/test-ai-workflow-validation.js.map +1 -0
- package/dist/scripts/test-api-headers.d.ts +3 -0
- package/dist/scripts/test-api-headers.d.ts.map +1 -0
- package/dist/scripts/test-api-headers.js +35 -0
- package/dist/scripts/test-api-headers.js.map +1 -0
- package/dist/scripts/test-docker-config-simulation.d.ts +3 -0
- package/dist/scripts/test-docker-config-simulation.d.ts.map +1 -0
- package/dist/scripts/test-docker-config-simulation.js +74 -0
- package/dist/scripts/test-docker-config-simulation.js.map +1 -0
- package/dist/scripts/test-enhanced-validation.d.ts +3 -0
- package/dist/scripts/test-enhanced-validation.d.ts.map +1 -0
- package/dist/scripts/test-enhanced-validation.js +117 -0
- package/dist/scripts/test-enhanced-validation.js.map +1 -0
- package/dist/scripts/test-lazy-config.d.ts +3 -0
- package/dist/scripts/test-lazy-config.d.ts.map +1 -0
- package/dist/scripts/test-lazy-config.js +60 -0
- package/dist/scripts/test-lazy-config.js.map +1 -0
- package/dist/scripts/test-limited-results.d.ts +3 -0
- package/dist/scripts/test-limited-results.d.ts.map +1 -0
- package/dist/scripts/test-limited-results.js +76 -0
- package/dist/scripts/test-limited-results.js.map +1 -0
- package/dist/scripts/test-mcp-n8n-update-partial.d.ts +3 -0
- package/dist/scripts/test-mcp-n8n-update-partial.d.ts.map +1 -0
- package/dist/scripts/test-mcp-n8n-update-partial.js +138 -0
- package/dist/scripts/test-mcp-n8n-update-partial.js.map +1 -0
- package/dist/scripts/test-mcp-tools.d.ts +3 -0
- package/dist/scripts/test-mcp-tools.d.ts.map +1 -0
- package/dist/scripts/test-mcp-tools.js +36 -0
- package/dist/scripts/test-mcp-tools.js.map +1 -0
- package/dist/scripts/test-n8n-manager-integration.d.ts +3 -0
- package/dist/scripts/test-n8n-manager-integration.d.ts.map +1 -0
- package/dist/scripts/test-n8n-manager-integration.js +122 -0
- package/dist/scripts/test-n8n-manager-integration.js.map +1 -0
- package/dist/scripts/test-n8n-validate-workflow.d.ts +3 -0
- package/dist/scripts/test-n8n-validate-workflow.d.ts.map +1 -0
- package/dist/scripts/test-n8n-validate-workflow.js +125 -0
- package/dist/scripts/test-n8n-validate-workflow.js.map +1 -0
- package/dist/scripts/test-nodes.d.ts +3 -0
- package/dist/scripts/test-nodes.d.ts.map +1 -0
- package/dist/scripts/test-nodes.js +91 -0
- package/dist/scripts/test-nodes.js.map +1 -0
- package/dist/scripts/test-single-workflow.d.ts +3 -0
- package/dist/scripts/test-single-workflow.d.ts.map +1 -0
- package/dist/scripts/test-single-workflow.js +112 -0
- package/dist/scripts/test-single-workflow.js.map +1 -0
- package/dist/scripts/test-template-validation.d.ts +3 -0
- package/dist/scripts/test-template-validation.d.ts.map +1 -0
- package/dist/scripts/test-template-validation.js +142 -0
- package/dist/scripts/test-template-validation.js.map +1 -0
- package/dist/scripts/test-templates.d.ts +4 -0
- package/dist/scripts/test-templates.d.ts.map +1 -0
- package/dist/scripts/test-templates.js +99 -0
- package/dist/scripts/test-templates.js.map +1 -0
- package/dist/scripts/test-transactional-diff.d.ts +2 -0
- package/dist/scripts/test-transactional-diff.d.ts.map +1 -0
- package/dist/scripts/test-transactional-diff.js +240 -0
- package/dist/scripts/test-transactional-diff.js.map +1 -0
- package/dist/scripts/test-update-partial-debug.d.ts +3 -0
- package/dist/scripts/test-update-partial-debug.d.ts.map +1 -0
- package/dist/scripts/test-update-partial-debug.js +92 -0
- package/dist/scripts/test-update-partial-debug.js.map +1 -0
- package/dist/scripts/test-version-extraction.d.ts +2 -0
- package/dist/scripts/test-version-extraction.d.ts.map +1 -0
- package/dist/scripts/test-version-extraction.js +74 -0
- package/dist/scripts/test-version-extraction.js.map +1 -0
- package/dist/scripts/test-workflow-diff.d.ts +3 -0
- package/dist/scripts/test-workflow-diff.d.ts.map +1 -0
- package/dist/scripts/test-workflow-diff.js +328 -0
- package/dist/scripts/test-workflow-diff.js.map +1 -0
- package/dist/scripts/test-workflow-validation.d.ts +3 -0
- package/dist/scripts/test-workflow-validation.d.ts.map +1 -0
- package/dist/scripts/test-workflow-validation.js +238 -0
- package/dist/scripts/test-workflow-validation.js.map +1 -0
- package/dist/scripts/validate.d.ts +3 -0
- package/dist/scripts/validate.d.ts.map +1 -0
- package/dist/scripts/validate.js +121 -0
- package/dist/scripts/validate.js.map +1 -0
- package/dist/scripts/validation-summary.d.ts +3 -0
- package/dist/scripts/validation-summary.d.ts.map +1 -0
- package/dist/scripts/validation-summary.js +135 -0
- package/dist/scripts/validation-summary.js.map +1 -0
- package/dist/services/config-validator.d.ts +39 -0
- package/dist/services/config-validator.d.ts.map +1 -0
- package/dist/services/config-validator.js +376 -0
- package/dist/services/config-validator.js.map +1 -0
- package/dist/services/enhanced-config-validator.d.ts +38 -0
- package/dist/services/enhanced-config-validator.d.ts.map +1 -0
- package/dist/services/enhanced-config-validator.js +300 -0
- package/dist/services/enhanced-config-validator.js.map +1 -0
- package/dist/services/example-generator.d.ts +14 -0
- package/dist/services/example-generator.d.ts.map +1 -0
- package/dist/services/example-generator.js +556 -0
- package/dist/services/example-generator.js.map +1 -0
- package/dist/services/expression-validator.d.ts +27 -0
- package/dist/services/expression-validator.d.ts.map +1 -0
- package/dist/services/expression-validator.js +163 -0
- package/dist/services/expression-validator.js.map +1 -0
- package/dist/services/n8n-api-client.d.ts +39 -0
- package/dist/services/n8n-api-client.d.ts.map +1 -0
- package/dist/services/n8n-api-client.js +326 -0
- package/dist/services/n8n-api-client.js.map +1 -0
- package/dist/services/n8n-validation.d.ts +127 -0
- package/dist/services/n8n-validation.d.ts.map +1 -0
- package/dist/services/n8n-validation.js +238 -0
- package/dist/services/n8n-validation.js.map +1 -0
- package/dist/services/node-documentation-service.d.ts +70 -0
- package/dist/services/node-documentation-service.d.ts.map +1 -0
- package/dist/services/node-documentation-service.js +518 -0
- package/dist/services/node-documentation-service.js.map +1 -0
- package/dist/services/node-specific-validators.d.ts +28 -0
- package/dist/services/node-specific-validators.d.ts.map +1 -0
- package/dist/services/node-specific-validators.js +666 -0
- package/dist/services/node-specific-validators.js.map +1 -0
- package/dist/services/property-dependencies.d.ts +36 -0
- package/dist/services/property-dependencies.d.ts.map +1 -0
- package/dist/services/property-dependencies.js +168 -0
- package/dist/services/property-dependencies.js.map +1 -0
- package/dist/services/property-filter.d.ts +39 -0
- package/dist/services/property-filter.d.ts.map +1 -0
- package/dist/services/property-filter.js +362 -0
- package/dist/services/property-filter.js.map +1 -0
- package/dist/services/task-templates.d.ts +26 -0
- package/dist/services/task-templates.d.ts.map +1 -0
- package/dist/services/task-templates.js +555 -0
- package/dist/services/task-templates.js.map +1 -0
- package/dist/services/workflow-diff-engine.d.ts +31 -0
- package/dist/services/workflow-diff-engine.d.ts.map +1 -0
- package/dist/services/workflow-diff-engine.js +478 -0
- package/dist/services/workflow-diff-engine.js.map +1 -0
- package/dist/services/workflow-validator.d.ts +87 -0
- package/dist/services/workflow-validator.d.ts.map +1 -0
- package/dist/services/workflow-validator.js +656 -0
- package/dist/services/workflow-validator.js.map +1 -0
- package/dist/templates/template-fetcher.d.ts +41 -0
- package/dist/templates/template-fetcher.d.ts.map +1 -0
- package/dist/templates/template-fetcher.js +94 -0
- package/dist/templates/template-fetcher.js.map +1 -0
- package/dist/templates/template-repository.d.ts +34 -0
- package/dist/templates/template-repository.d.ts.map +1 -0
- package/dist/templates/template-repository.js +121 -0
- package/dist/templates/template-repository.js.map +1 -0
- package/dist/templates/template-service.d.ts +31 -0
- package/dist/templates/template-service.d.ts.map +1 -0
- package/dist/templates/template-service.js +131 -0
- package/dist/templates/template-service.js.map +1 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/n8n-api.d.ts +241 -0
- package/dist/types/n8n-api.d.ts.map +1 -0
- package/dist/types/n8n-api.js +10 -0
- package/dist/types/n8n-api.js.map +1 -0
- package/dist/types/workflow-diff.d.ts +113 -0
- package/dist/types/workflow-diff.d.ts.map +1 -0
- package/dist/types/workflow-diff.js +15 -0
- package/dist/types/workflow-diff.js.map +1 -0
- package/dist/utils/auth.d.ts +12 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +66 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/bridge.d.ts +12 -0
- package/dist/utils/bridge.d.ts.map +1 -0
- package/dist/utils/bridge.js +127 -0
- package/dist/utils/bridge.js.map +1 -0
- package/dist/utils/console-manager.d.ts +10 -0
- package/dist/utils/console-manager.d.ts.map +1 -0
- package/dist/utils/console-manager.js +63 -0
- package/dist/utils/console-manager.js.map +1 -0
- package/dist/utils/documentation-fetcher.d.ts +2 -0
- package/dist/utils/documentation-fetcher.d.ts.map +1 -0
- package/dist/utils/documentation-fetcher.js +18 -0
- package/dist/utils/documentation-fetcher.js.map +1 -0
- package/dist/utils/enhanced-documentation-fetcher.d.ts +73 -0
- package/dist/utils/enhanced-documentation-fetcher.d.ts.map +1 -0
- package/dist/utils/enhanced-documentation-fetcher.js +397 -0
- package/dist/utils/enhanced-documentation-fetcher.js.map +1 -0
- package/dist/utils/error-handler.d.ts +24 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +84 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/example-generator.d.ts +8 -0
- package/dist/utils/example-generator.d.ts.map +1 -0
- package/dist/utils/example-generator.js +106 -0
- package/dist/utils/example-generator.js.map +1 -0
- package/dist/utils/logger.d.ts +32 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +97 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-client.d.ts +21 -0
- package/dist/utils/mcp-client.d.ts.map +1 -0
- package/dist/utils/mcp-client.js +96 -0
- package/dist/utils/mcp-client.js.map +1 -0
- package/dist/utils/n8n-errors.d.ts +25 -0
- package/dist/utils/n8n-errors.d.ts.map +1 -0
- package/dist/utils/n8n-errors.js +129 -0
- package/dist/utils/n8n-errors.js.map +1 -0
- package/dist/utils/node-source-extractor.d.ts +21 -0
- package/dist/utils/node-source-extractor.d.ts.map +1 -0
- package/dist/utils/node-source-extractor.js +377 -0
- package/dist/utils/node-source-extractor.js.map +1 -0
- package/dist/utils/simple-cache.d.ts +8 -0
- package/dist/utils/simple-cache.d.ts.map +1 -0
- package/dist/utils/simple-cache.js +34 -0
- package/dist/utils/simple-cache.js.map +1 -0
- package/dist/utils/template-sanitizer.d.ts +21 -0
- package/dist/utils/template-sanitizer.d.ts.map +1 -0
- package/dist/utils/template-sanitizer.js +108 -0
- package/dist/utils/template-sanitizer.js.map +1 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +18 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +100 -0
- package/package.runtime.json +19 -0
|
@@ -0,0 +1,666 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NodeSpecificValidators = void 0;
|
|
4
|
+
class NodeSpecificValidators {
|
|
5
|
+
static validateSlack(context) {
|
|
6
|
+
const { config, errors, warnings, suggestions } = context;
|
|
7
|
+
const { resource, operation } = config;
|
|
8
|
+
if (resource === 'message') {
|
|
9
|
+
switch (operation) {
|
|
10
|
+
case 'send':
|
|
11
|
+
this.validateSlackSendMessage(context);
|
|
12
|
+
break;
|
|
13
|
+
case 'update':
|
|
14
|
+
this.validateSlackUpdateMessage(context);
|
|
15
|
+
break;
|
|
16
|
+
case 'delete':
|
|
17
|
+
this.validateSlackDeleteMessage(context);
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else if (resource === 'channel') {
|
|
22
|
+
switch (operation) {
|
|
23
|
+
case 'create':
|
|
24
|
+
this.validateSlackCreateChannel(context);
|
|
25
|
+
break;
|
|
26
|
+
case 'get':
|
|
27
|
+
case 'getAll':
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (resource === 'user') {
|
|
32
|
+
if (operation === 'get' && !config.user) {
|
|
33
|
+
errors.push({
|
|
34
|
+
type: 'missing_required',
|
|
35
|
+
property: 'user',
|
|
36
|
+
message: 'User identifier required - use email, user ID, or username',
|
|
37
|
+
fix: 'Set user to an email like "john@example.com" or user ID like "U1234567890"'
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
static validateSlackSendMessage(context) {
|
|
43
|
+
const { config, errors, warnings, suggestions, autofix } = context;
|
|
44
|
+
if (!config.channel && !config.channelId) {
|
|
45
|
+
errors.push({
|
|
46
|
+
type: 'missing_required',
|
|
47
|
+
property: 'channel',
|
|
48
|
+
message: 'Channel is required to send a message',
|
|
49
|
+
fix: 'Set channel to a channel name (e.g., "#general") or ID (e.g., "C1234567890")'
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (!config.text && !config.blocks && !config.attachments) {
|
|
53
|
+
errors.push({
|
|
54
|
+
type: 'missing_required',
|
|
55
|
+
property: 'text',
|
|
56
|
+
message: 'Message content is required - provide text, blocks, or attachments',
|
|
57
|
+
fix: 'Add text field with your message content'
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (config.text && config.text.length > 40000) {
|
|
61
|
+
warnings.push({
|
|
62
|
+
type: 'inefficient',
|
|
63
|
+
property: 'text',
|
|
64
|
+
message: 'Message text exceeds Slack\'s 40,000 character limit',
|
|
65
|
+
suggestion: 'Split into multiple messages or use a file upload'
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (config.replyToThread && !config.threadTs) {
|
|
69
|
+
warnings.push({
|
|
70
|
+
type: 'missing_common',
|
|
71
|
+
property: 'threadTs',
|
|
72
|
+
message: 'Thread timestamp required when replying to thread',
|
|
73
|
+
suggestion: 'Set threadTs to the timestamp of the thread parent message'
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (config.text?.includes('@') && !config.linkNames) {
|
|
77
|
+
suggestions.push('Set linkNames=true to convert @mentions to user links');
|
|
78
|
+
autofix.linkNames = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
static validateSlackUpdateMessage(context) {
|
|
82
|
+
const { config, errors } = context;
|
|
83
|
+
if (!config.ts) {
|
|
84
|
+
errors.push({
|
|
85
|
+
type: 'missing_required',
|
|
86
|
+
property: 'ts',
|
|
87
|
+
message: 'Message timestamp (ts) is required to update a message',
|
|
88
|
+
fix: 'Provide the timestamp of the message to update'
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (!config.channel && !config.channelId) {
|
|
92
|
+
errors.push({
|
|
93
|
+
type: 'missing_required',
|
|
94
|
+
property: 'channel',
|
|
95
|
+
message: 'Channel is required to update a message',
|
|
96
|
+
fix: 'Provide the channel where the message exists'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
static validateSlackDeleteMessage(context) {
|
|
101
|
+
const { config, errors, warnings } = context;
|
|
102
|
+
if (!config.ts) {
|
|
103
|
+
errors.push({
|
|
104
|
+
type: 'missing_required',
|
|
105
|
+
property: 'ts',
|
|
106
|
+
message: 'Message timestamp (ts) is required to delete a message',
|
|
107
|
+
fix: 'Provide the timestamp of the message to delete'
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (!config.channel && !config.channelId) {
|
|
111
|
+
errors.push({
|
|
112
|
+
type: 'missing_required',
|
|
113
|
+
property: 'channel',
|
|
114
|
+
message: 'Channel is required to delete a message',
|
|
115
|
+
fix: 'Provide the channel where the message exists'
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
warnings.push({
|
|
119
|
+
type: 'security',
|
|
120
|
+
message: 'Message deletion is permanent and cannot be undone',
|
|
121
|
+
suggestion: 'Consider archiving or updating the message instead if you need to preserve history'
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
static validateSlackCreateChannel(context) {
|
|
125
|
+
const { config, errors, warnings } = context;
|
|
126
|
+
if (!config.name) {
|
|
127
|
+
errors.push({
|
|
128
|
+
type: 'missing_required',
|
|
129
|
+
property: 'name',
|
|
130
|
+
message: 'Channel name is required',
|
|
131
|
+
fix: 'Provide a channel name (lowercase, no spaces, 1-80 characters)'
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const name = config.name;
|
|
136
|
+
if (name.includes(' ')) {
|
|
137
|
+
errors.push({
|
|
138
|
+
type: 'invalid_value',
|
|
139
|
+
property: 'name',
|
|
140
|
+
message: 'Channel names cannot contain spaces',
|
|
141
|
+
fix: 'Use hyphens or underscores instead of spaces'
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (name !== name.toLowerCase()) {
|
|
145
|
+
errors.push({
|
|
146
|
+
type: 'invalid_value',
|
|
147
|
+
property: 'name',
|
|
148
|
+
message: 'Channel names must be lowercase',
|
|
149
|
+
fix: 'Convert the channel name to lowercase'
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (name.length > 80) {
|
|
153
|
+
errors.push({
|
|
154
|
+
type: 'invalid_value',
|
|
155
|
+
property: 'name',
|
|
156
|
+
message: 'Channel name exceeds 80 character limit',
|
|
157
|
+
fix: 'Shorten the channel name'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
static validateGoogleSheets(context) {
|
|
163
|
+
const { config, errors, warnings, suggestions } = context;
|
|
164
|
+
const { operation } = config;
|
|
165
|
+
if (!config.sheetId && !config.documentId) {
|
|
166
|
+
errors.push({
|
|
167
|
+
type: 'missing_required',
|
|
168
|
+
property: 'sheetId',
|
|
169
|
+
message: 'Spreadsheet ID is required',
|
|
170
|
+
fix: 'Provide the Google Sheets document ID from the URL'
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
switch (operation) {
|
|
174
|
+
case 'append':
|
|
175
|
+
this.validateGoogleSheetsAppend(context);
|
|
176
|
+
break;
|
|
177
|
+
case 'read':
|
|
178
|
+
this.validateGoogleSheetsRead(context);
|
|
179
|
+
break;
|
|
180
|
+
case 'update':
|
|
181
|
+
this.validateGoogleSheetsUpdate(context);
|
|
182
|
+
break;
|
|
183
|
+
case 'delete':
|
|
184
|
+
this.validateGoogleSheetsDelete(context);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
if (config.range) {
|
|
188
|
+
this.validateGoogleSheetsRange(config.range, errors, warnings);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
static validateGoogleSheetsAppend(context) {
|
|
192
|
+
const { config, errors, warnings, autofix } = context;
|
|
193
|
+
if (!config.range) {
|
|
194
|
+
errors.push({
|
|
195
|
+
type: 'missing_required',
|
|
196
|
+
property: 'range',
|
|
197
|
+
message: 'Range is required for append operation',
|
|
198
|
+
fix: 'Specify range like "Sheet1!A:B" or "Sheet1!A1:B10"'
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
if (!config.options?.valueInputMode) {
|
|
202
|
+
warnings.push({
|
|
203
|
+
type: 'missing_common',
|
|
204
|
+
property: 'options.valueInputMode',
|
|
205
|
+
message: 'Consider setting valueInputMode for proper data formatting',
|
|
206
|
+
suggestion: 'Use "USER_ENTERED" to parse formulas and dates, or "RAW" for literal values'
|
|
207
|
+
});
|
|
208
|
+
autofix.options = { ...config.options, valueInputMode: 'USER_ENTERED' };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
static validateGoogleSheetsRead(context) {
|
|
212
|
+
const { config, errors, suggestions } = context;
|
|
213
|
+
if (!config.range) {
|
|
214
|
+
errors.push({
|
|
215
|
+
type: 'missing_required',
|
|
216
|
+
property: 'range',
|
|
217
|
+
message: 'Range is required for read operation',
|
|
218
|
+
fix: 'Specify range like "Sheet1!A:B" or "Sheet1!A1:B10"'
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
if (!config.options?.dataStructure) {
|
|
222
|
+
suggestions.push('Consider setting options.dataStructure to "object" for easier data manipulation');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
static validateGoogleSheetsUpdate(context) {
|
|
226
|
+
const { config, errors } = context;
|
|
227
|
+
if (!config.range) {
|
|
228
|
+
errors.push({
|
|
229
|
+
type: 'missing_required',
|
|
230
|
+
property: 'range',
|
|
231
|
+
message: 'Range is required for update operation',
|
|
232
|
+
fix: 'Specify the exact range to update like "Sheet1!A1:B10"'
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
if (!config.values && !config.rawData) {
|
|
236
|
+
errors.push({
|
|
237
|
+
type: 'missing_required',
|
|
238
|
+
property: 'values',
|
|
239
|
+
message: 'Values are required for update operation',
|
|
240
|
+
fix: 'Provide the data to write to the spreadsheet'
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
static validateGoogleSheetsDelete(context) {
|
|
245
|
+
const { config, errors, warnings } = context;
|
|
246
|
+
if (!config.toDelete) {
|
|
247
|
+
errors.push({
|
|
248
|
+
type: 'missing_required',
|
|
249
|
+
property: 'toDelete',
|
|
250
|
+
message: 'Specify what to delete (rows or columns)',
|
|
251
|
+
fix: 'Set toDelete to "rows" or "columns"'
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (config.toDelete === 'rows' && !config.startIndex && config.startIndex !== 0) {
|
|
255
|
+
errors.push({
|
|
256
|
+
type: 'missing_required',
|
|
257
|
+
property: 'startIndex',
|
|
258
|
+
message: 'Start index is required when deleting rows',
|
|
259
|
+
fix: 'Specify the starting row index (0-based)'
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
warnings.push({
|
|
263
|
+
type: 'security',
|
|
264
|
+
message: 'Deletion is permanent. Consider backing up data first',
|
|
265
|
+
suggestion: 'Read the data before deletion to create a backup'
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
static validateGoogleSheetsRange(range, errors, warnings) {
|
|
269
|
+
if (!range.includes('!')) {
|
|
270
|
+
warnings.push({
|
|
271
|
+
type: 'inefficient',
|
|
272
|
+
property: 'range',
|
|
273
|
+
message: 'Range should include sheet name for clarity',
|
|
274
|
+
suggestion: 'Format: "SheetName!A1:B10" or "SheetName!A:B"'
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (range.includes(' ') && !range.match(/^'[^']+'/)) {
|
|
278
|
+
errors.push({
|
|
279
|
+
type: 'invalid_value',
|
|
280
|
+
property: 'range',
|
|
281
|
+
message: 'Sheet names with spaces must be quoted',
|
|
282
|
+
fix: 'Use single quotes around sheet name: \'Sheet Name\'!A1:B10'
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
const a1Pattern = /^('[^']+'|[^!]+)!([A-Z]+\d*:?[A-Z]*\d*|[A-Z]+:[A-Z]+|\d+:\d+)$/i;
|
|
286
|
+
if (!a1Pattern.test(range)) {
|
|
287
|
+
warnings.push({
|
|
288
|
+
type: 'inefficient',
|
|
289
|
+
property: 'range',
|
|
290
|
+
message: 'Range may not be in valid A1 notation',
|
|
291
|
+
suggestion: 'Examples: "Sheet1!A1:B10", "Sheet1!A:B", "Sheet1!1:10"'
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
static validateOpenAI(context) {
|
|
296
|
+
const { config, errors, warnings, suggestions } = context;
|
|
297
|
+
const { resource, operation } = config;
|
|
298
|
+
if (resource === 'chat' && operation === 'create') {
|
|
299
|
+
if (!config.model) {
|
|
300
|
+
errors.push({
|
|
301
|
+
type: 'missing_required',
|
|
302
|
+
property: 'model',
|
|
303
|
+
message: 'Model selection is required',
|
|
304
|
+
fix: 'Choose a model like "gpt-4", "gpt-3.5-turbo", etc.'
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
const deprecatedModels = ['text-davinci-003', 'text-davinci-002'];
|
|
309
|
+
if (deprecatedModels.includes(config.model)) {
|
|
310
|
+
warnings.push({
|
|
311
|
+
type: 'deprecated',
|
|
312
|
+
property: 'model',
|
|
313
|
+
message: `Model ${config.model} is deprecated`,
|
|
314
|
+
suggestion: 'Use "gpt-3.5-turbo" or "gpt-4" instead'
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (!config.messages && !config.prompt) {
|
|
319
|
+
errors.push({
|
|
320
|
+
type: 'missing_required',
|
|
321
|
+
property: 'messages',
|
|
322
|
+
message: 'Messages or prompt required for chat completion',
|
|
323
|
+
fix: 'Add messages array or use the prompt field'
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
if (config.maxTokens && config.maxTokens > 4000) {
|
|
327
|
+
warnings.push({
|
|
328
|
+
type: 'inefficient',
|
|
329
|
+
property: 'maxTokens',
|
|
330
|
+
message: 'High token limit may increase costs significantly',
|
|
331
|
+
suggestion: 'Consider if you really need more than 4000 tokens'
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
if (config.temperature !== undefined) {
|
|
335
|
+
if (config.temperature < 0 || config.temperature > 2) {
|
|
336
|
+
errors.push({
|
|
337
|
+
type: 'invalid_value',
|
|
338
|
+
property: 'temperature',
|
|
339
|
+
message: 'Temperature must be between 0 and 2',
|
|
340
|
+
fix: 'Set temperature between 0 (deterministic) and 2 (creative)'
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
static validateMongoDB(context) {
|
|
347
|
+
const { config, errors, warnings } = context;
|
|
348
|
+
const { operation } = config;
|
|
349
|
+
if (!config.collection) {
|
|
350
|
+
errors.push({
|
|
351
|
+
type: 'missing_required',
|
|
352
|
+
property: 'collection',
|
|
353
|
+
message: 'Collection name is required',
|
|
354
|
+
fix: 'Specify the MongoDB collection to work with'
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
switch (operation) {
|
|
358
|
+
case 'find':
|
|
359
|
+
if (config.query) {
|
|
360
|
+
try {
|
|
361
|
+
JSON.parse(config.query);
|
|
362
|
+
}
|
|
363
|
+
catch (e) {
|
|
364
|
+
errors.push({
|
|
365
|
+
type: 'invalid_value',
|
|
366
|
+
property: 'query',
|
|
367
|
+
message: 'Query must be valid JSON',
|
|
368
|
+
fix: 'Ensure query is valid JSON like: {"name": "John"}'
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
break;
|
|
373
|
+
case 'insert':
|
|
374
|
+
if (!config.fields && !config.documents) {
|
|
375
|
+
errors.push({
|
|
376
|
+
type: 'missing_required',
|
|
377
|
+
property: 'fields',
|
|
378
|
+
message: 'Document data is required for insert',
|
|
379
|
+
fix: 'Provide the data to insert'
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
383
|
+
case 'update':
|
|
384
|
+
if (!config.query) {
|
|
385
|
+
warnings.push({
|
|
386
|
+
type: 'security',
|
|
387
|
+
message: 'Update without query will affect all documents',
|
|
388
|
+
suggestion: 'Add a query to target specific documents'
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
break;
|
|
392
|
+
case 'delete':
|
|
393
|
+
if (!config.query || config.query === '{}') {
|
|
394
|
+
errors.push({
|
|
395
|
+
type: 'invalid_value',
|
|
396
|
+
property: 'query',
|
|
397
|
+
message: 'Delete without query would remove all documents - this is a critical security issue',
|
|
398
|
+
fix: 'Add a query to specify which documents to delete'
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
static validateWebhook(context) {
|
|
405
|
+
const { config, errors, warnings, suggestions } = context;
|
|
406
|
+
if (!config.path) {
|
|
407
|
+
errors.push({
|
|
408
|
+
type: 'missing_required',
|
|
409
|
+
property: 'path',
|
|
410
|
+
message: 'Webhook path is required',
|
|
411
|
+
fix: 'Set a unique path like "my-webhook" (no leading slash)'
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
const path = config.path;
|
|
416
|
+
if (path.startsWith('/')) {
|
|
417
|
+
warnings.push({
|
|
418
|
+
type: 'inefficient',
|
|
419
|
+
property: 'path',
|
|
420
|
+
message: 'Webhook path should not start with /',
|
|
421
|
+
suggestion: 'Remove the leading slash: use "my-webhook" instead of "/my-webhook"'
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
if (path.includes(' ')) {
|
|
425
|
+
errors.push({
|
|
426
|
+
type: 'invalid_value',
|
|
427
|
+
property: 'path',
|
|
428
|
+
message: 'Webhook path cannot contain spaces',
|
|
429
|
+
fix: 'Replace spaces with hyphens or underscores'
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
if (!/^[a-zA-Z0-9\-_\/]+$/.test(path.replace(/^\//, ''))) {
|
|
433
|
+
warnings.push({
|
|
434
|
+
type: 'inefficient',
|
|
435
|
+
property: 'path',
|
|
436
|
+
message: 'Webhook path contains special characters',
|
|
437
|
+
suggestion: 'Use only letters, numbers, hyphens, and underscores'
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (config.responseMode === 'responseNode') {
|
|
442
|
+
suggestions.push('Add a "Respond to Webhook" node to send custom responses');
|
|
443
|
+
if (!config.responseData) {
|
|
444
|
+
warnings.push({
|
|
445
|
+
type: 'missing_common',
|
|
446
|
+
property: 'responseData',
|
|
447
|
+
message: 'Response data not configured for responseNode mode',
|
|
448
|
+
suggestion: 'Add a "Respond to Webhook" node or change responseMode'
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (config.httpMethod && Array.isArray(config.httpMethod)) {
|
|
453
|
+
if (config.httpMethod.length === 0) {
|
|
454
|
+
errors.push({
|
|
455
|
+
type: 'invalid_value',
|
|
456
|
+
property: 'httpMethod',
|
|
457
|
+
message: 'At least one HTTP method must be selected',
|
|
458
|
+
fix: 'Select GET, POST, or other methods your webhook should accept'
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (!config.authentication || config.authentication === 'none') {
|
|
463
|
+
warnings.push({
|
|
464
|
+
type: 'security',
|
|
465
|
+
message: 'Webhook has no authentication',
|
|
466
|
+
suggestion: 'Consider adding authentication to prevent unauthorized access'
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
static validatePostgres(context) {
|
|
471
|
+
const { config, errors, warnings, suggestions, autofix } = context;
|
|
472
|
+
const { operation } = config;
|
|
473
|
+
if (['execute', 'select', 'insert', 'update', 'delete'].includes(operation)) {
|
|
474
|
+
this.validateSQLQuery(context, 'postgres');
|
|
475
|
+
}
|
|
476
|
+
switch (operation) {
|
|
477
|
+
case 'insert':
|
|
478
|
+
if (!config.table) {
|
|
479
|
+
errors.push({
|
|
480
|
+
type: 'missing_required',
|
|
481
|
+
property: 'table',
|
|
482
|
+
message: 'Table name is required for insert operation',
|
|
483
|
+
fix: 'Specify the table to insert data into'
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
if (!config.columns && !config.dataMode) {
|
|
487
|
+
warnings.push({
|
|
488
|
+
type: 'missing_common',
|
|
489
|
+
property: 'columns',
|
|
490
|
+
message: 'No columns specified for insert',
|
|
491
|
+
suggestion: 'Define which columns to insert data into'
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
break;
|
|
495
|
+
case 'update':
|
|
496
|
+
if (!config.table) {
|
|
497
|
+
errors.push({
|
|
498
|
+
type: 'missing_required',
|
|
499
|
+
property: 'table',
|
|
500
|
+
message: 'Table name is required for update operation',
|
|
501
|
+
fix: 'Specify the table to update'
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
if (!config.updateKey) {
|
|
505
|
+
warnings.push({
|
|
506
|
+
type: 'missing_common',
|
|
507
|
+
property: 'updateKey',
|
|
508
|
+
message: 'No update key specified',
|
|
509
|
+
suggestion: 'Set updateKey to identify which rows to update (e.g., "id")'
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
break;
|
|
513
|
+
case 'delete':
|
|
514
|
+
if (!config.table) {
|
|
515
|
+
errors.push({
|
|
516
|
+
type: 'missing_required',
|
|
517
|
+
property: 'table',
|
|
518
|
+
message: 'Table name is required for delete operation',
|
|
519
|
+
fix: 'Specify the table to delete from'
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
if (!config.deleteKey) {
|
|
523
|
+
errors.push({
|
|
524
|
+
type: 'missing_required',
|
|
525
|
+
property: 'deleteKey',
|
|
526
|
+
message: 'Delete key is required to identify rows',
|
|
527
|
+
fix: 'Set deleteKey (e.g., "id") to specify which rows to delete'
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
break;
|
|
531
|
+
case 'execute':
|
|
532
|
+
if (!config.query) {
|
|
533
|
+
errors.push({
|
|
534
|
+
type: 'missing_required',
|
|
535
|
+
property: 'query',
|
|
536
|
+
message: 'SQL query is required',
|
|
537
|
+
fix: 'Provide the SQL query to execute'
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
if (config.connectionTimeout === undefined) {
|
|
543
|
+
suggestions.push('Consider setting connectionTimeout to handle slow connections');
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
static validateMySQL(context) {
|
|
547
|
+
const { config, errors, warnings, suggestions } = context;
|
|
548
|
+
const { operation } = config;
|
|
549
|
+
if (['execute', 'insert', 'update', 'delete'].includes(operation)) {
|
|
550
|
+
this.validateSQLQuery(context, 'mysql');
|
|
551
|
+
}
|
|
552
|
+
switch (operation) {
|
|
553
|
+
case 'insert':
|
|
554
|
+
if (!config.table) {
|
|
555
|
+
errors.push({
|
|
556
|
+
type: 'missing_required',
|
|
557
|
+
property: 'table',
|
|
558
|
+
message: 'Table name is required for insert operation',
|
|
559
|
+
fix: 'Specify the table to insert data into'
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
break;
|
|
563
|
+
case 'update':
|
|
564
|
+
if (!config.table) {
|
|
565
|
+
errors.push({
|
|
566
|
+
type: 'missing_required',
|
|
567
|
+
property: 'table',
|
|
568
|
+
message: 'Table name is required for update operation',
|
|
569
|
+
fix: 'Specify the table to update'
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
if (!config.updateKey) {
|
|
573
|
+
warnings.push({
|
|
574
|
+
type: 'missing_common',
|
|
575
|
+
property: 'updateKey',
|
|
576
|
+
message: 'No update key specified',
|
|
577
|
+
suggestion: 'Set updateKey to identify which rows to update'
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
break;
|
|
581
|
+
case 'delete':
|
|
582
|
+
if (!config.table) {
|
|
583
|
+
errors.push({
|
|
584
|
+
type: 'missing_required',
|
|
585
|
+
property: 'table',
|
|
586
|
+
message: 'Table name is required for delete operation',
|
|
587
|
+
fix: 'Specify the table to delete from'
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
break;
|
|
591
|
+
case 'execute':
|
|
592
|
+
if (!config.query) {
|
|
593
|
+
errors.push({
|
|
594
|
+
type: 'missing_required',
|
|
595
|
+
property: 'query',
|
|
596
|
+
message: 'SQL query is required',
|
|
597
|
+
fix: 'Provide the SQL query to execute'
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
if (config.timezone === undefined) {
|
|
603
|
+
suggestions.push('Consider setting timezone to ensure consistent date/time handling');
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
static validateSQLQuery(context, dbType = 'generic') {
|
|
607
|
+
const { config, errors, warnings, suggestions } = context;
|
|
608
|
+
const query = config.query || config.deleteQuery || config.updateQuery || '';
|
|
609
|
+
if (!query)
|
|
610
|
+
return;
|
|
611
|
+
const lowerQuery = query.toLowerCase();
|
|
612
|
+
if (query.includes('${') || query.includes('{{')) {
|
|
613
|
+
warnings.push({
|
|
614
|
+
type: 'security',
|
|
615
|
+
message: 'Query contains template expressions that might be vulnerable to SQL injection',
|
|
616
|
+
suggestion: 'Use parameterized queries with query parameters instead of string interpolation'
|
|
617
|
+
});
|
|
618
|
+
suggestions.push('Example: Use "SELECT * FROM users WHERE id = $1" with queryParams: [userId]');
|
|
619
|
+
}
|
|
620
|
+
if (lowerQuery.includes('delete') && !lowerQuery.includes('where')) {
|
|
621
|
+
errors.push({
|
|
622
|
+
type: 'invalid_value',
|
|
623
|
+
property: 'query',
|
|
624
|
+
message: 'DELETE query without WHERE clause will delete all records',
|
|
625
|
+
fix: 'Add a WHERE clause to specify which records to delete'
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
if (lowerQuery.includes('update') && !lowerQuery.includes('where')) {
|
|
629
|
+
warnings.push({
|
|
630
|
+
type: 'security',
|
|
631
|
+
message: 'UPDATE query without WHERE clause will update all records',
|
|
632
|
+
suggestion: 'Add a WHERE clause to specify which records to update'
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
if (lowerQuery.includes('truncate')) {
|
|
636
|
+
warnings.push({
|
|
637
|
+
type: 'security',
|
|
638
|
+
message: 'TRUNCATE will remove all data from the table',
|
|
639
|
+
suggestion: 'Consider using DELETE with WHERE clause if you need to keep some data'
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
if (lowerQuery.includes('drop')) {
|
|
643
|
+
errors.push({
|
|
644
|
+
type: 'invalid_value',
|
|
645
|
+
property: 'query',
|
|
646
|
+
message: 'DROP operations are extremely dangerous and will permanently delete database objects',
|
|
647
|
+
fix: 'Use this only if you really intend to delete tables/databases permanently'
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
if (lowerQuery.includes('select *')) {
|
|
651
|
+
suggestions.push('Consider selecting specific columns instead of * for better performance');
|
|
652
|
+
}
|
|
653
|
+
if (dbType === 'postgres') {
|
|
654
|
+
if (query.includes('$$')) {
|
|
655
|
+
suggestions.push('Dollar-quoted strings detected - ensure they are properly closed');
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
else if (dbType === 'mysql') {
|
|
659
|
+
if (query.includes('`')) {
|
|
660
|
+
suggestions.push('Using backticks for identifiers - ensure they are properly paired');
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
exports.NodeSpecificValidators = NodeSpecificValidators;
|
|
666
|
+
//# sourceMappingURL=node-specific-validators.js.map
|