snow-flow 1.3.0 → 1.3.2
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/.claude-flow/queen/queen-memory.db +0 -0
- package/.env.example +249 -14
- package/CLAUDE.md +185 -24
- package/README.md +55 -5
- package/dist/api/error-handling.js +898 -4
- package/dist/api/performance-optimizer.js +3 -2
- package/dist/cli.js +590 -200
- package/dist/config/snow-flow-config.js +320 -8
- package/dist/health/system-health.js +288 -21
- package/dist/mcp/base-mcp-server.js +2 -0
- package/dist/mcp/http-transport-wrapper.js +65 -4
- package/dist/mcp/servicenow-automation-mcp-refactored.js +90 -9
- package/dist/mcp/servicenow-deployment-mcp-refactored.js +151 -2
- package/dist/mcp/servicenow-deployment-mcp.js +828 -15
- package/dist/mcp/servicenow-integration-mcp-refactored.js +100 -9
- package/dist/mcp/servicenow-intelligent-mcp.js +198 -7
- package/dist/mcp/servicenow-memory-mcp.js +2 -1
- package/dist/mcp/servicenow-operations-mcp-refactored.js +3 -2
- package/dist/mcp/servicenow-xml-flow-mcp.js +671 -0
- package/dist/mcp/shared/base-mcp-server.js +1356 -8
- package/dist/mcp/shared/mcp-resource-manager.js +304 -0
- package/dist/queen/parallel-agent-engine.js +26 -8
- package/dist/queen/servicenow-queen.js +47 -44
- package/dist/sparc/sparc-help.js +37 -26
- package/dist/sparc/team-sparc.js +60 -16
- package/dist/utils/action-type-cache.js +2 -1
- package/dist/utils/mcp-config-manager.js +7 -3
- package/dist/utils/mcp-server-manager.js +7 -3
- package/dist/utils/servicenow-client.js +134 -107
- package/dist/utils/servicenow-id-generator.js +171 -0
- package/dist/utils/snow-oauth.js +13 -8
- package/dist/utils/widget-template-generator.js +1690 -0
- package/dist/utils/xml-first-flow-generator.js +473 -0
- package/dist/version.js +7 -1
- package/flow-update-sets/flow_build_automated_approval_flow_with_notifications_flow.xml +203 -0
- package/flow-update-sets/flow_create_approval_flow_for_equipment_requests_flow.xml +206 -0
- package/flow-update-sets/flow_create_equipment_approval_flow_with_manager_approv_flow.xml +254 -0
- package/flow-update-sets/iphone_15_pro_approval_flow.xml +203 -0
- package/flow-update-sets/test_iphone_approval_flow_flow.xml +303 -0
- package/package.json +2 -1
- package/test-config.js +55 -0
- package/test-real-monitoring.js +184 -0
|
@@ -12,13 +12,17 @@ exports.ServiceNowClient = void 0;
|
|
|
12
12
|
const axios_1 = __importDefault(require("axios"));
|
|
13
13
|
const snow_oauth_1 = require("./snow-oauth");
|
|
14
14
|
const action_type_cache_1 = require("./action-type-cache");
|
|
15
|
+
const snow_flow_config_js_1 = require("../config/snow-flow-config.js");
|
|
16
|
+
const widget_template_generator_js_1 = require("./widget-template-generator.js");
|
|
17
|
+
const logger_1 = require("./logger");
|
|
15
18
|
const flow_structure_builder_1 = require("./flow-structure-builder");
|
|
16
19
|
class ServiceNowClient {
|
|
17
20
|
constructor() {
|
|
18
21
|
this.credentials = null;
|
|
22
|
+
this.logger = new logger_1.Logger('ServiceNowClient');
|
|
19
23
|
this.oauth = new snow_oauth_1.ServiceNowOAuth();
|
|
20
24
|
this.client = axios_1.default.create({
|
|
21
|
-
timeout:
|
|
25
|
+
timeout: snow_flow_config_js_1.snowFlowConfig.servicenow.timeout,
|
|
22
26
|
headers: {
|
|
23
27
|
'Content-Type': 'application/json',
|
|
24
28
|
'Accept': 'application/json'
|
|
@@ -27,8 +31,8 @@ class ServiceNowClient {
|
|
|
27
31
|
// 🔧 CRITICAL FIX: Add makeRequest method to Axios instance to fix phantom calls
|
|
28
32
|
// Some code expects makeRequest to exist on this.client (the Axios instance)
|
|
29
33
|
this.client.makeRequest = async (config) => {
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
this.logger.debug('🔧 AXIOS makeRequest called! Config:', config);
|
|
35
|
+
this.logger.debug('🔧 Routing to appropriate HTTP method...');
|
|
32
36
|
// Route to the appropriate Axios method based on the request config
|
|
33
37
|
const method = (config.method || 'GET').toLowerCase();
|
|
34
38
|
const url = config.url || config.endpoint;
|
|
@@ -72,10 +76,10 @@ class ServiceNowClient {
|
|
|
72
76
|
// Check if this is a 401 error and we haven't already tried to refresh
|
|
73
77
|
if (error.response?.status === 401 && !originalRequest._retry) {
|
|
74
78
|
originalRequest._retry = true;
|
|
75
|
-
|
|
79
|
+
this.logger.info('🔄 Received 401 error, attempting token refresh...');
|
|
76
80
|
const refreshResult = await this.oauth.refreshAccessToken();
|
|
77
81
|
if (refreshResult.success && refreshResult.accessToken) {
|
|
78
|
-
|
|
82
|
+
this.logger.info('✅ Token refreshed successfully, retrying request...');
|
|
79
83
|
// Update local credentials
|
|
80
84
|
if (this.credentials) {
|
|
81
85
|
this.credentials.accessToken = refreshResult.accessToken;
|
|
@@ -87,7 +91,7 @@ class ServiceNowClient {
|
|
|
87
91
|
}
|
|
88
92
|
else {
|
|
89
93
|
console.error('❌ Token refresh failed:', refreshResult.error);
|
|
90
|
-
|
|
94
|
+
this.logger.warn('💡 Please run "snow-flow auth login" to re-authenticate');
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
// Log other errors for debugging
|
|
@@ -147,7 +151,7 @@ class ServiceNowClient {
|
|
|
147
151
|
// Try to refresh the token
|
|
148
152
|
const refreshResult = await this.oauth.refreshAccessToken();
|
|
149
153
|
if (refreshResult.success && refreshResult.accessToken) {
|
|
150
|
-
|
|
154
|
+
this.logger.info('✅ Token refreshed successfully');
|
|
151
155
|
// Update local credentials
|
|
152
156
|
this.credentials.accessToken = refreshResult.accessToken;
|
|
153
157
|
return; // Success!
|
|
@@ -175,10 +179,10 @@ class ServiceNowClient {
|
|
|
175
179
|
const fiveMinutesFromNow = new Date(now.getTime() + 5 * 60 * 1000);
|
|
176
180
|
// If token expires in the next 5 minutes, refresh it
|
|
177
181
|
if (expiresAt <= fiveMinutesFromNow) {
|
|
178
|
-
|
|
182
|
+
this.logger.info('🔄 Token expiring soon, refreshing proactively...');
|
|
179
183
|
const refreshResult = await this.oauth.refreshAccessToken();
|
|
180
184
|
if (refreshResult.success) {
|
|
181
|
-
|
|
185
|
+
this.logger.info('✅ Token refreshed proactively');
|
|
182
186
|
if (this.credentials && refreshResult.accessToken) {
|
|
183
187
|
this.credentials.accessToken = refreshResult.accessToken;
|
|
184
188
|
}
|
|
@@ -290,7 +294,7 @@ class ServiceNowClient {
|
|
|
290
294
|
];
|
|
291
295
|
for (const test of tests) {
|
|
292
296
|
try {
|
|
293
|
-
|
|
297
|
+
this.logger.info(`Running diagnostic: ${test.name}...`);
|
|
294
298
|
const result = await test.test();
|
|
295
299
|
diagnostics.tests[test.name] = {
|
|
296
300
|
status: '✅ PASS',
|
|
@@ -412,8 +416,8 @@ class ServiceNowClient {
|
|
|
412
416
|
*/
|
|
413
417
|
async createWidget(widget) {
|
|
414
418
|
try {
|
|
415
|
-
|
|
416
|
-
|
|
419
|
+
this.logger.info('🎨 Creating ServiceNow widget...');
|
|
420
|
+
this.logger.info(`📋 Widget Name: ${widget.name}`);
|
|
417
421
|
// Add pre-deployment validation for widgets
|
|
418
422
|
if (!widget.name || widget.name.trim() === '') {
|
|
419
423
|
throw new Error('Widget name is required');
|
|
@@ -422,7 +426,30 @@ class ServiceNowClient {
|
|
|
422
426
|
throw new Error('Widget title is required');
|
|
423
427
|
}
|
|
424
428
|
if (!widget.template || widget.template.trim() === '') {
|
|
425
|
-
console.warn('⚠️ Widget has no template content -
|
|
429
|
+
console.warn('⚠️ Widget has no template content - generating functional template automatically');
|
|
430
|
+
// Generate a functional template instead of deploying an empty widget
|
|
431
|
+
const generatedWidget = widget_template_generator_js_1.widgetTemplateGenerator.generateWidget({
|
|
432
|
+
title: widget.title,
|
|
433
|
+
instruction: widget.description || widget.name || 'auto-generated widget',
|
|
434
|
+
type: 'info', // Default to info widget for auto-generated templates
|
|
435
|
+
theme: 'default',
|
|
436
|
+
responsive: true
|
|
437
|
+
});
|
|
438
|
+
// Apply generated components to the widget
|
|
439
|
+
widget.template = generatedWidget.template;
|
|
440
|
+
if (!widget.css || widget.css.trim() === '') {
|
|
441
|
+
widget.css = generatedWidget.css;
|
|
442
|
+
}
|
|
443
|
+
if (!widget.client_script || widget.client_script.trim() === '') {
|
|
444
|
+
widget.client_script = generatedWidget.clientScript;
|
|
445
|
+
}
|
|
446
|
+
if (!widget.server_script || widget.server_script.trim() === '') {
|
|
447
|
+
widget.server_script = generatedWidget.serverScript;
|
|
448
|
+
}
|
|
449
|
+
if (!widget.option_schema || widget.option_schema.trim() === '' || widget.option_schema === '[]') {
|
|
450
|
+
widget.option_schema = generatedWidget.optionSchema;
|
|
451
|
+
}
|
|
452
|
+
this.logger.info('✅ Generated functional widget template automatically');
|
|
426
453
|
}
|
|
427
454
|
// Ensure we have credentials before making the API call
|
|
428
455
|
await this.ensureAuthenticated();
|
|
@@ -440,8 +467,8 @@ class ServiceNowClient {
|
|
|
440
467
|
has_preview: widget.has_preview || false,
|
|
441
468
|
category: widget.category || 'custom'
|
|
442
469
|
});
|
|
443
|
-
|
|
444
|
-
|
|
470
|
+
this.logger.info('✅ Widget created successfully!');
|
|
471
|
+
this.logger.info(`🆔 Widget ID: ${response.data.result.sys_id}`);
|
|
445
472
|
// Add post-deployment verification
|
|
446
473
|
await this.verifyDeployment(response.data.result.sys_id, 'widget');
|
|
447
474
|
return {
|
|
@@ -462,7 +489,7 @@ class ServiceNowClient {
|
|
|
462
489
|
*/
|
|
463
490
|
async updateWidget(sysId, widget) {
|
|
464
491
|
try {
|
|
465
|
-
|
|
492
|
+
this.logger.info(`🔄 Updating widget ${sysId}...`);
|
|
466
493
|
// Ensure we have credentials before making the API call
|
|
467
494
|
await this.ensureAuthenticated();
|
|
468
495
|
// Map fields for Service Portal widget API
|
|
@@ -472,7 +499,7 @@ class ServiceNowClient {
|
|
|
472
499
|
delete mappedWidget.server_script;
|
|
473
500
|
}
|
|
474
501
|
const response = await this.client.patch(`${this.getBaseUrl()}/api/now/table/sp_widget/${sysId}`, mappedWidget);
|
|
475
|
-
|
|
502
|
+
this.logger.info('✅ Widget updated successfully!');
|
|
476
503
|
return {
|
|
477
504
|
success: true,
|
|
478
505
|
data: response.data.result
|
|
@@ -517,8 +544,8 @@ class ServiceNowClient {
|
|
|
517
544
|
*/
|
|
518
545
|
async createWorkflow(workflow) {
|
|
519
546
|
try {
|
|
520
|
-
|
|
521
|
-
|
|
547
|
+
this.logger.info('🔄 Creating ServiceNow workflow...');
|
|
548
|
+
this.logger.info(`📋 Workflow Name: ${workflow.name}`);
|
|
522
549
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/wf_workflow`, {
|
|
523
550
|
name: workflow.name,
|
|
524
551
|
description: workflow.description,
|
|
@@ -527,8 +554,8 @@ class ServiceNowClient {
|
|
|
527
554
|
table: workflow.table || '',
|
|
528
555
|
condition: workflow.condition || ''
|
|
529
556
|
});
|
|
530
|
-
|
|
531
|
-
|
|
557
|
+
this.logger.info('✅ Workflow created successfully!');
|
|
558
|
+
this.logger.info(`🆔 Workflow ID: ${response.data.result.sys_id}`);
|
|
532
559
|
return {
|
|
533
560
|
success: true,
|
|
534
561
|
data: response.data.result
|
|
@@ -547,8 +574,8 @@ class ServiceNowClient {
|
|
|
547
574
|
*/
|
|
548
575
|
async createApplication(application) {
|
|
549
576
|
try {
|
|
550
|
-
|
|
551
|
-
|
|
577
|
+
this.logger.info('🏗️ Creating ServiceNow application...');
|
|
578
|
+
this.logger.info(`📋 Application Name: ${application.name}`);
|
|
552
579
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_app`, {
|
|
553
580
|
name: application.name,
|
|
554
581
|
scope: application.scope,
|
|
@@ -561,8 +588,8 @@ class ServiceNowClient {
|
|
|
561
588
|
logo: application.logo || '',
|
|
562
589
|
active: application.active
|
|
563
590
|
});
|
|
564
|
-
|
|
565
|
-
|
|
591
|
+
this.logger.info('✅ Application created successfully!');
|
|
592
|
+
this.logger.info(`🆔 Application ID: ${response.data.result.sys_id}`);
|
|
566
593
|
return {
|
|
567
594
|
success: true,
|
|
568
595
|
data: response.data.result
|
|
@@ -581,12 +608,12 @@ class ServiceNowClient {
|
|
|
581
608
|
*/
|
|
582
609
|
async executeScript(script) {
|
|
583
610
|
try {
|
|
584
|
-
|
|
611
|
+
this.logger.info('⚡ Executing ServiceNow script...');
|
|
585
612
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_script_execution`, {
|
|
586
613
|
script: script,
|
|
587
614
|
type: 'server'
|
|
588
615
|
});
|
|
589
|
-
|
|
616
|
+
this.logger.info('✅ Script executed successfully!');
|
|
590
617
|
return {
|
|
591
618
|
success: true,
|
|
592
619
|
data: response.data.result
|
|
@@ -675,7 +702,7 @@ class ServiceNowClient {
|
|
|
675
702
|
}
|
|
676
703
|
}
|
|
677
704
|
catch (error) {
|
|
678
|
-
|
|
705
|
+
this.logger.warn('Could not fetch flow defaults, using minimal defaults');
|
|
679
706
|
}
|
|
680
707
|
// Return minimal defaults if we can't get from ServiceNow
|
|
681
708
|
return {
|
|
@@ -831,14 +858,14 @@ class ServiceNowClient {
|
|
|
831
858
|
*/
|
|
832
859
|
async searchFlowActions(searchTerm) {
|
|
833
860
|
try {
|
|
834
|
-
|
|
861
|
+
this.logger.info(`🔍 Searching for flow actions: ${searchTerm}`);
|
|
835
862
|
// Search in sys_hub_action_type_base for available action types
|
|
836
863
|
const results = await this.searchRecords('sys_hub_action_type_base', `nameLIKE${searchTerm}^ORlabelLIKE${searchTerm}^ORdescriptionLIKE${searchTerm}`, 20);
|
|
837
864
|
// Also search in sys_hub_action_instance for existing actions
|
|
838
865
|
const instanceResults = await this.searchRecords('sys_hub_action_instance', `action_nameLIKE${searchTerm}^ORdescriptionLIKE${searchTerm}`, 10);
|
|
839
866
|
const actionTypes = results.success ? results.data.result : [];
|
|
840
867
|
const actionInstances = instanceResults.success ? instanceResults.data.result : [];
|
|
841
|
-
|
|
868
|
+
this.logger.info(`✅ Found ${actionTypes.length} action types and ${actionInstances.length} action instances`);
|
|
842
869
|
return {
|
|
843
870
|
actionTypes,
|
|
844
871
|
actionInstances
|
|
@@ -960,7 +987,7 @@ snow_create_flow({
|
|
|
960
987
|
`);
|
|
961
988
|
}
|
|
962
989
|
else {
|
|
963
|
-
|
|
990
|
+
this.logger.info(`✅ ${expectedType} has ${activities.length} activities`);
|
|
964
991
|
}
|
|
965
992
|
}
|
|
966
993
|
else if (expectedType === 'widget') {
|
|
@@ -969,7 +996,7 @@ snow_create_flow({
|
|
|
969
996
|
console.warn(`⚠️ Widget deployed but appears to have no content: ${artifact.name}`);
|
|
970
997
|
}
|
|
971
998
|
}
|
|
972
|
-
|
|
999
|
+
this.logger.info(`✅ Deployment verified: ${artifact.name} (${sysId})`);
|
|
973
1000
|
}
|
|
974
1001
|
catch (error) {
|
|
975
1002
|
console.error(`❌ Deployment verification failed for ${sysId}:`, error);
|
|
@@ -1008,8 +1035,8 @@ snow_create_flow({
|
|
|
1008
1035
|
*/
|
|
1009
1036
|
async createFlowWithStructureBuilder(flowDefinition) {
|
|
1010
1037
|
try {
|
|
1011
|
-
|
|
1012
|
-
|
|
1038
|
+
this.logger.info('🏗️ Creating flow with structure builder...');
|
|
1039
|
+
this.logger.info(`📋 Flow: ${flowDefinition.name}`);
|
|
1013
1040
|
await this.ensureAuthenticated();
|
|
1014
1041
|
// Generate all flow components with proper structure
|
|
1015
1042
|
const components = (0, flow_structure_builder_1.generateFlowComponents)(flowDefinition);
|
|
@@ -1023,32 +1050,32 @@ snow_create_flow({
|
|
|
1023
1050
|
validation.warnings.forEach(warning => console.warn(` • ${warning}`));
|
|
1024
1051
|
}
|
|
1025
1052
|
// Deploy all components in correct order
|
|
1026
|
-
|
|
1053
|
+
this.logger.info('🚀 Deploying flow components...');
|
|
1027
1054
|
// 1. Create main flow record
|
|
1028
1055
|
const flowResponse = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow`, components.flowRecord);
|
|
1029
1056
|
if (!flowResponse.data?.result) {
|
|
1030
1057
|
throw new Error('Failed to create flow record');
|
|
1031
1058
|
}
|
|
1032
1059
|
const flowSysId = flowResponse.data.result.sys_id;
|
|
1033
|
-
|
|
1060
|
+
this.logger.info(`✅ Flow record created: ${flowSysId}`);
|
|
1034
1061
|
// 2. Create trigger instance
|
|
1035
1062
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_trigger_instance`, components.triggerInstance);
|
|
1036
|
-
|
|
1063
|
+
this.logger.info(`✅ Trigger created: ${components.triggerInstance.sys_id}`);
|
|
1037
1064
|
// 3. Create action instances
|
|
1038
1065
|
for (const action of components.actionInstances) {
|
|
1039
1066
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_instance`, action);
|
|
1040
1067
|
}
|
|
1041
|
-
|
|
1068
|
+
this.logger.info(`✅ Created ${components.actionInstances.length} action instances`);
|
|
1042
1069
|
// 4. Create logic chain (connections)
|
|
1043
1070
|
for (const logic of components.logicChain) {
|
|
1044
1071
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_logic`, logic);
|
|
1045
1072
|
}
|
|
1046
|
-
|
|
1073
|
+
this.logger.info(`✅ Created logic chain with ${components.logicChain.length} connections`);
|
|
1047
1074
|
// 5. Create variables
|
|
1048
1075
|
for (const variable of components.variables) {
|
|
1049
1076
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variable);
|
|
1050
1077
|
}
|
|
1051
|
-
|
|
1078
|
+
this.logger.info(`✅ Created ${components.variables.length} flow variables`);
|
|
1052
1079
|
// Verify deployment
|
|
1053
1080
|
await this.verifyDeployment(flowSysId, 'flow');
|
|
1054
1081
|
const credentials = await this.oauth.loadCredentials();
|
|
@@ -1085,10 +1112,10 @@ snow_create_flow({
|
|
|
1085
1112
|
*/
|
|
1086
1113
|
async createFlow(flow) {
|
|
1087
1114
|
try {
|
|
1088
|
-
|
|
1089
|
-
|
|
1115
|
+
this.logger.info('🔄 Creating Flow Designer flow...');
|
|
1116
|
+
this.logger.info(`📋 Flow: ${flow.name}`);
|
|
1090
1117
|
// 🔧 CRITICAL DEBUG: Check if makeRequest exists on this instance
|
|
1091
|
-
|
|
1118
|
+
this.logger.debug('🔧 CRITICAL DEBUG - Client methods check:', {
|
|
1092
1119
|
hasCreateFlow: typeof this.createFlow === 'function',
|
|
1093
1120
|
hasMakeRequest: typeof this.makeRequest === 'function',
|
|
1094
1121
|
clientPrototype: Object.getOwnPropertyNames(Object.getPrototypeOf(this)),
|
|
@@ -1181,37 +1208,37 @@ snow_create_flow({
|
|
|
1181
1208
|
throw new Error('No response data from flow creation');
|
|
1182
1209
|
}
|
|
1183
1210
|
const flowId = response.data.result.sys_id;
|
|
1184
|
-
|
|
1185
|
-
|
|
1211
|
+
this.logger.info('✅ Flow created successfully with complete snapshot!');
|
|
1212
|
+
this.logger.info(`🆔 Flow sys_id: ${flowId}`);
|
|
1186
1213
|
// 🔧 CRITICAL FIX: Create action instances after flow creation
|
|
1187
1214
|
// While the flow definition contains the structure, ServiceNow also needs
|
|
1188
1215
|
// actual sys_hub_action_instance records for proper execution
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1216
|
+
this.logger.info('📋 Flow components included in definition:');
|
|
1217
|
+
this.logger.info(`- Trigger: ${flowDefinition.trigger.type}`);
|
|
1218
|
+
this.logger.info(`- Activities: ${flowDefinition.activities.length}`);
|
|
1219
|
+
this.logger.info(`- Inputs: ${flowDefinition.inputs.length}`);
|
|
1220
|
+
this.logger.info(`- Outputs: ${flowDefinition.outputs.length}`);
|
|
1194
1221
|
// Create action instances for each activity
|
|
1195
1222
|
if (activitiesToProcess.length > 0) {
|
|
1196
|
-
|
|
1223
|
+
this.logger.info('🔧 Creating action instances for activities...');
|
|
1197
1224
|
for (let i = 0; i < activitiesToProcess.length; i++) {
|
|
1198
1225
|
const activity = activitiesToProcess[i];
|
|
1199
1226
|
try {
|
|
1200
1227
|
await this.createFlowActionInstance(flowId, activity, (i + 1) * 100);
|
|
1201
|
-
|
|
1228
|
+
this.logger.info(`✅ Action instance created: ${activity.name}`);
|
|
1202
1229
|
}
|
|
1203
1230
|
catch (activityError) {
|
|
1204
1231
|
console.warn(`⚠️ Failed to create action instance ${activity.name}:`, activityError);
|
|
1205
1232
|
// Continue with other activities even if one fails
|
|
1206
1233
|
}
|
|
1207
1234
|
}
|
|
1208
|
-
|
|
1235
|
+
this.logger.info(`✅ Created ${activitiesToProcess.length} action instances`);
|
|
1209
1236
|
}
|
|
1210
1237
|
// 🔧 NEW: Only need to activate the flow since it already has complete definition
|
|
1211
1238
|
try {
|
|
1212
|
-
|
|
1239
|
+
this.logger.info('⚡ Activating flow...');
|
|
1213
1240
|
await this.activateFlow(flowId);
|
|
1214
|
-
|
|
1241
|
+
this.logger.info('✅ Flow activated successfully!');
|
|
1215
1242
|
}
|
|
1216
1243
|
catch (activationError) {
|
|
1217
1244
|
console.warn('⚠️ Flow activation failed:', activationError);
|
|
@@ -1219,7 +1246,7 @@ snow_create_flow({
|
|
|
1219
1246
|
}
|
|
1220
1247
|
// 🔧 CRITICAL FIX: Create actual ServiceNow records after flow creation
|
|
1221
1248
|
// The JSON definition alone is not enough - we need component records
|
|
1222
|
-
|
|
1249
|
+
this.logger.info('🔧 Creating actual ServiceNow flow component records...');
|
|
1223
1250
|
try {
|
|
1224
1251
|
// 1. Create trigger instance if trigger is specified
|
|
1225
1252
|
if (flow.trigger_type && flow.trigger_type !== 'manual') {
|
|
@@ -1229,7 +1256,7 @@ snow_create_flow({
|
|
|
1229
1256
|
condition: flow.trigger_condition || flow.condition || ''
|
|
1230
1257
|
};
|
|
1231
1258
|
const triggerResult = await this.createFlowTrigger(flowId, triggerData);
|
|
1232
|
-
|
|
1259
|
+
this.logger.info(`✅ Trigger created: ${triggerResult.sys_id}`);
|
|
1233
1260
|
}
|
|
1234
1261
|
// 2. Create action instances for each activity
|
|
1235
1262
|
if (activitiesToProcess && activitiesToProcess.length > 0) {
|
|
@@ -1240,7 +1267,7 @@ snow_create_flow({
|
|
|
1240
1267
|
try {
|
|
1241
1268
|
const actionResult = await this.createFlowActionInstance(flowId, activity, order);
|
|
1242
1269
|
actionResults.push(actionResult);
|
|
1243
|
-
|
|
1270
|
+
this.logger.info(`✅ Action created: ${activity.name} (${actionResult.sys_id})`);
|
|
1244
1271
|
}
|
|
1245
1272
|
catch (actionError) {
|
|
1246
1273
|
console.warn(`⚠️ Failed to create action ${activity.name}:`, actionError);
|
|
@@ -1258,7 +1285,7 @@ snow_create_flow({
|
|
|
1258
1285
|
};
|
|
1259
1286
|
try {
|
|
1260
1287
|
const logicResult = await this.createFlowLogic(flowId, logicData);
|
|
1261
|
-
|
|
1288
|
+
this.logger.info(`✅ Flow logic created: ${logicResult.sys_id}`);
|
|
1262
1289
|
}
|
|
1263
1290
|
catch (logicError) {
|
|
1264
1291
|
console.warn(`⚠️ Failed to create flow logic for ${action.action_name}:`, logicError);
|
|
@@ -1266,7 +1293,7 @@ snow_create_flow({
|
|
|
1266
1293
|
}
|
|
1267
1294
|
}
|
|
1268
1295
|
}
|
|
1269
|
-
|
|
1296
|
+
this.logger.info('✅ All flow component records created successfully!');
|
|
1270
1297
|
}
|
|
1271
1298
|
catch (componentError) {
|
|
1272
1299
|
console.warn('⚠️ Some flow components may not have been created properly:', componentError);
|
|
@@ -1359,8 +1386,8 @@ snow_create_flow({
|
|
|
1359
1386
|
*/
|
|
1360
1387
|
async createSubflow(subflow) {
|
|
1361
1388
|
try {
|
|
1362
|
-
|
|
1363
|
-
|
|
1389
|
+
this.logger.info('🔄 Creating Subflow...');
|
|
1390
|
+
this.logger.info(`📋 Subflow: ${subflow.name}`);
|
|
1364
1391
|
// Add pre-deployment validation
|
|
1365
1392
|
this.validateFlowBeforeDeployment(subflow);
|
|
1366
1393
|
// Ensure Update Set
|
|
@@ -1426,8 +1453,8 @@ snow_create_flow({
|
|
|
1426
1453
|
*/
|
|
1427
1454
|
async createFlowAction(action) {
|
|
1428
1455
|
try {
|
|
1429
|
-
|
|
1430
|
-
|
|
1456
|
+
this.logger.info('⚡ Creating Flow Action...');
|
|
1457
|
+
this.logger.info(`📋 Action: ${action.name}`);
|
|
1431
1458
|
// Add pre-deployment validation (adapted for actions)
|
|
1432
1459
|
if (!action.name || action.name.trim() === '') {
|
|
1433
1460
|
throw new Error('Flow Action name is required');
|
|
@@ -1454,7 +1481,7 @@ snow_create_flow({
|
|
|
1454
1481
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_type_definition`, actionData);
|
|
1455
1482
|
// Add basic verification for action creation
|
|
1456
1483
|
if (response.data.result?.sys_id) {
|
|
1457
|
-
|
|
1484
|
+
this.logger.info(`✅ Flow Action created: ${action.name} (${response.data.result.sys_id})`);
|
|
1458
1485
|
}
|
|
1459
1486
|
return {
|
|
1460
1487
|
success: true,
|
|
@@ -1474,7 +1501,7 @@ snow_create_flow({
|
|
|
1474
1501
|
*/
|
|
1475
1502
|
async createFlowActionPrivate(flowId, action, order) {
|
|
1476
1503
|
try {
|
|
1477
|
-
|
|
1504
|
+
this.logger.info(`Creating flow action: ${action.type} - ${action.name}`);
|
|
1478
1505
|
// If we have a discovered action type, use it
|
|
1479
1506
|
let actionTypeId = action.action_type_id;
|
|
1480
1507
|
// If no specific action type provided, search for one
|
|
@@ -1482,7 +1509,7 @@ snow_create_flow({
|
|
|
1482
1509
|
const searchResults = await this.searchFlowActions(action.type);
|
|
1483
1510
|
if (searchResults.actionTypes && searchResults.actionTypes.length > 0) {
|
|
1484
1511
|
actionTypeId = searchResults.actionTypes[0].sys_id;
|
|
1485
|
-
|
|
1512
|
+
this.logger.info(`📋 Using discovered action type: ${searchResults.actionTypes[0].name}`);
|
|
1486
1513
|
}
|
|
1487
1514
|
else {
|
|
1488
1515
|
// Fallback to common action types
|
|
@@ -1495,7 +1522,7 @@ snow_create_flow({
|
|
|
1495
1522
|
'approval': 'com.glideapp.servicenow_common.approval'
|
|
1496
1523
|
};
|
|
1497
1524
|
actionTypeId = fallbackMap[action.type] || 'com.glideapp.servicenow_common.script';
|
|
1498
|
-
|
|
1525
|
+
this.logger.info(`📋 Using fallback action type: ${actionTypeId}`);
|
|
1499
1526
|
}
|
|
1500
1527
|
}
|
|
1501
1528
|
// Get action details to understand inputs/outputs
|
|
@@ -1513,7 +1540,7 @@ snow_create_flow({
|
|
|
1513
1540
|
configuration: this.buildActionConfiguration(action)
|
|
1514
1541
|
};
|
|
1515
1542
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_instance`, actionData);
|
|
1516
|
-
|
|
1543
|
+
this.logger.info(`✅ Flow action created: ${action.name}`);
|
|
1517
1544
|
return response.data.result;
|
|
1518
1545
|
}
|
|
1519
1546
|
catch (error) {
|
|
@@ -1677,13 +1704,13 @@ try {
|
|
|
1677
1704
|
description: `Auto-generated trigger for Flow Designer flow: ${flowId}`
|
|
1678
1705
|
};
|
|
1679
1706
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_trigger`, sysTriggerData);
|
|
1680
|
-
|
|
1707
|
+
this.logger.info('✅ sys_trigger record created for proper flow execution');
|
|
1681
1708
|
}
|
|
1682
1709
|
catch (sysTriggerError) {
|
|
1683
1710
|
console.warn('Could not create sys_trigger record, flow may not trigger properly:', sysTriggerError);
|
|
1684
1711
|
}
|
|
1685
1712
|
}
|
|
1686
|
-
|
|
1713
|
+
this.logger.info('✅ Trigger created successfully');
|
|
1687
1714
|
return response.data.result;
|
|
1688
1715
|
}
|
|
1689
1716
|
catch (error) {
|
|
@@ -1696,7 +1723,7 @@ try {
|
|
|
1696
1723
|
*/
|
|
1697
1724
|
async createFlowVariables(flowId, flow) {
|
|
1698
1725
|
try {
|
|
1699
|
-
|
|
1726
|
+
this.logger.info('📋 Creating flow variables...');
|
|
1700
1727
|
// Process inputs
|
|
1701
1728
|
const inputs = flow.inputs || [];
|
|
1702
1729
|
if (inputs.length > 0) {
|
|
@@ -1714,7 +1741,7 @@ try {
|
|
|
1714
1741
|
};
|
|
1715
1742
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variableData);
|
|
1716
1743
|
}
|
|
1717
|
-
|
|
1744
|
+
this.logger.info(`✅ Created ${inputs.length} input variables`);
|
|
1718
1745
|
}
|
|
1719
1746
|
// Process outputs
|
|
1720
1747
|
const outputs = flow.outputs || [];
|
|
@@ -1733,7 +1760,7 @@ try {
|
|
|
1733
1760
|
};
|
|
1734
1761
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variableData);
|
|
1735
1762
|
}
|
|
1736
|
-
|
|
1763
|
+
this.logger.info(`✅ Created ${outputs.length} output variables`);
|
|
1737
1764
|
}
|
|
1738
1765
|
// Extract variables from flow_definition if available
|
|
1739
1766
|
if (flow.flow_definition) {
|
|
@@ -1755,7 +1782,7 @@ try {
|
|
|
1755
1782
|
};
|
|
1756
1783
|
await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variableData);
|
|
1757
1784
|
}
|
|
1758
|
-
|
|
1785
|
+
this.logger.info(`✅ Created ${flowDef.variables.length} flow definition variables`);
|
|
1759
1786
|
}
|
|
1760
1787
|
}
|
|
1761
1788
|
catch (parseError) {
|
|
@@ -1773,7 +1800,7 @@ try {
|
|
|
1773
1800
|
*/
|
|
1774
1801
|
async createFlowActionInstance(flowId, action, order) {
|
|
1775
1802
|
try {
|
|
1776
|
-
|
|
1803
|
+
this.logger.info(`Creating action instance: ${action.name}`);
|
|
1777
1804
|
// Map action types to search terms
|
|
1778
1805
|
const actionSearchMap = {
|
|
1779
1806
|
'notification': 'Send Email',
|
|
@@ -1848,7 +1875,7 @@ try {
|
|
|
1848
1875
|
inputs: JSON.stringify(inputs)
|
|
1849
1876
|
};
|
|
1850
1877
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_instance`, actionData);
|
|
1851
|
-
|
|
1878
|
+
this.logger.info(`✅ Action created: ${action.name}`);
|
|
1852
1879
|
return response.data.result;
|
|
1853
1880
|
}
|
|
1854
1881
|
catch (error) {
|
|
@@ -1887,7 +1914,7 @@ try {
|
|
|
1887
1914
|
*/
|
|
1888
1915
|
async createScriptInclude(scriptInclude) {
|
|
1889
1916
|
try {
|
|
1890
|
-
|
|
1917
|
+
this.logger.info('📝 Creating Script Include...');
|
|
1891
1918
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_script_include`, {
|
|
1892
1919
|
name: scriptInclude.name,
|
|
1893
1920
|
api_name: scriptInclude.api_name,
|
|
@@ -1896,7 +1923,7 @@ try {
|
|
|
1896
1923
|
active: scriptInclude.active,
|
|
1897
1924
|
access: scriptInclude.access || 'public'
|
|
1898
1925
|
});
|
|
1899
|
-
|
|
1926
|
+
this.logger.info('✅ Script Include created successfully!');
|
|
1900
1927
|
return {
|
|
1901
1928
|
success: true,
|
|
1902
1929
|
data: response.data.result
|
|
@@ -1915,7 +1942,7 @@ try {
|
|
|
1915
1942
|
*/
|
|
1916
1943
|
async createBusinessRule(businessRule) {
|
|
1917
1944
|
try {
|
|
1918
|
-
|
|
1945
|
+
this.logger.info('📋 Creating Business Rule...');
|
|
1919
1946
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_script`, {
|
|
1920
1947
|
name: businessRule.name,
|
|
1921
1948
|
collection: businessRule.table,
|
|
@@ -1926,7 +1953,7 @@ try {
|
|
|
1926
1953
|
active: businessRule.active,
|
|
1927
1954
|
order: businessRule.order || 100
|
|
1928
1955
|
});
|
|
1929
|
-
|
|
1956
|
+
this.logger.info('✅ Business Rule created successfully!');
|
|
1930
1957
|
return {
|
|
1931
1958
|
success: true,
|
|
1932
1959
|
data: response.data.result
|
|
@@ -1945,7 +1972,7 @@ try {
|
|
|
1945
1972
|
*/
|
|
1946
1973
|
async createTable(table) {
|
|
1947
1974
|
try {
|
|
1948
|
-
|
|
1975
|
+
this.logger.info('🗄️ Creating Table...');
|
|
1949
1976
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_db_object`, {
|
|
1950
1977
|
name: table.name,
|
|
1951
1978
|
label: table.label,
|
|
@@ -1954,7 +1981,7 @@ try {
|
|
|
1954
1981
|
access: table.access || 'public',
|
|
1955
1982
|
create_access_controls: table.create_access_controls !== false
|
|
1956
1983
|
});
|
|
1957
|
-
|
|
1984
|
+
this.logger.info('✅ Table created successfully!');
|
|
1958
1985
|
return {
|
|
1959
1986
|
success: true,
|
|
1960
1987
|
data: response.data.result
|
|
@@ -1973,7 +2000,7 @@ try {
|
|
|
1973
2000
|
*/
|
|
1974
2001
|
async createTableField(field) {
|
|
1975
2002
|
try {
|
|
1976
|
-
|
|
2003
|
+
this.logger.info('📊 Creating Table Field...');
|
|
1977
2004
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_dictionary`, {
|
|
1978
2005
|
name: `${field.table}.${field.element}`,
|
|
1979
2006
|
element: field.element,
|
|
@@ -1982,7 +2009,7 @@ try {
|
|
|
1982
2009
|
max_length: field.max_length || 255,
|
|
1983
2010
|
active: true
|
|
1984
2011
|
});
|
|
1985
|
-
|
|
2012
|
+
this.logger.info('✅ Table Field created successfully!');
|
|
1986
2013
|
return {
|
|
1987
2014
|
success: true,
|
|
1988
2015
|
data: response.data.result
|
|
@@ -2001,7 +2028,7 @@ try {
|
|
|
2001
2028
|
*/
|
|
2002
2029
|
async createUpdateSet(updateSet) {
|
|
2003
2030
|
try {
|
|
2004
|
-
|
|
2031
|
+
this.logger.info('📦 Creating Update Set...');
|
|
2005
2032
|
// Ensure we have credentials before making the API call
|
|
2006
2033
|
await this.ensureAuthenticated();
|
|
2007
2034
|
const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_update_set`, {
|
|
@@ -2011,7 +2038,7 @@ try {
|
|
|
2011
2038
|
state: updateSet.state || 'in_progress',
|
|
2012
2039
|
application: updateSet.application || 'global'
|
|
2013
2040
|
});
|
|
2014
|
-
|
|
2041
|
+
this.logger.info('✅ Update Set created successfully!');
|
|
2015
2042
|
return {
|
|
2016
2043
|
success: true,
|
|
2017
2044
|
data: response.data.result
|
|
@@ -2030,7 +2057,7 @@ try {
|
|
|
2030
2057
|
*/
|
|
2031
2058
|
async setCurrentUpdateSet(updateSetId) {
|
|
2032
2059
|
try {
|
|
2033
|
-
|
|
2060
|
+
this.logger.info('🔄 Setting current Update Set...');
|
|
2034
2061
|
// Ensure we have credentials before making the API call
|
|
2035
2062
|
await this.ensureAuthenticated();
|
|
2036
2063
|
// Use the sys_user_preference table to set the current update set
|
|
@@ -2056,7 +2083,7 @@ try {
|
|
|
2056
2083
|
user: 'javascript:gs.getUserID()'
|
|
2057
2084
|
});
|
|
2058
2085
|
}
|
|
2059
|
-
|
|
2086
|
+
this.logger.info('✅ Current Update Set changed successfully!');
|
|
2060
2087
|
return {
|
|
2061
2088
|
success: true,
|
|
2062
2089
|
data: response.data.result
|
|
@@ -2075,7 +2102,7 @@ try {
|
|
|
2075
2102
|
*/
|
|
2076
2103
|
async getCurrentUpdateSet() {
|
|
2077
2104
|
try {
|
|
2078
|
-
|
|
2105
|
+
this.logger.info('📋 Getting current Update Set...');
|
|
2079
2106
|
// Ensure we have credentials before making the API call
|
|
2080
2107
|
await this.ensureAuthenticated();
|
|
2081
2108
|
// Try to get the current update set using sys_user_preference table
|
|
@@ -2098,7 +2125,7 @@ try {
|
|
|
2098
2125
|
}
|
|
2099
2126
|
}
|
|
2100
2127
|
catch (prefError) {
|
|
2101
|
-
|
|
2128
|
+
this.logger.info('⚠️ User preference lookup failed, trying fallback...');
|
|
2102
2129
|
}
|
|
2103
2130
|
// Fallback: Get the most recent in-progress update set for the current user
|
|
2104
2131
|
const response = await this.client.get(`${this.getBaseUrl()}/api/now/table/sys_update_set`, {
|
|
@@ -2132,7 +2159,7 @@ try {
|
|
|
2132
2159
|
*/
|
|
2133
2160
|
async getUpdateSet(updateSetId) {
|
|
2134
2161
|
try {
|
|
2135
|
-
|
|
2162
|
+
this.logger.info(`📋 Getting Update Set ${updateSetId}...`);
|
|
2136
2163
|
// Ensure we have credentials before making the API call
|
|
2137
2164
|
await this.ensureAuthenticated();
|
|
2138
2165
|
const response = await this.client.get(`${this.getBaseUrl()}/api/now/table/sys_update_set/${updateSetId}`);
|
|
@@ -2154,7 +2181,7 @@ try {
|
|
|
2154
2181
|
*/
|
|
2155
2182
|
async listUpdateSets(options) {
|
|
2156
2183
|
try {
|
|
2157
|
-
|
|
2184
|
+
this.logger.info('📋 Listing Update Sets...');
|
|
2158
2185
|
// Ensure we have credentials before making the API call
|
|
2159
2186
|
await this.ensureAuthenticated();
|
|
2160
2187
|
let query = 'sys_created_by=javascript:gs.getUserName()';
|
|
@@ -2186,14 +2213,14 @@ try {
|
|
|
2186
2213
|
*/
|
|
2187
2214
|
async completeUpdateSet(updateSetId, notes) {
|
|
2188
2215
|
try {
|
|
2189
|
-
|
|
2216
|
+
this.logger.info('✅ Completing Update Set...');
|
|
2190
2217
|
// Ensure we have credentials before making the API call
|
|
2191
2218
|
await this.ensureAuthenticated();
|
|
2192
2219
|
const response = await this.client.patch(`${this.getBaseUrl()}/api/now/table/sys_update_set/${updateSetId}`, {
|
|
2193
2220
|
state: 'complete',
|
|
2194
2221
|
description: notes ? `${notes}\n\nCompleted: ${new Date().toISOString()}` : undefined
|
|
2195
2222
|
});
|
|
2196
|
-
|
|
2223
|
+
this.logger.info('✅ Update Set completed successfully!');
|
|
2197
2224
|
return {
|
|
2198
2225
|
success: true,
|
|
2199
2226
|
data: response.data.result
|
|
@@ -2212,7 +2239,7 @@ try {
|
|
|
2212
2239
|
*/
|
|
2213
2240
|
async activateUpdateSet(updateSetId) {
|
|
2214
2241
|
try {
|
|
2215
|
-
|
|
2242
|
+
this.logger.info('🔄 Activating Update Set...');
|
|
2216
2243
|
// Set the update set as current
|
|
2217
2244
|
const result = await this.setCurrentUpdateSet(updateSetId);
|
|
2218
2245
|
if (result.success) {
|
|
@@ -2220,7 +2247,7 @@ try {
|
|
|
2220
2247
|
const updateResponse = await this.client.patch(`${this.getBaseUrl()}/api/now/table/sys_update_set/${updateSetId}`, {
|
|
2221
2248
|
state: 'in_progress'
|
|
2222
2249
|
});
|
|
2223
|
-
|
|
2250
|
+
this.logger.info('✅ Update Set activated successfully!');
|
|
2224
2251
|
return {
|
|
2225
2252
|
success: true,
|
|
2226
2253
|
data: updateResponse.data.result
|
|
@@ -2241,7 +2268,7 @@ try {
|
|
|
2241
2268
|
*/
|
|
2242
2269
|
async previewUpdateSet(updateSetId) {
|
|
2243
2270
|
try {
|
|
2244
|
-
|
|
2271
|
+
this.logger.info('🔍 Previewing Update Set changes...');
|
|
2245
2272
|
// Get Update Set details
|
|
2246
2273
|
const updateSetResponse = await this.getUpdateSet(updateSetId);
|
|
2247
2274
|
if (!updateSetResponse.success) {
|
|
@@ -2281,12 +2308,12 @@ try {
|
|
|
2281
2308
|
// Check if we have a current Update Set
|
|
2282
2309
|
const currentUpdateSet = await this.getCurrentUpdateSet();
|
|
2283
2310
|
if (currentUpdateSet.success && currentUpdateSet.data) {
|
|
2284
|
-
|
|
2311
|
+
this.logger.info(`📦 Using existing Update Set: ${currentUpdateSet.data.name}`);
|
|
2285
2312
|
return currentUpdateSet;
|
|
2286
2313
|
}
|
|
2287
2314
|
// Create a new Update Set if none exists
|
|
2288
2315
|
const updateSetName = `Snow-Flow Changes ${new Date().toISOString().split('T')[0]}`;
|
|
2289
|
-
|
|
2316
|
+
this.logger.info(`📦 Creating new Update Set: ${updateSetName}`);
|
|
2290
2317
|
const newUpdateSet = await this.createUpdateSet({
|
|
2291
2318
|
name: updateSetName,
|
|
2292
2319
|
description: 'Automated changes from Snow-Flow MCP',
|
|
@@ -2308,7 +2335,7 @@ try {
|
|
|
2308
2335
|
}
|
|
2309
2336
|
async exportUpdateSet(updateSetId) {
|
|
2310
2337
|
try {
|
|
2311
|
-
|
|
2338
|
+
this.logger.info('📤 Exporting Update Set...');
|
|
2312
2339
|
// Get Update Set details first
|
|
2313
2340
|
const updateSetResponse = await this.getUpdateSet(updateSetId);
|
|
2314
2341
|
if (!updateSetResponse.success) {
|
|
@@ -2345,7 +2372,7 @@ try {
|
|
|
2345
2372
|
*/
|
|
2346
2373
|
async debugFlow(flowId) {
|
|
2347
2374
|
try {
|
|
2348
|
-
|
|
2375
|
+
this.logger.info('🔍 Debugging flow structure...');
|
|
2349
2376
|
// Get the flow record
|
|
2350
2377
|
const flowResponse = await this.client.get(`${this.getBaseUrl()}/api/now/table/sys_hub_flow/${flowId}`);
|
|
2351
2378
|
if (!flowResponse.data.result) {
|
|
@@ -2501,17 +2528,17 @@ try {
|
|
|
2501
2528
|
* This method provides compatibility for code that expects makeRequest
|
|
2502
2529
|
*/
|
|
2503
2530
|
async makeRequest(config) {
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2531
|
+
this.logger.info('🔧 MAKEQUEST CALLED! Stack trace:', new Error().stack);
|
|
2532
|
+
this.logger.info('🔧 TEMP FIX: makeRequest called with config:', config);
|
|
2533
|
+
this.logger.info('🔧 This instance constructor:', this.constructor.name);
|
|
2534
|
+
this.logger.info('🔧 This instance methods:', Object.getOwnPropertyNames(Object.getPrototypeOf(this)));
|
|
2508
2535
|
try {
|
|
2509
2536
|
await this.ensureAuthenticated();
|
|
2510
2537
|
// Route the request to the appropriate HTTP method
|
|
2511
2538
|
const method = (config.method || 'GET').toLowerCase();
|
|
2512
2539
|
const url = config.url || config.endpoint;
|
|
2513
2540
|
const data = config.data || config.body;
|
|
2514
|
-
|
|
2541
|
+
this.logger.info(`🔧 Routing ${method.toUpperCase()} request to: ${url}`);
|
|
2515
2542
|
switch (method) {
|
|
2516
2543
|
case 'get':
|
|
2517
2544
|
return await this.get(url, config.params);
|