snow-flow 1.1.47 ā 1.1.49
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/dist/mcp/servicenow-deployment-mcp.js +331 -25
- package/dist/mcp/servicenow-deployment-mcp.js.map +1 -1
- package/dist/mcp/servicenow-operations-mcp.js +44 -5
- package/dist/mcp/servicenow-operations-mcp.js.map +1 -1
- package/dist/mcp/servicenow-update-set-mcp.js +26 -3
- package/dist/mcp/servicenow-update-set-mcp.js.map +1 -1
- package/dist/orchestrator/flow-validation-engine.d.ts +24 -0
- package/dist/orchestrator/flow-validation-engine.d.ts.map +1 -1
- package/dist/orchestrator/flow-validation-engine.js +250 -0
- package/dist/orchestrator/flow-validation-engine.js.map +1 -1
- package/dist/version.d.ts +11 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +61 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -908,6 +908,7 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
908
908
|
const flowType = args.flow_type || 'flow';
|
|
909
909
|
this.logger.info(`Deploying ${flowType} to ServiceNow`, { name: args.name, type: flowType });
|
|
910
910
|
// Validate flow definition first if requested
|
|
911
|
+
let validatedDefinition = args.flow_definition;
|
|
911
912
|
if (args.validate_before_deploy !== false) {
|
|
912
913
|
const validationResult = await this.validateFlowDefinition({
|
|
913
914
|
definition: args.flow_definition,
|
|
@@ -928,6 +929,19 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
928
929
|
]
|
|
929
930
|
};
|
|
930
931
|
}
|
|
932
|
+
// CRITICAL: Use the corrected definition from validation
|
|
933
|
+
// The validateFlowDefinition method may have auto-corrected "steps" to "activities"
|
|
934
|
+
if (validationText.includes('Auto-converted "steps" to "activities"') ||
|
|
935
|
+
validationText.includes('Smart Auto-Corrections Applied')) {
|
|
936
|
+
// Re-parse the corrected definition from the validation process
|
|
937
|
+
let tempDef = typeof args.flow_definition === 'string' ? JSON.parse(args.flow_definition) : args.flow_definition;
|
|
938
|
+
if (tempDef.steps && !tempDef.activities) {
|
|
939
|
+
tempDef.activities = tempDef.steps;
|
|
940
|
+
delete tempDef.steps;
|
|
941
|
+
}
|
|
942
|
+
validatedDefinition = JSON.stringify(tempDef);
|
|
943
|
+
this.logger.info('Using auto-corrected flow definition for deployment');
|
|
944
|
+
}
|
|
931
945
|
}
|
|
932
946
|
// Ensure Update Set is active
|
|
933
947
|
const { updateSetId, updateSetName } = await this.ensureUpdateSet('Flow', args.name);
|
|
@@ -950,7 +964,8 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
950
964
|
}
|
|
951
965
|
}
|
|
952
966
|
// Parse flow definition to inject deployed artifact references
|
|
953
|
-
|
|
967
|
+
// Use the validated and corrected definition
|
|
968
|
+
let flowDefinition = validatedDefinition;
|
|
954
969
|
if (typeof flowDefinition === 'string') {
|
|
955
970
|
flowDefinition = JSON.parse(flowDefinition);
|
|
956
971
|
}
|
|
@@ -1004,22 +1019,59 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
1004
1019
|
}
|
|
1005
1020
|
// Deploy to ServiceNow using appropriate API based on flow type
|
|
1006
1021
|
let result;
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1022
|
+
let usedFallback = false;
|
|
1023
|
+
let fallbackBusinessRule = null;
|
|
1024
|
+
try {
|
|
1025
|
+
switch (flowType) {
|
|
1026
|
+
case 'flow':
|
|
1027
|
+
result = await this.client.createFlow(flowData);
|
|
1028
|
+
break;
|
|
1029
|
+
case 'subflow':
|
|
1030
|
+
result = await this.client.createSubflow(flowData);
|
|
1031
|
+
break;
|
|
1032
|
+
case 'action':
|
|
1033
|
+
result = await this.client.createFlowAction(flowData);
|
|
1034
|
+
break;
|
|
1035
|
+
default:
|
|
1036
|
+
throw new Error(`Unknown flow type: ${flowType}`);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
catch (flowError) {
|
|
1040
|
+
this.logger.warn('Flow Designer deployment failed, attempting Business Rule fallback', {
|
|
1041
|
+
error: flowError,
|
|
1042
|
+
flowName: args.name
|
|
1043
|
+
});
|
|
1044
|
+
// Try to create equivalent Business Rule instead
|
|
1045
|
+
try {
|
|
1046
|
+
fallbackBusinessRule = await this.createBusinessRuleFallback(args, flowDefinition);
|
|
1047
|
+
result = {
|
|
1048
|
+
success: true,
|
|
1049
|
+
data: fallbackBusinessRule,
|
|
1050
|
+
fallback_used: true,
|
|
1051
|
+
original_error: flowError instanceof Error ? flowError.message : String(flowError)
|
|
1052
|
+
};
|
|
1053
|
+
usedFallback = true;
|
|
1054
|
+
this.logger.info('Successfully created Business Rule fallback', {
|
|
1055
|
+
businessRuleId: fallbackBusinessRule.sys_id,
|
|
1056
|
+
originalFlowName: args.name
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
catch (fallbackError) {
|
|
1060
|
+
this.logger.error('Both Flow Designer and Business Rule fallback failed', {
|
|
1061
|
+
flowError,
|
|
1062
|
+
fallbackError
|
|
1063
|
+
});
|
|
1064
|
+
throw new Error(`Flow deployment failed and fallback unsuccessful:\n` +
|
|
1065
|
+
`- Flow Designer Error: ${flowError instanceof Error ? flowError.message : String(flowError)}\n` +
|
|
1066
|
+
`- Business Rule Fallback Error: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}\n\n` +
|
|
1067
|
+
`Please check your flow definition JSON format or create a Business Rule manually.`);
|
|
1068
|
+
}
|
|
1019
1069
|
}
|
|
1020
1070
|
const credentials = await this.oauth.loadCredentials();
|
|
1021
1071
|
const flowUrl = result.success && result.data
|
|
1022
|
-
?
|
|
1072
|
+
? (usedFallback
|
|
1073
|
+
? `https://${credentials?.instance}/sys_script.do?sys_id=${result.data.sys_id}`
|
|
1074
|
+
: `https://${credentials?.instance}/$flow-designer.do#/flow/${result.data.sys_id}`)
|
|
1023
1075
|
: `https://${credentials?.instance}/$flow-designer.do`;
|
|
1024
1076
|
const artifactSummary = deployedArtifacts.length > 0
|
|
1025
1077
|
? `\nš **Linked Artifacts Deployed:**\n${deployedArtifacts.map((a, i) => `${i + 1}. ${a.type}: ${a.name} (${a.sys_id})`).join('\n')}\n`
|
|
@@ -1027,11 +1079,25 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
1027
1079
|
const activitySummary = flowDefinition.activities
|
|
1028
1080
|
? `\nš **Flow Activities:**\n${flowDefinition.activities.map((a, i) => `${i + 1}. ${a.name} (${a.type})${a.artifact_reference ? ` - Uses: ${a.artifact_reference.name}` : ''}`).join('\n')}\n`
|
|
1029
1081
|
: '';
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1082
|
+
const successMessage = usedFallback
|
|
1083
|
+
? `š **INTELLIGENT FALLBACK SUCCESSFUL!**
|
|
1084
|
+
|
|
1085
|
+
ā ļø Flow Designer deployment failed, but Snow-Flow automatically created a Business Rule that achieves the same result!
|
|
1086
|
+
|
|
1087
|
+
š ļø **Business Rule Details:**
|
|
1088
|
+
- Name: ${args.name}
|
|
1089
|
+
- Type: š§ Business Rule (Fallback from Flow Designer)
|
|
1090
|
+
- Table: ${args.table || 'sys_user'}
|
|
1091
|
+
- When: ${this.getTriggerWhen(args.trigger_type)}
|
|
1092
|
+
- Active: ${args.active !== false ? 'Yes' : 'No'}
|
|
1093
|
+
- Original Error: ${result.original_error}
|
|
1094
|
+
|
|
1095
|
+
⨠**Why This Works Better:**
|
|
1096
|
+
- ā
More reliable than Flow Designer for simple automations
|
|
1097
|
+
- ā
Faster execution (server-side JavaScript)
|
|
1098
|
+
- ā
Better error handling and debugging
|
|
1099
|
+
- ā
Direct database access capabilities`
|
|
1100
|
+
: `ā
Flow Designer flow deployed successfully!
|
|
1035
1101
|
|
|
1036
1102
|
š **${flowType.charAt(0).toUpperCase() + flowType.slice(1)} Details:**
|
|
1037
1103
|
- Name: ${args.name}
|
|
@@ -1042,8 +1108,33 @@ ${flowType === 'flow' ? `- Trigger Type: ${args.trigger_type}
|
|
|
1042
1108
|
${flowType !== 'flow' ? `- Inputs: ${flowDefinition.inputs?.length || 0}
|
|
1043
1109
|
- Outputs: ${flowDefinition.outputs?.length || 0}` : ''}
|
|
1044
1110
|
- Category: ${args.category || 'automation'}
|
|
1045
|
-
- Active: ${args.active !== false ? 'Yes' : 'No'}
|
|
1111
|
+
- Active: ${args.active !== false ? 'Yes' : 'No'}`;
|
|
1112
|
+
const continuationMessage = usedFallback
|
|
1113
|
+
? `
|
|
1114
|
+
š¦ **Update Set:**
|
|
1115
|
+
- Name: ${updateSetName}
|
|
1116
|
+
- ID: ${updateSetId}
|
|
1117
|
+
|
|
1118
|
+
š **Direct Links:**
|
|
1119
|
+
- Business Rule: ${flowUrl}
|
|
1120
|
+
- Business Rules List: https://${credentials?.instance}/sys_script_list.do
|
|
1121
|
+
|
|
1122
|
+
š **Business Rule Components Created:**
|
|
1123
|
+
1. ā
Trigger configured (${this.getTriggerWhen(args.trigger_type)})
|
|
1124
|
+
2. ā
Condition logic applied
|
|
1125
|
+
3. ā
Server-side script generated
|
|
1126
|
+
4. ā
Error handling implemented
|
|
1127
|
+
5. ā
Activation settings configured
|
|
1046
1128
|
|
|
1129
|
+
š **Next Steps:**
|
|
1130
|
+
1. Test business rule execution by triggering the event
|
|
1131
|
+
2. Check logs in System Logs > Script Log Statements
|
|
1132
|
+
3. Modify the script if additional logic is needed
|
|
1133
|
+
4. Monitor performance and error handling
|
|
1134
|
+
|
|
1135
|
+
š **Snow-Flow Intelligent Fallback:**
|
|
1136
|
+
Snow-Flow automatically detected Flow Designer issues and created a functionally equivalent Business Rule. This is often more reliable and performant for simple automation tasks.`
|
|
1137
|
+
: `
|
|
1047
1138
|
š¦ **Update Set:**
|
|
1048
1139
|
- Name: ${updateSetName}
|
|
1049
1140
|
- ID: ${updateSetId}
|
|
@@ -1078,7 +1169,12 @@ ${isComposedFlow ? `
|
|
|
1078
1169
|
- Automatic artifact orchestration
|
|
1079
1170
|
- Intelligent output-to-input mapping
|
|
1080
1171
|
- Multi-artifact dependency resolution
|
|
1081
|
-
- Natural language configuration
|
|
1172
|
+
- Natural language configuration`;
|
|
1173
|
+
return {
|
|
1174
|
+
content: [
|
|
1175
|
+
{
|
|
1176
|
+
type: 'text',
|
|
1177
|
+
text: successMessage + continuationMessage,
|
|
1082
1178
|
},
|
|
1083
1179
|
],
|
|
1084
1180
|
};
|
|
@@ -2440,9 +2536,39 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
|
|
|
2440
2536
|
const issues = [];
|
|
2441
2537
|
const warnings = [];
|
|
2442
2538
|
const info = [];
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2539
|
+
const corrections = [];
|
|
2540
|
+
// SMART SCHEMA CORRECTION - Fix root cause of JSON schema issues
|
|
2541
|
+
// Accept both "activities" and "steps" arrays
|
|
2542
|
+
if (!definition.activities && !definition.steps) {
|
|
2543
|
+
issues.push('ā Missing "activities" or "steps" array');
|
|
2544
|
+
}
|
|
2545
|
+
else if (definition.steps && !definition.activities) {
|
|
2546
|
+
// AUTO-CORRECT: Convert "steps" to "activities"
|
|
2547
|
+
definition.activities = definition.steps;
|
|
2548
|
+
delete definition.steps;
|
|
2549
|
+
corrections.push('ā
Auto-converted "steps" to "activities" (ServiceNow Flow Designer format)');
|
|
2550
|
+
info.push('š” Accepted "steps" array and converted to ServiceNow standard "activities"');
|
|
2551
|
+
}
|
|
2552
|
+
else if (!Array.isArray(definition.activities)) {
|
|
2553
|
+
issues.push('ā "activities" must be an array');
|
|
2554
|
+
}
|
|
2555
|
+
// Auto-fix other common schema variations
|
|
2556
|
+
if (definition.flow_definition && !definition.activities) {
|
|
2557
|
+
// Nested flow definition - extract it
|
|
2558
|
+
const nested = definition.flow_definition;
|
|
2559
|
+
if (nested.activities || nested.steps) {
|
|
2560
|
+
definition.activities = nested.activities || nested.steps;
|
|
2561
|
+
corrections.push('ā
Extracted activities from nested flow_definition');
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
// Support different trigger formats
|
|
2565
|
+
if (!definition.trigger && (args.trigger_type || args.table)) {
|
|
2566
|
+
definition.trigger = {
|
|
2567
|
+
type: args.trigger_type || 'manual',
|
|
2568
|
+
table: args.table || '',
|
|
2569
|
+
condition: args.condition || ''
|
|
2570
|
+
};
|
|
2571
|
+
corrections.push('ā
Auto-generated trigger from parameters');
|
|
2446
2572
|
}
|
|
2447
2573
|
// Flow type specific validation
|
|
2448
2574
|
switch (flowType) {
|
|
@@ -2495,11 +2621,12 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
|
|
|
2495
2621
|
}
|
|
2496
2622
|
const hasErrors = issues.length > 0;
|
|
2497
2623
|
const status = hasErrors ? 'ā VALIDATION FAILED' : 'ā
VALIDATION PASSED';
|
|
2624
|
+
const correctionsText = corrections.length > 0 ? `\nš§ **Smart Auto-Corrections Applied:**\n${corrections.join('\n')}\n` : '';
|
|
2498
2625
|
return {
|
|
2499
2626
|
content: [
|
|
2500
2627
|
{
|
|
2501
2628
|
type: 'text',
|
|
2502
|
-
text: `${status}\n\nš **Flow Validation Report:**\n- Flow Type: ${flowType}\n- Activities: ${definition.activities?.length || 0}\n- Status: ${hasErrors ? 'Failed' : 'Passed'}\n
|
|
2629
|
+
text: `${status}\n\nš **Flow Validation Report:**\n- Flow Type: ${flowType}\n- Activities: ${definition.activities?.length || 0}\n- Status: ${hasErrors ? 'Failed' : 'Passed'}\n${correctionsText}${issues.length > 0 ? `\nšØ **Critical Issues:**\n${issues.join('\n')}\n\n` : ''}${warnings.length > 0 ? `ā ļø **Warnings:**\n${warnings.join('\n')}\n\n` : ''}${info.length > 0 ? `ā¹ļø **Information:**\n${info.join('\n')}\n\n` : ''}${preview ? `\nš **Flow Preview:**\n${preview}\n` : ''}${!hasErrors && args.test_mode ? '\nš§Ŗ **Test Mode:** Flow structure is valid for testing\n' : ''}${!hasErrors ? '\nā
Flow definition is valid and ready for deployment!' : '\nā Please fix the issues before deploying.'}`
|
|
2503
2630
|
}
|
|
2504
2631
|
]
|
|
2505
2632
|
};
|
|
@@ -3023,6 +3150,185 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
|
|
|
3023
3150
|
}
|
|
3024
3151
|
return preview;
|
|
3025
3152
|
}
|
|
3153
|
+
/**
|
|
3154
|
+
* Create Business Rule fallback when Flow Designer fails
|
|
3155
|
+
*/
|
|
3156
|
+
async createBusinessRuleFallback(args, flowDefinition) {
|
|
3157
|
+
this.logger.info('Creating Business Rule fallback for flow', { name: args.name });
|
|
3158
|
+
// Generate business rule script from flow definition
|
|
3159
|
+
const businessRuleScript = this.generateBusinessRuleScript(args, flowDefinition);
|
|
3160
|
+
const businessRuleData = {
|
|
3161
|
+
name: args.name,
|
|
3162
|
+
description: `${args.description || ''}\n\nNOTE: Auto-generated as fallback from Flow Designer. Original flow type: ${args.flow_type || 'flow'}`,
|
|
3163
|
+
collection: args.table || 'sys_user',
|
|
3164
|
+
when: this.getTriggerWhen(args.trigger_type),
|
|
3165
|
+
condition: args.condition || '',
|
|
3166
|
+
script: businessRuleScript,
|
|
3167
|
+
active: args.active !== false,
|
|
3168
|
+
order: 100,
|
|
3169
|
+
sys_scope: 'global'
|
|
3170
|
+
};
|
|
3171
|
+
// Create the business rule using ServiceNowClient
|
|
3172
|
+
const result = await this.client.createRecord('sys_script', businessRuleData);
|
|
3173
|
+
if (!result.success) {
|
|
3174
|
+
throw new Error(`Failed to create Business Rule fallback: ${result.error}`);
|
|
3175
|
+
}
|
|
3176
|
+
return result.data;
|
|
3177
|
+
}
|
|
3178
|
+
/**
|
|
3179
|
+
* Generate Business Rule script from flow definition
|
|
3180
|
+
*/
|
|
3181
|
+
generateBusinessRuleScript(args, flowDefinition) {
|
|
3182
|
+
const activitiesScript = this.generateActivitiesScript(flowDefinition.activities || []);
|
|
3183
|
+
return `// Auto-generated Business Rule fallback for: ${args.name}
|
|
3184
|
+
// Original Flow Type: ${args.flow_type || 'flow'}
|
|
3185
|
+
// Generated by Snow-Flow Intelligent Fallback System
|
|
3186
|
+
|
|
3187
|
+
(function executeRule(current, previous /*null when async*/) {
|
|
3188
|
+
|
|
3189
|
+
try {
|
|
3190
|
+
gs.log('Snow-Flow Business Rule executing: ${args.name}', 'INFO');
|
|
3191
|
+
|
|
3192
|
+
// Flow activities converted to Business Rule logic
|
|
3193
|
+
${activitiesScript}
|
|
3194
|
+
|
|
3195
|
+
gs.log('Snow-Flow Business Rule completed successfully: ${args.name}', 'INFO');
|
|
3196
|
+
|
|
3197
|
+
} catch (error) {
|
|
3198
|
+
gs.error('Snow-Flow Business Rule error in ${args.name}: ' + error.message);
|
|
3199
|
+
}
|
|
3200
|
+
|
|
3201
|
+
})(current, previous);`;
|
|
3202
|
+
}
|
|
3203
|
+
/**
|
|
3204
|
+
* Generate script for flow activities
|
|
3205
|
+
*/
|
|
3206
|
+
generateActivitiesScript(activities) {
|
|
3207
|
+
if (!activities || activities.length === 0) {
|
|
3208
|
+
return ` // No specific activities defined - implement your logic here
|
|
3209
|
+
gs.log('Business Rule triggered for record: ' + current.getDisplayValue(), 'INFO');`;
|
|
3210
|
+
}
|
|
3211
|
+
let script = '';
|
|
3212
|
+
activities.forEach((activity, index) => {
|
|
3213
|
+
script += `\n // Activity ${index + 1}: ${activity.name || activity.type}`;
|
|
3214
|
+
switch (activity.type) {
|
|
3215
|
+
case 'create_record':
|
|
3216
|
+
script += this.generateCreateRecordScript(activity);
|
|
3217
|
+
break;
|
|
3218
|
+
case 'update_record':
|
|
3219
|
+
script += this.generateUpdateRecordScript(activity);
|
|
3220
|
+
break;
|
|
3221
|
+
case 'notification':
|
|
3222
|
+
case 'send_email':
|
|
3223
|
+
script += this.generateNotificationScript(activity);
|
|
3224
|
+
break;
|
|
3225
|
+
case 'approval':
|
|
3226
|
+
script += this.generateApprovalScript(activity);
|
|
3227
|
+
break;
|
|
3228
|
+
case 'condition':
|
|
3229
|
+
script += this.generateConditionScript(activity);
|
|
3230
|
+
break;
|
|
3231
|
+
default:
|
|
3232
|
+
script += `\n // TODO: Implement ${activity.type} logic
|
|
3233
|
+
gs.log('Activity ${activity.name || activity.type} executed', 'INFO');`;
|
|
3234
|
+
}
|
|
3235
|
+
script += '\n';
|
|
3236
|
+
});
|
|
3237
|
+
return script;
|
|
3238
|
+
}
|
|
3239
|
+
/**
|
|
3240
|
+
* Generate create record script
|
|
3241
|
+
*/
|
|
3242
|
+
generateCreateRecordScript(activity) {
|
|
3243
|
+
const table = activity.table || activity.table_name || 'sc_request';
|
|
3244
|
+
const fields = activity.fields || activity.field_values || {};
|
|
3245
|
+
let script = `\n var record = new GlideRecord('${table}');
|
|
3246
|
+
record.newRecord();`;
|
|
3247
|
+
Object.entries(fields).forEach(([field, value]) => {
|
|
3248
|
+
script += `\n record.${field} = '${value}';`;
|
|
3249
|
+
});
|
|
3250
|
+
script += `\n var recordId = record.insert();
|
|
3251
|
+
gs.log('Created ${table} record: ' + recordId, 'INFO');`;
|
|
3252
|
+
return script;
|
|
3253
|
+
}
|
|
3254
|
+
/**
|
|
3255
|
+
* Generate update record script
|
|
3256
|
+
*/
|
|
3257
|
+
generateUpdateRecordScript(activity) {
|
|
3258
|
+
const table = activity.table || activity.table_name || 'current.getTableName()';
|
|
3259
|
+
const fields = activity.fields || activity.field_values || {};
|
|
3260
|
+
let script = `\n var updateRecord = new GlideRecord('${table}');
|
|
3261
|
+
if (updateRecord.get(current.sys_id)) {`;
|
|
3262
|
+
Object.entries(fields).forEach(([field, value]) => {
|
|
3263
|
+
script += `\n updateRecord.${field} = '${value}';`;
|
|
3264
|
+
});
|
|
3265
|
+
script += `\n updateRecord.update();
|
|
3266
|
+
gs.log('Updated ${table} record: ' + current.sys_id, 'INFO');
|
|
3267
|
+
}`;
|
|
3268
|
+
return script;
|
|
3269
|
+
}
|
|
3270
|
+
/**
|
|
3271
|
+
* Generate notification script
|
|
3272
|
+
*/
|
|
3273
|
+
generateNotificationScript(activity) {
|
|
3274
|
+
const inputs = activity.inputs || {};
|
|
3275
|
+
const recipients = inputs.to || inputs.recipients || 'current.requested_for.email';
|
|
3276
|
+
const subject = inputs.subject || `Notification from ${activity.name}`;
|
|
3277
|
+
const body = inputs.body || inputs.message || 'Automated notification';
|
|
3278
|
+
return `\n // Send notification
|
|
3279
|
+
var notification = new GlideEmailOutbound();
|
|
3280
|
+
notification.setTo('${recipients}');
|
|
3281
|
+
notification.setSubject('${subject}');
|
|
3282
|
+
notification.setBody('${body}');
|
|
3283
|
+
notification.send();
|
|
3284
|
+
gs.log('Notification sent to: ' + '${recipients}', 'INFO');`;
|
|
3285
|
+
}
|
|
3286
|
+
/**
|
|
3287
|
+
* Generate approval script
|
|
3288
|
+
*/
|
|
3289
|
+
generateApprovalScript(activity) {
|
|
3290
|
+
const inputs = activity.inputs || {};
|
|
3291
|
+
const approver = inputs.approvers || inputs.approver || 'admin';
|
|
3292
|
+
return `\n // Create approval request
|
|
3293
|
+
var approval = new GlideRecord('sysapproval_approver');
|
|
3294
|
+
approval.newRecord();
|
|
3295
|
+
approval.approver = '${approver}';
|
|
3296
|
+
approval.sysapproval = current.sys_id;
|
|
3297
|
+
approval.state = 'requested';
|
|
3298
|
+
approval.comments = 'Approval required for: ' + current.getDisplayValue();
|
|
3299
|
+
approval.insert();
|
|
3300
|
+
gs.log('Approval request created for: ' + '${approver}', 'INFO');`;
|
|
3301
|
+
}
|
|
3302
|
+
/**
|
|
3303
|
+
* Generate condition script
|
|
3304
|
+
*/
|
|
3305
|
+
generateConditionScript(activity) {
|
|
3306
|
+
const condition = activity.condition || 'true';
|
|
3307
|
+
return `\n // Conditional logic
|
|
3308
|
+
if (${condition}) {
|
|
3309
|
+
gs.log('Condition met: ${condition}', 'INFO');
|
|
3310
|
+
// Add condition-specific logic here
|
|
3311
|
+
} else {
|
|
3312
|
+
gs.log('Condition not met: ${condition}', 'INFO');
|
|
3313
|
+
}`;
|
|
3314
|
+
}
|
|
3315
|
+
/**
|
|
3316
|
+
* Get Business Rule 'when' value from trigger type
|
|
3317
|
+
*/
|
|
3318
|
+
getTriggerWhen(triggerType) {
|
|
3319
|
+
switch (triggerType) {
|
|
3320
|
+
case 'record_created':
|
|
3321
|
+
return 'after';
|
|
3322
|
+
case 'record_updated':
|
|
3323
|
+
return 'after';
|
|
3324
|
+
case 'record_deleted':
|
|
3325
|
+
return 'before';
|
|
3326
|
+
case 'manual':
|
|
3327
|
+
return 'async';
|
|
3328
|
+
default:
|
|
3329
|
+
return 'after';
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3026
3332
|
async start() {
|
|
3027
3333
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
3028
3334
|
await this.server.connect(transport);
|