snow-flow 1.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/.env.example +49 -0
- package/.mcp.json +106 -0
- package/.mcp.json.template +106 -0
- package/LICENSE +21 -0
- package/README.md +236 -0
- package/bin/snow-flow +4 -0
- package/bin/snow-flow.js +3 -0
- package/claude-flow +79 -0
- package/claude-flow.bat +18 -0
- package/claude-flow.config.json +20 -0
- package/claude-flow.ps1 +24 -0
- package/dist/agents/app-creator.agent.d.ts +55 -0
- package/dist/agents/app-creator.agent.d.ts.map +1 -0
- package/dist/agents/app-creator.agent.js +1292 -0
- package/dist/agents/app-creator.agent.js.map +1 -0
- package/dist/agents/base-snow-agent.d.ts +63 -0
- package/dist/agents/base-snow-agent.d.ts.map +1 -0
- package/dist/agents/base-snow-agent.js +296 -0
- package/dist/agents/base-snow-agent.js.map +1 -0
- package/dist/agents/script-generator.agent.d.ts +32 -0
- package/dist/agents/script-generator.agent.d.ts.map +1 -0
- package/dist/agents/script-generator.agent.js +772 -0
- package/dist/agents/script-generator.agent.js.map +1 -0
- package/dist/agents/ui-builder.agent.d.ts +50 -0
- package/dist/agents/ui-builder.agent.d.ts.map +1 -0
- package/dist/agents/ui-builder.agent.js +1539 -0
- package/dist/agents/ui-builder.agent.js.map +1 -0
- package/dist/agents/widget-builder.agent.d.ts +32 -0
- package/dist/agents/widget-builder.agent.d.ts.map +1 -0
- package/dist/agents/widget-builder.agent.js +439 -0
- package/dist/agents/widget-builder.agent.js.map +1 -0
- package/dist/agents/workflow-designer.agent.d.ts +31 -0
- package/dist/agents/workflow-designer.agent.d.ts.map +1 -0
- package/dist/agents/workflow-designer.agent.js +583 -0
- package/dist/agents/workflow-designer.agent.js.map +1 -0
- package/dist/api/error-handling.d.ts +214 -0
- package/dist/api/error-handling.d.ts.map +1 -0
- package/dist/api/error-handling.js +594 -0
- package/dist/api/error-handling.js.map +1 -0
- package/dist/api/flow-designer-api.d.ts +167 -0
- package/dist/api/flow-designer-api.d.ts.map +1 -0
- package/dist/api/flow-designer-api.js +555 -0
- package/dist/api/flow-designer-api.js.map +1 -0
- package/dist/api/natural-language-mapper.d.ts +126 -0
- package/dist/api/natural-language-mapper.d.ts.map +1 -0
- package/dist/api/natural-language-mapper.js +498 -0
- package/dist/api/natural-language-mapper.js.map +1 -0
- package/dist/api/performance-optimizer.d.ts +240 -0
- package/dist/api/performance-optimizer.d.ts.map +1 -0
- package/dist/api/performance-optimizer.js +701 -0
- package/dist/api/performance-optimizer.js.map +1 -0
- package/dist/api/transaction-manager.d.ts +189 -0
- package/dist/api/transaction-manager.d.ts.map +1 -0
- package/dist/api/transaction-manager.js +576 -0
- package/dist/api/transaction-manager.js.map +1 -0
- package/dist/cli/deploy-artifact.d.ts +7 -0
- package/dist/cli/deploy-artifact.d.ts.map +1 -0
- package/dist/cli/deploy-artifact.js +279 -0
- package/dist/cli/deploy-artifact.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2057 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/scope-manager.d.ts +75 -0
- package/dist/managers/scope-manager.d.ts.map +1 -0
- package/dist/managers/scope-manager.js +448 -0
- package/dist/managers/scope-manager.js.map +1 -0
- package/dist/mcp/mcp-wrapper.d.ts +8 -0
- package/dist/mcp/mcp-wrapper.d.ts.map +1 -0
- package/dist/mcp/mcp-wrapper.js +77 -0
- package/dist/mcp/mcp-wrapper.js.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.js +683 -0
- package/dist/mcp/servicenow-automation-mcp.js.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.js +972 -0
- package/dist/mcp/servicenow-deployment-mcp.js.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js +1121 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js +703 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.js +689 -0
- package/dist/mcp/servicenow-integration-mcp.js.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.js +1138 -0
- package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -0
- package/dist/mcp/servicenow-mcp-server.d.ts +37 -0
- package/dist/mcp/servicenow-mcp-server.d.ts.map +1 -0
- package/dist/mcp/servicenow-mcp-server.js +648 -0
- package/dist/mcp/servicenow-mcp-server.js.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts +15 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.js +1287 -0
- package/dist/mcp/servicenow-operations-mcp.js.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.js +557 -0
- package/dist/mcp/servicenow-platform-development-mcp.js.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts +79 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.js +320 -0
- package/dist/mcp/servicenow-progressive-indexer.js.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js +888 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js +812 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.js +599 -0
- package/dist/mcp/servicenow-update-set-mcp.js.map +1 -0
- package/dist/mcp/start-all-mcp-servers.d.ts +6 -0
- package/dist/mcp/start-all-mcp-servers.d.ts.map +1 -0
- package/dist/mcp/start-all-mcp-servers.js +65 -0
- package/dist/mcp/start-all-mcp-servers.js.map +1 -0
- package/dist/mcp/start-servicenow-mcp.d.ts +7 -0
- package/dist/mcp/start-servicenow-mcp.d.ts.map +1 -0
- package/dist/mcp/start-servicenow-mcp.js +64 -0
- package/dist/mcp/start-servicenow-mcp.js.map +1 -0
- package/dist/mcp/test-simple-mcp.d.ts +6 -0
- package/dist/mcp/test-simple-mcp.d.ts.map +1 -0
- package/dist/mcp/test-simple-mcp.js +64 -0
- package/dist/mcp/test-simple-mcp.js.map +1 -0
- package/dist/orchestrator/flow-composer.d.ts +269 -0
- package/dist/orchestrator/flow-composer.d.ts.map +1 -0
- package/dist/orchestrator/flow-composer.js +2221 -0
- package/dist/orchestrator/flow-composer.js.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts +260 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.js +906 -0
- package/dist/orchestrator/flow-pattern-templates.js.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts +202 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js +769 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js.map +1 -0
- package/dist/orchestrator/flow-validation-engine.d.ts +145 -0
- package/dist/orchestrator/flow-validation-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-validation-engine.js +663 -0
- package/dist/orchestrator/flow-validation-engine.js.map +1 -0
- package/dist/orchestrator/snow-orchestrator.d.ts +49 -0
- package/dist/orchestrator/snow-orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/snow-orchestrator.js +235 -0
- package/dist/orchestrator/snow-orchestrator.js.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts +230 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.js +791 -0
- package/dist/orchestrator/subflow-creation-handler.js.map +1 -0
- package/dist/strategies/global-scope-strategy.d.ts +123 -0
- package/dist/strategies/global-scope-strategy.d.ts.map +1 -0
- package/dist/strategies/global-scope-strategy.js +585 -0
- package/dist/strategies/global-scope-strategy.js.map +1 -0
- package/dist/types/index.d.ts +138 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/servicenow.types.d.ts +260 -0
- package/dist/types/servicenow.types.d.ts.map +1 -0
- package/dist/types/servicenow.types.js +3 -0
- package/dist/types/servicenow.types.js.map +1 -0
- package/dist/types/snow-flow.types.d.ts +114 -0
- package/dist/types/snow-flow.types.d.ts.map +1 -0
- package/dist/types/snow-flow.types.js +3 -0
- package/dist/types/snow-flow.types.js.map +1 -0
- package/dist/utils/action-type-cache.d.ts +66 -0
- package/dist/utils/action-type-cache.d.ts.map +1 -0
- package/dist/utils/action-type-cache.js +237 -0
- package/dist/utils/action-type-cache.js.map +1 -0
- package/dist/utils/agent-detector.d.ts +35 -0
- package/dist/utils/agent-detector.d.ts.map +1 -0
- package/dist/utils/agent-detector.js +353 -0
- package/dist/utils/agent-detector.js.map +1 -0
- package/dist/utils/flow-api-discovery.d.ts +151 -0
- package/dist/utils/flow-api-discovery.d.ts.map +1 -0
- package/dist/utils/flow-api-discovery.js +440 -0
- package/dist/utils/flow-api-discovery.js.map +1 -0
- package/dist/utils/flow-xml-generator.d.ts +41 -0
- package/dist/utils/flow-xml-generator.d.ts.map +1 -0
- package/dist/utils/flow-xml-generator.js +258 -0
- package/dist/utils/flow-xml-generator.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +51 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-auth-middleware.d.ts +58 -0
- package/dist/utils/mcp-auth-middleware.d.ts.map +1 -0
- package/dist/utils/mcp-auth-middleware.js +227 -0
- package/dist/utils/mcp-auth-middleware.js.map +1 -0
- package/dist/utils/mcp-config-manager.d.ts +126 -0
- package/dist/utils/mcp-config-manager.d.ts.map +1 -0
- package/dist/utils/mcp-config-manager.js +209 -0
- package/dist/utils/mcp-config-manager.js.map +1 -0
- package/dist/utils/mcp-server-manager.d.ts +91 -0
- package/dist/utils/mcp-server-manager.d.ts.map +1 -0
- package/dist/utils/mcp-server-manager.js +338 -0
- package/dist/utils/mcp-server-manager.js.map +1 -0
- package/dist/utils/scope-utils.d.ts +72 -0
- package/dist/utils/scope-utils.d.ts.map +1 -0
- package/dist/utils/scope-utils.js +386 -0
- package/dist/utils/scope-utils.js.map +1 -0
- package/dist/utils/servicenow-client.d.ts +233 -0
- package/dist/utils/servicenow-client.d.ts.map +1 -0
- package/dist/utils/servicenow-client.js +1465 -0
- package/dist/utils/servicenow-client.js.map +1 -0
- package/dist/utils/snow-oauth-old.d.ts +65 -0
- package/dist/utils/snow-oauth-old.d.ts.map +1 -0
- package/dist/utils/snow-oauth-old.js +345 -0
- package/dist/utils/snow-oauth-old.js.map +1 -0
- package/dist/utils/snow-oauth.d.ts +85 -0
- package/dist/utils/snow-oauth.d.ts.map +1 -0
- package/dist/utils/snow-oauth.js +512 -0
- package/dist/utils/snow-oauth.js.map +1 -0
- package/dist/utils/template-engine.d.ts +76 -0
- package/dist/utils/template-engine.d.ts.map +1 -0
- package/dist/utils/template-engine.js +391 -0
- package/dist/utils/template-engine.js.map +1 -0
- package/dist/version.d.ts +35 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +72 -0
- package/dist/version.js.map +1 -0
- package/mcp-wrapper.sh +12 -0
- package/package.json +77 -0
- package/reports/swarm-auto-centralized-1752649029776.json +13 -0
- package/scripts/postinstall.js +30 -0
- package/scripts/setup-mcp.js +89 -0
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ServiceNow Subflow Creation Handler
|
|
4
|
+
*
|
|
5
|
+
* This module handles the creation of subflows with proper input/output management,
|
|
6
|
+
* validation, and integration with the main flow composer.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.SubflowCreationHandler = void 0;
|
|
10
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
11
|
+
const servicenow_client_js_1 = require("../utils/servicenow-client.js");
|
|
12
|
+
const flow_subflow_decision_engine_js_1 = require("./flow-subflow-decision-engine.js");
|
|
13
|
+
/**
|
|
14
|
+
* Subflow Creation Handler
|
|
15
|
+
*/
|
|
16
|
+
class SubflowCreationHandler {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.templates = new Map();
|
|
19
|
+
this.logger = new logger_js_1.Logger('SubflowCreationHandler');
|
|
20
|
+
this.client = new servicenow_client_js_1.ServiceNowClient();
|
|
21
|
+
this.initializeTemplates();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a subflow from a candidate
|
|
25
|
+
*/
|
|
26
|
+
async createSubflow(candidate) {
|
|
27
|
+
this.logger.info('Creating subflow from candidate', { name: candidate.name });
|
|
28
|
+
try {
|
|
29
|
+
// Validate the candidate
|
|
30
|
+
const validationResult = this.validateCandidate(candidate);
|
|
31
|
+
if (!validationResult.isValid) {
|
|
32
|
+
return {
|
|
33
|
+
success: false,
|
|
34
|
+
validationErrors: validationResult.errors
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Build the subflow definition
|
|
38
|
+
const subflowDef = this.buildSubflowDefinition(candidate);
|
|
39
|
+
// Validate the complete definition
|
|
40
|
+
const defValidation = this.validateSubflowDefinition(subflowDef);
|
|
41
|
+
if (!defValidation.isValid) {
|
|
42
|
+
return {
|
|
43
|
+
success: false,
|
|
44
|
+
validationErrors: defValidation.errors
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// Deploy to ServiceNow
|
|
48
|
+
const deployResult = await this.deploySubflow(subflowDef);
|
|
49
|
+
if (!deployResult.success) {
|
|
50
|
+
return {
|
|
51
|
+
success: false,
|
|
52
|
+
validationErrors: [deployResult.error || 'Deployment failed']
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Generate recommendations
|
|
56
|
+
const recommendations = this.generateRecommendations(subflowDef);
|
|
57
|
+
return {
|
|
58
|
+
success: true,
|
|
59
|
+
subflow: subflowDef,
|
|
60
|
+
sys_id: deployResult.sys_id,
|
|
61
|
+
url: deployResult.url,
|
|
62
|
+
warnings: defValidation.warnings,
|
|
63
|
+
recommendations
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
this.logger.error('Failed to create subflow', error);
|
|
68
|
+
return {
|
|
69
|
+
success: false,
|
|
70
|
+
validationErrors: [error instanceof Error ? error.message : String(error)]
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create multiple subflows from candidates
|
|
76
|
+
*/
|
|
77
|
+
async createMultipleSubflows(candidates) {
|
|
78
|
+
this.logger.info('Creating multiple subflows', { count: candidates.length });
|
|
79
|
+
const results = [];
|
|
80
|
+
for (const candidate of candidates) {
|
|
81
|
+
const result = await this.createSubflow(candidate);
|
|
82
|
+
results.push(result);
|
|
83
|
+
// Add delay to avoid overwhelming ServiceNow
|
|
84
|
+
await this.delay(500);
|
|
85
|
+
}
|
|
86
|
+
return results;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Build subflow definition from candidate
|
|
90
|
+
*/
|
|
91
|
+
buildSubflowDefinition(candidate) {
|
|
92
|
+
const name = this.sanitizeName(candidate.name);
|
|
93
|
+
const label = candidate.name;
|
|
94
|
+
// Get template if available
|
|
95
|
+
const template = this.findMatchingTemplate(candidate);
|
|
96
|
+
return {
|
|
97
|
+
name,
|
|
98
|
+
label,
|
|
99
|
+
description: candidate.description,
|
|
100
|
+
category: this.determineCategory(candidate),
|
|
101
|
+
inputs: this.buildInputDefinitions(candidate.inputs, template),
|
|
102
|
+
outputs: this.buildOutputDefinitions(candidate.outputs, template),
|
|
103
|
+
activities: this.buildActivities(candidate, template),
|
|
104
|
+
connections: this.buildConnections(candidate, template),
|
|
105
|
+
errorHandling: this.buildErrorHandling(candidate),
|
|
106
|
+
metadata: {
|
|
107
|
+
version: '1.0.0',
|
|
108
|
+
author: 'ServiceNow Multi-Agent System',
|
|
109
|
+
created: new Date(),
|
|
110
|
+
updated: new Date(),
|
|
111
|
+
tags: this.generateTags(candidate),
|
|
112
|
+
complexity: candidate.complexity,
|
|
113
|
+
reusability: candidate.reusability,
|
|
114
|
+
testCoverage: 0,
|
|
115
|
+
documentation: this.generateDocumentation(candidate),
|
|
116
|
+
dependencies: [],
|
|
117
|
+
compatibleVersions: ['Tokyo', 'Utah', 'Vancouver']
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Build input definitions with enhanced metadata
|
|
123
|
+
*/
|
|
124
|
+
buildInputDefinitions(inputs, template) {
|
|
125
|
+
return inputs.map((input, index) => {
|
|
126
|
+
const baseInput = template?.baseInputs.find(base => base.name === input.name);
|
|
127
|
+
return {
|
|
128
|
+
...input,
|
|
129
|
+
label: this.generateInputLabel(input.name),
|
|
130
|
+
category: this.categorizeInput(input),
|
|
131
|
+
order: index + 1,
|
|
132
|
+
tooltip: input.description,
|
|
133
|
+
placeholder: this.generatePlaceholder(input),
|
|
134
|
+
options: this.generateInputOptions(input),
|
|
135
|
+
dependsOn: this.findInputDependencies(input, inputs),
|
|
136
|
+
conditionalLogic: baseInput?.conditionalLogic
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Build output definitions with enhanced metadata
|
|
142
|
+
*/
|
|
143
|
+
buildOutputDefinitions(outputs, template) {
|
|
144
|
+
return outputs.map((output, index) => {
|
|
145
|
+
const baseOutput = template?.baseOutputs.find(base => base.name === output.name);
|
|
146
|
+
return {
|
|
147
|
+
...output,
|
|
148
|
+
label: this.generateOutputLabel(output.name),
|
|
149
|
+
category: this.categorizeOutput(output),
|
|
150
|
+
order: index + 1,
|
|
151
|
+
tooltip: output.description,
|
|
152
|
+
format: this.generateOutputFormat(output),
|
|
153
|
+
conditionalLogic: baseOutput?.conditionalLogic
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Build activities for the subflow
|
|
159
|
+
*/
|
|
160
|
+
buildActivities(candidate, template) {
|
|
161
|
+
const activities = [];
|
|
162
|
+
// Add start activity
|
|
163
|
+
activities.push({
|
|
164
|
+
id: 'start',
|
|
165
|
+
name: 'Start',
|
|
166
|
+
type: 'start',
|
|
167
|
+
label: 'Start',
|
|
168
|
+
description: 'Subflow start point',
|
|
169
|
+
inputs: {},
|
|
170
|
+
outputs: {},
|
|
171
|
+
position: { x: 100, y: 100 },
|
|
172
|
+
configuration: {},
|
|
173
|
+
errorHandling: []
|
|
174
|
+
});
|
|
175
|
+
// Add main processing activities based on actions
|
|
176
|
+
candidate.actions.forEach((action, index) => {
|
|
177
|
+
const activityId = `activity_${index + 1}`;
|
|
178
|
+
const activity = this.createActivityFromAction(action, activityId, index);
|
|
179
|
+
activities.push(activity);
|
|
180
|
+
});
|
|
181
|
+
// Add end activity
|
|
182
|
+
activities.push({
|
|
183
|
+
id: 'end',
|
|
184
|
+
name: 'End',
|
|
185
|
+
type: 'end',
|
|
186
|
+
label: 'End',
|
|
187
|
+
description: 'Subflow end point',
|
|
188
|
+
inputs: {},
|
|
189
|
+
outputs: this.buildEndOutputs(candidate.outputs),
|
|
190
|
+
position: { x: 100 + (candidate.actions.length + 1) * 200, y: 100 },
|
|
191
|
+
configuration: {},
|
|
192
|
+
errorHandling: []
|
|
193
|
+
});
|
|
194
|
+
return activities;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Build connections between activities
|
|
198
|
+
*/
|
|
199
|
+
buildConnections(candidate, template) {
|
|
200
|
+
const connections = [];
|
|
201
|
+
// Sequential connections
|
|
202
|
+
let previousId = 'start';
|
|
203
|
+
candidate.actions.forEach((action, index) => {
|
|
204
|
+
const currentId = `activity_${index + 1}`;
|
|
205
|
+
connections.push({
|
|
206
|
+
id: `connection_${index + 1}`,
|
|
207
|
+
from: previousId,
|
|
208
|
+
to: currentId,
|
|
209
|
+
label: this.generateConnectionLabel(action)
|
|
210
|
+
});
|
|
211
|
+
previousId = currentId;
|
|
212
|
+
});
|
|
213
|
+
// Final connection to end
|
|
214
|
+
connections.push({
|
|
215
|
+
id: 'connection_end',
|
|
216
|
+
from: previousId,
|
|
217
|
+
to: 'end',
|
|
218
|
+
label: 'Complete'
|
|
219
|
+
});
|
|
220
|
+
return connections;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Build error handling for the subflow
|
|
224
|
+
*/
|
|
225
|
+
buildErrorHandling(candidate) {
|
|
226
|
+
const errorHandling = [];
|
|
227
|
+
// Global error handler
|
|
228
|
+
errorHandling.push({
|
|
229
|
+
id: 'global_error',
|
|
230
|
+
condition: 'any_activity_failed',
|
|
231
|
+
action: 'stop',
|
|
232
|
+
parameters: {
|
|
233
|
+
message: `Error in ${candidate.name} subflow`,
|
|
234
|
+
log_level: 'error'
|
|
235
|
+
},
|
|
236
|
+
description: 'Handle any unexpected errors'
|
|
237
|
+
});
|
|
238
|
+
// Specific error handlers based on complexity
|
|
239
|
+
if (candidate.complexity === flow_subflow_decision_engine_js_1.ComplexityLevel.HIGH || candidate.complexity === flow_subflow_decision_engine_js_1.ComplexityLevel.VERY_HIGH) {
|
|
240
|
+
errorHandling.push({
|
|
241
|
+
id: 'retry_handler',
|
|
242
|
+
condition: 'temporary_failure',
|
|
243
|
+
action: 'retry',
|
|
244
|
+
parameters: {
|
|
245
|
+
max_retries: 3,
|
|
246
|
+
delay_seconds: 5
|
|
247
|
+
},
|
|
248
|
+
description: 'Retry on temporary failures'
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
return errorHandling;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Create activity from action string
|
|
255
|
+
*/
|
|
256
|
+
createActivityFromAction(action, activityId, index) {
|
|
257
|
+
const activityType = this.mapActionToActivityType(action);
|
|
258
|
+
return {
|
|
259
|
+
id: activityId,
|
|
260
|
+
name: this.generateActivityName(action),
|
|
261
|
+
type: activityType,
|
|
262
|
+
label: this.generateActivityLabel(action),
|
|
263
|
+
description: this.generateActivityDescription(action),
|
|
264
|
+
inputs: this.generateActivityInputs(action),
|
|
265
|
+
outputs: this.generateActivityOutputs(action),
|
|
266
|
+
position: { x: 100 + (index + 1) * 200, y: 100 },
|
|
267
|
+
configuration: this.generateActivityConfiguration(action),
|
|
268
|
+
errorHandling: this.generateActivityErrorHandling(action)
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Validate candidate before processing
|
|
273
|
+
*/
|
|
274
|
+
validateCandidate(candidate) {
|
|
275
|
+
const errors = [];
|
|
276
|
+
if (!candidate.name || candidate.name.trim() === '') {
|
|
277
|
+
errors.push('Subflow name is required');
|
|
278
|
+
}
|
|
279
|
+
if (!candidate.description || candidate.description.trim() === '') {
|
|
280
|
+
errors.push('Subflow description is required');
|
|
281
|
+
}
|
|
282
|
+
if (!candidate.actions || candidate.actions.length === 0) {
|
|
283
|
+
errors.push('At least one action is required');
|
|
284
|
+
}
|
|
285
|
+
if (candidate.inputs.length === 0) {
|
|
286
|
+
errors.push('At least one input parameter is required');
|
|
287
|
+
}
|
|
288
|
+
if (candidate.outputs.length === 0) {
|
|
289
|
+
errors.push('At least one output parameter is required');
|
|
290
|
+
}
|
|
291
|
+
// Validate input parameters
|
|
292
|
+
candidate.inputs.forEach((input, index) => {
|
|
293
|
+
if (!input.name || input.name.trim() === '') {
|
|
294
|
+
errors.push(`Input parameter ${index + 1} name is required`);
|
|
295
|
+
}
|
|
296
|
+
if (!input.type || input.type.trim() === '') {
|
|
297
|
+
errors.push(`Input parameter ${index + 1} type is required`);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
// Validate output parameters
|
|
301
|
+
candidate.outputs.forEach((output, index) => {
|
|
302
|
+
if (!output.name || output.name.trim() === '') {
|
|
303
|
+
errors.push(`Output parameter ${index + 1} name is required`);
|
|
304
|
+
}
|
|
305
|
+
if (!output.type || output.type.trim() === '') {
|
|
306
|
+
errors.push(`Output parameter ${index + 1} type is required`);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
return { isValid: errors.length === 0, errors };
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Validate complete subflow definition
|
|
313
|
+
*/
|
|
314
|
+
validateSubflowDefinition(definition) {
|
|
315
|
+
const errors = [];
|
|
316
|
+
const warnings = [];
|
|
317
|
+
// Validate basic structure
|
|
318
|
+
if (!definition.name || definition.name.trim() === '') {
|
|
319
|
+
errors.push('Subflow name is required');
|
|
320
|
+
}
|
|
321
|
+
if (definition.activities.length < 3) { // start, at least one activity, end
|
|
322
|
+
errors.push('Subflow must have at least one processing activity');
|
|
323
|
+
}
|
|
324
|
+
if (definition.connections.length < 2) { // start->activity, activity->end
|
|
325
|
+
errors.push('Subflow must have proper connections');
|
|
326
|
+
}
|
|
327
|
+
// Validate connections
|
|
328
|
+
const activityIds = new Set(definition.activities.map(a => a.id));
|
|
329
|
+
definition.connections.forEach(conn => {
|
|
330
|
+
if (!activityIds.has(conn.from)) {
|
|
331
|
+
errors.push(`Connection references unknown activity: ${conn.from}`);
|
|
332
|
+
}
|
|
333
|
+
if (!activityIds.has(conn.to)) {
|
|
334
|
+
errors.push(`Connection references unknown activity: ${conn.to}`);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
// Warnings for best practices
|
|
338
|
+
if (definition.inputs.length > 10) {
|
|
339
|
+
warnings.push('Subflow has many input parameters, consider grouping related parameters');
|
|
340
|
+
}
|
|
341
|
+
if (definition.outputs.length > 5) {
|
|
342
|
+
warnings.push('Subflow has many output parameters, consider consolidating outputs');
|
|
343
|
+
}
|
|
344
|
+
if (definition.activities.length > 15) {
|
|
345
|
+
warnings.push('Subflow is complex, consider breaking into smaller subflows');
|
|
346
|
+
}
|
|
347
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Deploy subflow to ServiceNow
|
|
351
|
+
*/
|
|
352
|
+
async deploySubflow(definition) {
|
|
353
|
+
try {
|
|
354
|
+
// Convert to ServiceNow format
|
|
355
|
+
const serviceNowFormat = this.convertToServiceNowFormat(definition);
|
|
356
|
+
// Deploy via ServiceNow client (using createFlow for now until createSubflow is implemented)
|
|
357
|
+
const result = await this.client.createFlow(serviceNowFormat);
|
|
358
|
+
if (result.success) {
|
|
359
|
+
return {
|
|
360
|
+
success: true,
|
|
361
|
+
sys_id: result.data.sys_id,
|
|
362
|
+
url: `https://${process.env.SNOW_INSTANCE}/flow_designer.do#/subflow/${result.data.sys_id}`
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
return {
|
|
367
|
+
success: false,
|
|
368
|
+
error: result.error || 'Unknown deployment error'
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
return {
|
|
374
|
+
success: false,
|
|
375
|
+
error: error instanceof Error ? error.message : String(error)
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Convert subflow definition to ServiceNow format
|
|
381
|
+
*/
|
|
382
|
+
convertToServiceNowFormat(definition) {
|
|
383
|
+
return {
|
|
384
|
+
name: definition.name,
|
|
385
|
+
label: definition.label,
|
|
386
|
+
description: definition.description,
|
|
387
|
+
category: definition.category,
|
|
388
|
+
active: true,
|
|
389
|
+
inputs: definition.inputs.map(input => ({
|
|
390
|
+
name: input.name,
|
|
391
|
+
label: input.label,
|
|
392
|
+
type: input.type,
|
|
393
|
+
mandatory: input.required,
|
|
394
|
+
description: input.description,
|
|
395
|
+
default_value: input.defaultValue,
|
|
396
|
+
tooltip: input.tooltip,
|
|
397
|
+
options: input.options,
|
|
398
|
+
order: input.order
|
|
399
|
+
})),
|
|
400
|
+
outputs: definition.outputs.map(output => ({
|
|
401
|
+
name: output.name,
|
|
402
|
+
label: output.label,
|
|
403
|
+
type: output.type,
|
|
404
|
+
description: output.description,
|
|
405
|
+
order: output.order
|
|
406
|
+
})),
|
|
407
|
+
activities: definition.activities.map(activity => ({
|
|
408
|
+
id: activity.id,
|
|
409
|
+
name: activity.name,
|
|
410
|
+
type: activity.type,
|
|
411
|
+
label: activity.label,
|
|
412
|
+
description: activity.description,
|
|
413
|
+
position: activity.position,
|
|
414
|
+
inputs: activity.inputs,
|
|
415
|
+
outputs: activity.outputs,
|
|
416
|
+
configuration: activity.configuration
|
|
417
|
+
})),
|
|
418
|
+
connections: definition.connections.map(conn => ({
|
|
419
|
+
id: conn.id,
|
|
420
|
+
from: conn.from,
|
|
421
|
+
to: conn.to,
|
|
422
|
+
label: conn.label,
|
|
423
|
+
condition: conn.condition
|
|
424
|
+
}))
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Generate recommendations for the subflow
|
|
429
|
+
*/
|
|
430
|
+
generateRecommendations(definition) {
|
|
431
|
+
const recommendations = [];
|
|
432
|
+
// Input recommendations
|
|
433
|
+
if (definition.inputs.length > 5) {
|
|
434
|
+
recommendations.push('Consider grouping related input parameters into objects');
|
|
435
|
+
}
|
|
436
|
+
// Activity recommendations
|
|
437
|
+
if (definition.activities.length > 10) {
|
|
438
|
+
recommendations.push('Consider breaking this subflow into smaller, more focused subflows');
|
|
439
|
+
}
|
|
440
|
+
// Error handling recommendations
|
|
441
|
+
if (definition.errorHandling.length === 0) {
|
|
442
|
+
recommendations.push('Add error handling for better robustness');
|
|
443
|
+
}
|
|
444
|
+
// Documentation recommendations
|
|
445
|
+
if (!definition.metadata.documentation || definition.metadata.documentation.length < 100) {
|
|
446
|
+
recommendations.push('Add comprehensive documentation for better maintainability');
|
|
447
|
+
}
|
|
448
|
+
// Testing recommendations
|
|
449
|
+
recommendations.push('Create test cases to verify subflow functionality');
|
|
450
|
+
recommendations.push('Consider adding validation activities for input parameters');
|
|
451
|
+
return recommendations;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Initialize subflow templates
|
|
455
|
+
*/
|
|
456
|
+
initializeTemplates() {
|
|
457
|
+
// Approval template
|
|
458
|
+
this.templates.set('approval', {
|
|
459
|
+
name: 'Approval Process',
|
|
460
|
+
description: 'Standard approval workflow template',
|
|
461
|
+
category: 'Approval',
|
|
462
|
+
complexity: flow_subflow_decision_engine_js_1.ComplexityLevel.MEDIUM,
|
|
463
|
+
baseInputs: [
|
|
464
|
+
{
|
|
465
|
+
name: 'record',
|
|
466
|
+
label: 'Record',
|
|
467
|
+
type: 'reference',
|
|
468
|
+
required: true,
|
|
469
|
+
description: 'Record to approve',
|
|
470
|
+
category: 'Data',
|
|
471
|
+
order: 1
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
name: 'approvers',
|
|
475
|
+
label: 'Approvers',
|
|
476
|
+
type: 'string',
|
|
477
|
+
required: true,
|
|
478
|
+
description: 'List of approvers',
|
|
479
|
+
category: 'Configuration',
|
|
480
|
+
order: 2
|
|
481
|
+
}
|
|
482
|
+
],
|
|
483
|
+
baseOutputs: [
|
|
484
|
+
{
|
|
485
|
+
name: 'approval_state',
|
|
486
|
+
label: 'Approval State',
|
|
487
|
+
type: 'string',
|
|
488
|
+
description: 'Final approval state',
|
|
489
|
+
category: 'Result',
|
|
490
|
+
order: 1
|
|
491
|
+
}
|
|
492
|
+
],
|
|
493
|
+
baseActivities: [],
|
|
494
|
+
baseConnections: [],
|
|
495
|
+
customizationPoints: ['approval_logic', 'notification_template', 'timeout_handling']
|
|
496
|
+
});
|
|
497
|
+
// Notification template
|
|
498
|
+
this.templates.set('notification', {
|
|
499
|
+
name: 'Notification Sender',
|
|
500
|
+
description: 'Multi-channel notification template',
|
|
501
|
+
category: 'Communication',
|
|
502
|
+
complexity: flow_subflow_decision_engine_js_1.ComplexityLevel.LOW,
|
|
503
|
+
baseInputs: [
|
|
504
|
+
{
|
|
505
|
+
name: 'recipients',
|
|
506
|
+
label: 'Recipients',
|
|
507
|
+
type: 'string',
|
|
508
|
+
required: true,
|
|
509
|
+
description: 'Notification recipients',
|
|
510
|
+
category: 'Configuration',
|
|
511
|
+
order: 1
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
name: 'message',
|
|
515
|
+
label: 'Message',
|
|
516
|
+
type: 'string',
|
|
517
|
+
required: true,
|
|
518
|
+
description: 'Notification message',
|
|
519
|
+
category: 'Content',
|
|
520
|
+
order: 2
|
|
521
|
+
}
|
|
522
|
+
],
|
|
523
|
+
baseOutputs: [
|
|
524
|
+
{
|
|
525
|
+
name: 'sent_successfully',
|
|
526
|
+
label: 'Sent Successfully',
|
|
527
|
+
type: 'boolean',
|
|
528
|
+
description: 'Whether notification was sent',
|
|
529
|
+
category: 'Result',
|
|
530
|
+
order: 1
|
|
531
|
+
}
|
|
532
|
+
],
|
|
533
|
+
baseActivities: [],
|
|
534
|
+
baseConnections: [],
|
|
535
|
+
customizationPoints: ['message_template', 'delivery_method', 'retry_logic']
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
// Helper methods
|
|
539
|
+
sanitizeName(name) {
|
|
540
|
+
return name.toLowerCase().replace(/[^a-z0-9_]/g, '_').replace(/^_+|_+$/g, '');
|
|
541
|
+
}
|
|
542
|
+
determineCategory(candidate) {
|
|
543
|
+
if (candidate.name.toLowerCase().includes('approval'))
|
|
544
|
+
return 'Approval';
|
|
545
|
+
if (candidate.name.toLowerCase().includes('notification'))
|
|
546
|
+
return 'Communication';
|
|
547
|
+
if (candidate.name.toLowerCase().includes('data'))
|
|
548
|
+
return 'Data Processing';
|
|
549
|
+
if (candidate.name.toLowerCase().includes('integration'))
|
|
550
|
+
return 'Integration';
|
|
551
|
+
return 'Utility';
|
|
552
|
+
}
|
|
553
|
+
findMatchingTemplate(candidate) {
|
|
554
|
+
const nameKey = candidate.name.toLowerCase();
|
|
555
|
+
for (const [key, template] of this.templates) {
|
|
556
|
+
if (nameKey.includes(key)) {
|
|
557
|
+
return template;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return undefined;
|
|
561
|
+
}
|
|
562
|
+
generateTags(candidate) {
|
|
563
|
+
const tags = [];
|
|
564
|
+
tags.push(candidate.complexity.toLowerCase());
|
|
565
|
+
tags.push(candidate.reusability.toLowerCase());
|
|
566
|
+
tags.push('auto-generated');
|
|
567
|
+
return tags;
|
|
568
|
+
}
|
|
569
|
+
generateDocumentation(candidate) {
|
|
570
|
+
return `
|
|
571
|
+
# ${candidate.name}
|
|
572
|
+
|
|
573
|
+
## Description
|
|
574
|
+
${candidate.description}
|
|
575
|
+
|
|
576
|
+
## Reason for Creation
|
|
577
|
+
${candidate.reason}
|
|
578
|
+
|
|
579
|
+
## Complexity Level
|
|
580
|
+
${candidate.complexity}
|
|
581
|
+
|
|
582
|
+
## Reusability Level
|
|
583
|
+
${candidate.reusability}
|
|
584
|
+
|
|
585
|
+
## Actions
|
|
586
|
+
${candidate.actions.map(action => `- ${action}`).join('\n')}
|
|
587
|
+
|
|
588
|
+
## Usage
|
|
589
|
+
This subflow can be used in any flow that requires ${candidate.name.toLowerCase()} functionality.
|
|
590
|
+
|
|
591
|
+
## Inputs
|
|
592
|
+
${candidate.inputs.map(input => `- **${input.name}** (${input.type}): ${input.description}`).join('\n')}
|
|
593
|
+
|
|
594
|
+
## Outputs
|
|
595
|
+
${candidate.outputs.map(output => `- **${output.name}** (${output.type}): ${output.description}`).join('\n')}
|
|
596
|
+
`.trim();
|
|
597
|
+
}
|
|
598
|
+
generateInputLabel(name) {
|
|
599
|
+
return name.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
600
|
+
}
|
|
601
|
+
generateOutputLabel(name) {
|
|
602
|
+
return name.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
603
|
+
}
|
|
604
|
+
categorizeInput(input) {
|
|
605
|
+
if (input.type === 'reference')
|
|
606
|
+
return 'Data';
|
|
607
|
+
if (input.name.includes('config') || input.name.includes('setting'))
|
|
608
|
+
return 'Configuration';
|
|
609
|
+
if (input.name.includes('message') || input.name.includes('content'))
|
|
610
|
+
return 'Content';
|
|
611
|
+
return 'General';
|
|
612
|
+
}
|
|
613
|
+
categorizeOutput(output) {
|
|
614
|
+
if (output.name.includes('result') || output.name.includes('success'))
|
|
615
|
+
return 'Result';
|
|
616
|
+
if (output.name.includes('data') || output.name.includes('record'))
|
|
617
|
+
return 'Data';
|
|
618
|
+
if (output.name.includes('status') || output.name.includes('state'))
|
|
619
|
+
return 'Status';
|
|
620
|
+
return 'General';
|
|
621
|
+
}
|
|
622
|
+
generatePlaceholder(input) {
|
|
623
|
+
switch (input.type) {
|
|
624
|
+
case 'string': return `Enter ${input.name}`;
|
|
625
|
+
case 'number': return '0';
|
|
626
|
+
case 'boolean': return 'true';
|
|
627
|
+
default: return '';
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
generateInputOptions(input) {
|
|
631
|
+
if (input.name.includes('priority')) {
|
|
632
|
+
return ['1 - Critical', '2 - High', '3 - Medium', '4 - Low'];
|
|
633
|
+
}
|
|
634
|
+
if (input.name.includes('state')) {
|
|
635
|
+
return ['New', 'In Progress', 'Completed', 'Cancelled'];
|
|
636
|
+
}
|
|
637
|
+
return undefined;
|
|
638
|
+
}
|
|
639
|
+
findInputDependencies(input, allInputs) {
|
|
640
|
+
// Simple dependency detection based on naming patterns
|
|
641
|
+
const dependencies = [];
|
|
642
|
+
if (input.name.includes('_type') || input.name.includes('_method')) {
|
|
643
|
+
const baseNames = allInputs.map(i => i.name).filter(name => name !== input.name && input.name.includes(name.split('_')[0]));
|
|
644
|
+
dependencies.push(...baseNames);
|
|
645
|
+
}
|
|
646
|
+
return dependencies;
|
|
647
|
+
}
|
|
648
|
+
generateOutputFormat(output) {
|
|
649
|
+
switch (output.type) {
|
|
650
|
+
case 'string': return 'text';
|
|
651
|
+
case 'number': return 'numeric';
|
|
652
|
+
case 'boolean': return 'true/false';
|
|
653
|
+
case 'object': return 'json';
|
|
654
|
+
default: return 'text';
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
buildEndOutputs(outputs) {
|
|
658
|
+
const endOutputs = {};
|
|
659
|
+
outputs.forEach(output => {
|
|
660
|
+
endOutputs[output.name] = `\${subflow.${output.name}}`;
|
|
661
|
+
});
|
|
662
|
+
return endOutputs;
|
|
663
|
+
}
|
|
664
|
+
generateConnectionLabel(action) {
|
|
665
|
+
return action.charAt(0).toUpperCase() + action.slice(1);
|
|
666
|
+
}
|
|
667
|
+
mapActionToActivityType(action) {
|
|
668
|
+
const actionMap = {
|
|
669
|
+
'approve': 'approval',
|
|
670
|
+
'reject': 'approval',
|
|
671
|
+
'notify': 'notification',
|
|
672
|
+
'send': 'notification',
|
|
673
|
+
'create': 'create_record',
|
|
674
|
+
'update': 'update_record',
|
|
675
|
+
'delete': 'delete_record',
|
|
676
|
+
'validate': 'script',
|
|
677
|
+
'process': 'script',
|
|
678
|
+
'transform': 'script',
|
|
679
|
+
'integrate': 'rest',
|
|
680
|
+
'schedule': 'timer',
|
|
681
|
+
'assign': 'assignment',
|
|
682
|
+
'escalate': 'escalation',
|
|
683
|
+
'complete': 'script',
|
|
684
|
+
'cancel': 'script',
|
|
685
|
+
'retry': 'script',
|
|
686
|
+
'log': 'log',
|
|
687
|
+
'track': 'script',
|
|
688
|
+
'monitor': 'script'
|
|
689
|
+
};
|
|
690
|
+
return actionMap[action] || 'script';
|
|
691
|
+
}
|
|
692
|
+
generateActivityName(action) {
|
|
693
|
+
return action.charAt(0).toUpperCase() + action.slice(1);
|
|
694
|
+
}
|
|
695
|
+
generateActivityLabel(action) {
|
|
696
|
+
return action.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
697
|
+
}
|
|
698
|
+
generateActivityDescription(action) {
|
|
699
|
+
return `Execute ${action} operation`;
|
|
700
|
+
}
|
|
701
|
+
generateActivityInputs(action) {
|
|
702
|
+
const inputs = {};
|
|
703
|
+
// Common inputs for all activities
|
|
704
|
+
inputs.record = '${subflow.record}';
|
|
705
|
+
// Action-specific inputs
|
|
706
|
+
switch (action) {
|
|
707
|
+
case 'approve':
|
|
708
|
+
case 'reject':
|
|
709
|
+
inputs.approvers = '${subflow.approvers}';
|
|
710
|
+
break;
|
|
711
|
+
case 'notify':
|
|
712
|
+
case 'send':
|
|
713
|
+
inputs.recipients = '${subflow.recipients}';
|
|
714
|
+
inputs.message = '${subflow.message}';
|
|
715
|
+
break;
|
|
716
|
+
case 'create':
|
|
717
|
+
case 'update':
|
|
718
|
+
inputs.table = '${subflow.table}';
|
|
719
|
+
inputs.data = '${subflow.data}';
|
|
720
|
+
break;
|
|
721
|
+
}
|
|
722
|
+
return inputs;
|
|
723
|
+
}
|
|
724
|
+
generateActivityOutputs(action) {
|
|
725
|
+
const outputs = {};
|
|
726
|
+
// Common outputs
|
|
727
|
+
outputs.success = '${step.success}';
|
|
728
|
+
// Action-specific outputs
|
|
729
|
+
switch (action) {
|
|
730
|
+
case 'approve':
|
|
731
|
+
case 'reject':
|
|
732
|
+
outputs.approval_state = '${step.approval_state}';
|
|
733
|
+
outputs.approved_by = '${step.approved_by}';
|
|
734
|
+
break;
|
|
735
|
+
case 'notify':
|
|
736
|
+
case 'send':
|
|
737
|
+
outputs.notification_sent = '${step.notification_sent}';
|
|
738
|
+
break;
|
|
739
|
+
case 'create':
|
|
740
|
+
outputs.created_record = '${step.created_record}';
|
|
741
|
+
break;
|
|
742
|
+
case 'update':
|
|
743
|
+
outputs.updated_record = '${step.updated_record}';
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
return outputs;
|
|
747
|
+
}
|
|
748
|
+
generateActivityConfiguration(action) {
|
|
749
|
+
const config = {};
|
|
750
|
+
switch (action) {
|
|
751
|
+
case 'approve':
|
|
752
|
+
config.approval_type = 'sequential';
|
|
753
|
+
config.timeout = '24 hours';
|
|
754
|
+
break;
|
|
755
|
+
case 'notify':
|
|
756
|
+
config.notification_type = 'email';
|
|
757
|
+
break;
|
|
758
|
+
case 'create':
|
|
759
|
+
config.insert_mode = 'single';
|
|
760
|
+
break;
|
|
761
|
+
}
|
|
762
|
+
return config;
|
|
763
|
+
}
|
|
764
|
+
generateActivityErrorHandling(action) {
|
|
765
|
+
const errorHandling = [];
|
|
766
|
+
// Common error handling
|
|
767
|
+
errorHandling.push({
|
|
768
|
+
condition: 'step.success === false',
|
|
769
|
+
action: 'stop',
|
|
770
|
+
parameters: {
|
|
771
|
+
message: `Failed to execute ${action}`
|
|
772
|
+
}
|
|
773
|
+
});
|
|
774
|
+
// Action-specific error handling
|
|
775
|
+
if (action === 'approve') {
|
|
776
|
+
errorHandling.push({
|
|
777
|
+
condition: 'step.timeout === true',
|
|
778
|
+
action: 'escalate',
|
|
779
|
+
parameters: {
|
|
780
|
+
escalation_group: 'managers'
|
|
781
|
+
}
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
return errorHandling;
|
|
785
|
+
}
|
|
786
|
+
delay(ms) {
|
|
787
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
exports.SubflowCreationHandler = SubflowCreationHandler;
|
|
791
|
+
//# sourceMappingURL=subflow-creation-handler.js.map
|