snow-flow 10.0.1-dev.475 → 10.0.1-dev.477
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/package.json
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snow-Flow Flow Designer Tool
|
|
3
|
+
*
|
|
4
|
+
* DISCLAIMER:
|
|
5
|
+
* This tool uses both official and undocumented ServiceNow APIs to interact
|
|
6
|
+
* with Flow Designer. The GraphQL-based operations (snFlowDesigner) use
|
|
7
|
+
* internal ServiceNow APIs that are not officially documented and may change
|
|
8
|
+
* without notice. Use at your own risk.
|
|
9
|
+
*
|
|
10
|
+
* This tool is not affiliated with, endorsed by, or sponsored by ServiceNow, Inc.
|
|
11
|
+
* ServiceNow is a registered trademark of ServiceNow, Inc.
|
|
12
|
+
*
|
|
13
|
+
* A valid ServiceNow subscription and credentials are required to use this tool.
|
|
14
|
+
*/
|
|
15
|
+
|
|
1
16
|
import { MCPToolDefinition, ServiceNowContext, ToolResult } from '../../shared/types.js';
|
|
2
17
|
import { getAuthenticatedClient } from '../../shared/auth.js';
|
|
3
18
|
import { createSuccessResult, createErrorResult, SnowFlowError, ErrorType } from '../../shared/error-handler.js';
|
|
@@ -1148,102 +1163,113 @@ async function getFlowTriggerInfo(
|
|
|
1148
1163
|
var tableLabel = '';
|
|
1149
1164
|
var debug: any = {};
|
|
1150
1165
|
|
|
1166
|
+
// PRIMARY: Read flow via ProcessFlow REST API (same endpoint as Flow Designer UI)
|
|
1167
|
+
// This API returns XML (not JSON). We parse trigger info from the XML string.
|
|
1151
1168
|
try {
|
|
1152
|
-
|
|
1153
|
-
var
|
|
1154
|
-
|
|
1155
|
-
sysparm_query: 'flow=' + flowId + '^ORDERBYDESCsys_created_on',
|
|
1156
|
-
sysparm_fields: 'sys_id,payload',
|
|
1157
|
-
sysparm_limit: 1
|
|
1158
|
-
}
|
|
1169
|
+
debug.processflow_api = 'attempting';
|
|
1170
|
+
var pfResp = await client.get('/api/now/processflow/flow/' + flowId, {
|
|
1171
|
+
headers: { 'Accept': 'application/xml, application/json' }
|
|
1159
1172
|
});
|
|
1160
|
-
var
|
|
1161
|
-
debug.
|
|
1162
|
-
debug.
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
//
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
debug.
|
|
1173
|
+
var pfRaw = pfResp.data;
|
|
1174
|
+
debug.processflow_api = 'success';
|
|
1175
|
+
debug.processflow_type = typeof pfRaw;
|
|
1176
|
+
|
|
1177
|
+
if (typeof pfRaw === 'string' && pfRaw.indexOf('<triggerInstances>') >= 0) {
|
|
1178
|
+
// Response is XML — parse trigger info with regex
|
|
1179
|
+
debug.processflow_format = 'xml';
|
|
1180
|
+
|
|
1181
|
+
// Extract the triggerInstances block
|
|
1182
|
+
var trigBlockMatch = pfRaw.match(/<triggerInstances>([\s\S]*?)<\/triggerInstances>/);
|
|
1183
|
+
if (trigBlockMatch) {
|
|
1184
|
+
var trigBlock = trigBlockMatch[1];
|
|
1185
|
+
|
|
1186
|
+
// Trigger name: <name>X</name> that appears near <triggerType> at end of block
|
|
1187
|
+
// Structure: ...<name>Created or Updated</name><comment/>...<triggerType>Record</triggerType>
|
|
1188
|
+
var trigNameMatch = trigBlock.match(/<name>([^<]+)<\/name>[\s\S]{0,300}<triggerType>/);
|
|
1189
|
+
if (trigNameMatch) {
|
|
1190
|
+
triggerName = trigNameMatch[1];
|
|
1191
|
+
debug.processflow_trigger_name = triggerName;
|
|
1179
1192
|
}
|
|
1193
|
+
|
|
1194
|
+
// Table: find <name>table</name> ... <value>X</value> inside trigger inputs
|
|
1195
|
+
var tableMatch = trigBlock.match(/<name>table<\/name>[\s\S]*?<value>([^<]+)<\/value>/);
|
|
1196
|
+
if (tableMatch) {
|
|
1197
|
+
table = tableMatch[1];
|
|
1198
|
+
debug.processflow_table = table;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
} else if (pfRaw && typeof pfRaw === 'object') {
|
|
1202
|
+
// Response is JSON — traverse object structure
|
|
1203
|
+
debug.processflow_format = 'json';
|
|
1204
|
+
var pfData = pfRaw.result || pfRaw;
|
|
1205
|
+
debug.processflow_keys = pfData && typeof pfData === 'object' ? Object.keys(pfData).slice(0, 20) : null;
|
|
1206
|
+
|
|
1207
|
+
var pfTriggers = pfData?.triggerInstances || pfData?.trigger_instances || pfData?.triggers || [];
|
|
1208
|
+
if (!Array.isArray(pfTriggers) && pfData?.model?.triggerInstances) {
|
|
1209
|
+
pfTriggers = pfData.model.triggerInstances;
|
|
1210
|
+
}
|
|
1211
|
+
if (!Array.isArray(pfTriggers) && pfData?.definition?.triggerInstances) {
|
|
1212
|
+
pfTriggers = pfData.definition.triggerInstances;
|
|
1180
1213
|
}
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
debug.trigger_input_names = trigger.inputs.map(function (inp: any) { return inp.name; });
|
|
1190
|
-
for (var ti = 0; ti < trigger.inputs.length; ti++) {
|
|
1191
|
-
if (trigger.inputs[ti].name === 'table') {
|
|
1192
|
-
table = trigger.inputs[ti].value?.value || trigger.inputs[ti].value || '';
|
|
1214
|
+
|
|
1215
|
+
if (Array.isArray(pfTriggers) && pfTriggers.length > 0) {
|
|
1216
|
+
var pfTrig = pfTriggers[0];
|
|
1217
|
+
triggerName = pfTrig.name || pfTrig.triggerName || '';
|
|
1218
|
+
if (pfTrig.inputs && Array.isArray(pfTrig.inputs)) {
|
|
1219
|
+
for (var pfi = 0; pfi < pfTrig.inputs.length; pfi++) {
|
|
1220
|
+
if (pfTrig.inputs[pfi].name === 'table') {
|
|
1221
|
+
table = pfTrig.inputs[pfi].value?.value || str(pfTrig.inputs[pfi].value) || '';
|
|
1193
1222
|
break;
|
|
1194
1223
|
}
|
|
1195
1224
|
}
|
|
1196
|
-
} else {
|
|
1197
|
-
debug.trigger_inputs = trigger.inputs ? typeof trigger.inputs : 'undefined';
|
|
1198
1225
|
}
|
|
1199
1226
|
}
|
|
1200
|
-
} else {
|
|
1201
|
-
debug.payload_raw = 'null_or_empty';
|
|
1202
1227
|
}
|
|
1203
|
-
} catch (
|
|
1204
|
-
debug.
|
|
1228
|
+
} catch (pfErr: any) {
|
|
1229
|
+
debug.processflow_api = 'error: ' + pfErr.message;
|
|
1205
1230
|
}
|
|
1206
1231
|
|
|
1207
|
-
// Fallback 1:
|
|
1208
|
-
// Sending just flowId with no changes returns the current state including trigger instances
|
|
1232
|
+
// Fallback 1: Read version payload (legacy approach)
|
|
1209
1233
|
if (!triggerName || !table) {
|
|
1210
|
-
debug.
|
|
1234
|
+
debug.version_fallback = 'attempting';
|
|
1211
1235
|
try {
|
|
1212
|
-
var
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1236
|
+
var resp = await client.get('/api/now/table/sys_hub_flow_version', {
|
|
1237
|
+
params: {
|
|
1238
|
+
sysparm_query: 'flow=' + flowId + '^ORDERBYDESCsys_created_on',
|
|
1239
|
+
sysparm_fields: 'sys_id,payload',
|
|
1240
|
+
sysparm_limit: 1
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
var payload = resp.data.result?.[0]?.payload;
|
|
1244
|
+
if (payload) {
|
|
1245
|
+
var parsed = typeof payload === 'string' ? JSON.parse(payload) : payload;
|
|
1246
|
+
debug.version_payload_keys = Object.keys(parsed);
|
|
1247
|
+
var trigInst = parsed.triggerInstances || parsed.trigger_instances || [];
|
|
1248
|
+
if (Array.isArray(trigInst) && trigInst.length > 0) {
|
|
1249
|
+
if (!triggerName) triggerName = trigInst[0].name || trigInst[0].triggerName || '';
|
|
1250
|
+
if (!table && trigInst[0].inputs) {
|
|
1251
|
+
for (var vi = 0; vi < trigInst[0].inputs.length; vi++) {
|
|
1252
|
+
if (trigInst[0].inputs[vi].name === 'table') {
|
|
1253
|
+
table = trigInst[0].inputs[vi].value?.value || '';
|
|
1254
|
+
break;
|
|
1255
|
+
}
|
|
1227
1256
|
}
|
|
1228
1257
|
}
|
|
1229
1258
|
}
|
|
1230
1259
|
}
|
|
1231
|
-
} catch (
|
|
1232
|
-
debug.fallback_noop_mutation = 'error: ' + noopErr.message;
|
|
1233
|
-
}
|
|
1260
|
+
} catch (_) {}
|
|
1234
1261
|
}
|
|
1235
1262
|
|
|
1236
1263
|
// Fallback 2: query sys_hub_flow for table + trigger definition for name
|
|
1237
1264
|
if (!triggerName || !table) {
|
|
1238
|
-
debug.
|
|
1265
|
+
debug.flow_record_fallback = 'attempting';
|
|
1239
1266
|
try {
|
|
1240
1267
|
var flowResp = await client.get('/api/now/table/sys_hub_flow', {
|
|
1241
1268
|
params: { sysparm_query: 'sys_id=' + flowId, sysparm_fields: 'sys_id,name,table,trigger_type', sysparm_limit: 1 }
|
|
1242
1269
|
});
|
|
1243
1270
|
var flowRec = flowResp.data.result?.[0];
|
|
1244
|
-
debug.
|
|
1271
|
+
debug.flow_record = { table: str(flowRec?.table), trigger_type: str(flowRec?.trigger_type) };
|
|
1245
1272
|
if (!table && flowRec?.table) table = str(flowRec.table);
|
|
1246
|
-
// Try to resolve trigger name from trigger_type reference
|
|
1247
1273
|
var trigTypeId = str(flowRec?.trigger_type);
|
|
1248
1274
|
if (!triggerName && trigTypeId) {
|
|
1249
1275
|
try {
|
|
@@ -1252,7 +1278,7 @@ async function getFlowTriggerInfo(
|
|
|
1252
1278
|
});
|
|
1253
1279
|
var trigDef = trigDefResp.data.result?.[0];
|
|
1254
1280
|
if (trigDef?.name) triggerName = str(trigDef.name);
|
|
1255
|
-
debug.
|
|
1281
|
+
debug.trigger_def = { name: str(trigDef?.name), type: str(trigDef?.type) };
|
|
1256
1282
|
} catch (_) {}
|
|
1257
1283
|
}
|
|
1258
1284
|
} catch (_) {}
|