snow-flow 10.0.1-dev.472 → 10.0.1-dev.474
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
|
@@ -1142,10 +1142,11 @@ async function addActionViaGraphQL(
|
|
|
1142
1142
|
async function getFlowTriggerInfo(
|
|
1143
1143
|
client: any,
|
|
1144
1144
|
flowId: string
|
|
1145
|
-
): Promise<{ dataPillBase: string; triggerName: string; table: string; tableLabel: string; tableRef: string; error?: string }> {
|
|
1145
|
+
): Promise<{ dataPillBase: string; triggerName: string; table: string; tableLabel: string; tableRef: string; error?: string; debug?: any }> {
|
|
1146
1146
|
var triggerName = '';
|
|
1147
1147
|
var table = '';
|
|
1148
1148
|
var tableLabel = '';
|
|
1149
|
+
var debug: any = {};
|
|
1149
1150
|
|
|
1150
1151
|
try {
|
|
1151
1152
|
// Read the flow version payload which contains all flow elements
|
|
@@ -1156,37 +1157,97 @@ async function getFlowTriggerInfo(
|
|
|
1156
1157
|
sysparm_limit: 1
|
|
1157
1158
|
}
|
|
1158
1159
|
});
|
|
1159
|
-
var
|
|
1160
|
+
var versionRecord = resp.data.result?.[0];
|
|
1161
|
+
debug.version_found = !!versionRecord;
|
|
1162
|
+
debug.version_sys_id = versionRecord?.sys_id || null;
|
|
1163
|
+
var payload = versionRecord?.payload;
|
|
1164
|
+
debug.payload_exists = !!payload;
|
|
1165
|
+
debug.payload_type = typeof payload;
|
|
1160
1166
|
if (payload) {
|
|
1161
1167
|
var parsed = typeof payload === 'string' ? JSON.parse(payload) : payload;
|
|
1168
|
+
debug.payload_keys = Object.keys(parsed);
|
|
1162
1169
|
// The payload contains triggerInstances array with trigger data
|
|
1163
1170
|
var triggerInstances = parsed.triggerInstances || parsed.trigger_instances || [];
|
|
1171
|
+
debug.triggerInstances_found = Array.isArray(triggerInstances) ? triggerInstances.length : 'not_array';
|
|
1164
1172
|
if (!Array.isArray(triggerInstances)) {
|
|
1165
1173
|
// Some payloads nest elements differently
|
|
1166
1174
|
if (parsed.elements) {
|
|
1167
1175
|
triggerInstances = (Array.isArray(parsed.elements) ? parsed.elements : []).filter(
|
|
1168
1176
|
(e: any) => e.type === 'trigger' || e.elementType === 'trigger'
|
|
1169
1177
|
);
|
|
1178
|
+
debug.elements_trigger_count = triggerInstances.length;
|
|
1170
1179
|
}
|
|
1171
1180
|
}
|
|
1172
1181
|
if (triggerInstances.length > 0) {
|
|
1173
1182
|
var trigger = triggerInstances[0];
|
|
1183
|
+
debug.trigger_keys = Object.keys(trigger);
|
|
1184
|
+
debug.trigger_name_field = trigger.name;
|
|
1185
|
+
debug.trigger_triggerName_field = trigger.triggerName;
|
|
1174
1186
|
triggerName = trigger.name || trigger.triggerName || '';
|
|
1175
1187
|
// Look for table in trigger inputs
|
|
1176
1188
|
if (trigger.inputs && Array.isArray(trigger.inputs)) {
|
|
1189
|
+
debug.trigger_input_names = trigger.inputs.map(function (inp: any) { return inp.name; });
|
|
1177
1190
|
for (var ti = 0; ti < trigger.inputs.length; ti++) {
|
|
1178
1191
|
if (trigger.inputs[ti].name === 'table') {
|
|
1179
1192
|
table = trigger.inputs[ti].value?.value || trigger.inputs[ti].value || '';
|
|
1180
1193
|
break;
|
|
1181
1194
|
}
|
|
1182
1195
|
}
|
|
1196
|
+
} else {
|
|
1197
|
+
debug.trigger_inputs = trigger.inputs ? typeof trigger.inputs : 'undefined';
|
|
1183
1198
|
}
|
|
1184
1199
|
}
|
|
1200
|
+
} else {
|
|
1201
|
+
debug.payload_raw = 'null_or_empty';
|
|
1185
1202
|
}
|
|
1186
|
-
} catch (
|
|
1203
|
+
} catch (e: any) {
|
|
1204
|
+
debug.error = e.message;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
// Fallback: if version payload didn't have trigger, try reading from GraphQL flow state
|
|
1208
|
+
if (!triggerName || !table) {
|
|
1209
|
+
debug.fallback_graphql = 'attempting';
|
|
1210
|
+
try {
|
|
1211
|
+
var gqlQuery = 'query { global { snFlowDesigner { designTimeFlow(sysId: "' + flowId + '") { triggerInstances { name type inputs { name value { value } } } __typename } __typename } __typename } }';
|
|
1212
|
+
var gqlResp = await client.post('/api/now/graphql', { variables: {}, query: gqlQuery });
|
|
1213
|
+
var dtFlow = gqlResp.data?.data?.global?.snFlowDesigner?.designTimeFlow;
|
|
1214
|
+
var gqlTriggers = dtFlow?.triggerInstances || [];
|
|
1215
|
+
debug.fallback_graphql_triggers = gqlTriggers.length;
|
|
1216
|
+
if (gqlTriggers.length > 0) {
|
|
1217
|
+
var gqlTrig = gqlTriggers[0];
|
|
1218
|
+
debug.fallback_graphql_trigger = { name: gqlTrig.name, type: gqlTrig.type, inputCount: gqlTrig.inputs?.length };
|
|
1219
|
+
if (!triggerName && gqlTrig.name) triggerName = gqlTrig.name;
|
|
1220
|
+
if (!table && gqlTrig.inputs) {
|
|
1221
|
+
for (var gi = 0; gi < gqlTrig.inputs.length; gi++) {
|
|
1222
|
+
if (gqlTrig.inputs[gi].name === 'table') {
|
|
1223
|
+
table = gqlTrig.inputs[gi].value?.value || '';
|
|
1224
|
+
break;
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
} catch (gqlErr: any) {
|
|
1230
|
+
debug.fallback_graphql = 'error: ' + gqlErr.message;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// Fallback 2: look up trigger definition that belongs to this flow
|
|
1235
|
+
if (!triggerName) {
|
|
1236
|
+
debug.fallback_trigdef = 'attempting';
|
|
1237
|
+
try {
|
|
1238
|
+
// Query sys_hub_trigger_type_definition to find triggers available for this flow
|
|
1239
|
+
// The trigger name in the definition matches the data pill prefix
|
|
1240
|
+
var trigResp = await client.get('/api/now/table/sys_hub_flow', {
|
|
1241
|
+
params: { sysparm_query: 'sys_id=' + flowId, sysparm_fields: 'sys_id,name,table', sysparm_limit: 1 }
|
|
1242
|
+
});
|
|
1243
|
+
var flowRec = trigResp.data.result?.[0];
|
|
1244
|
+
debug.fallback_flow_record = { table: flowRec?.table };
|
|
1245
|
+
if (flowRec?.table && !table) table = str(flowRec.table);
|
|
1246
|
+
} catch (_) {}
|
|
1247
|
+
}
|
|
1187
1248
|
|
|
1188
1249
|
// Look up table label for display in label cache
|
|
1189
|
-
if (table) {
|
|
1250
|
+
if (table && !tableLabel) {
|
|
1190
1251
|
try {
|
|
1191
1252
|
var labelResp = await client.get('/api/now/table/sys_db_object', {
|
|
1192
1253
|
params: {
|
|
@@ -1199,17 +1260,16 @@ async function getFlowTriggerInfo(
|
|
|
1199
1260
|
tableLabel = str(labelResp.data.result?.[0]?.label) || '';
|
|
1200
1261
|
} catch (_) {}
|
|
1201
1262
|
if (!tableLabel) {
|
|
1202
|
-
// Fallback: capitalize the table name
|
|
1203
1263
|
tableLabel = table.charAt(0).toUpperCase() + table.slice(1).replace(/_/g, ' ');
|
|
1204
1264
|
}
|
|
1205
1265
|
}
|
|
1206
1266
|
|
|
1207
1267
|
if (!triggerName) {
|
|
1208
|
-
return { dataPillBase: '', triggerName: '', table: table, tableLabel: tableLabel, tableRef: table, error: 'Could not determine trigger name from flow version payload' };
|
|
1268
|
+
return { dataPillBase: '', triggerName: '', table: table, tableLabel: tableLabel, tableRef: table, error: 'Could not determine trigger name from flow version payload or GraphQL', debug };
|
|
1209
1269
|
}
|
|
1210
1270
|
|
|
1211
1271
|
var dataPillBase = triggerName + '_1.current';
|
|
1212
|
-
return { dataPillBase, triggerName, table, tableLabel, tableRef: table };
|
|
1272
|
+
return { dataPillBase, triggerName, table, tableLabel, tableRef: table, debug };
|
|
1213
1273
|
}
|
|
1214
1274
|
|
|
1215
1275
|
/**
|
|
@@ -1359,18 +1419,24 @@ async function buildConditionLabelCache(
|
|
|
1359
1419
|
triggerName: string,
|
|
1360
1420
|
table: string,
|
|
1361
1421
|
tableLabel: string,
|
|
1362
|
-
logicUiId: string
|
|
1422
|
+
logicUiId: string,
|
|
1423
|
+
explicitFields?: string[]
|
|
1363
1424
|
): Promise<any[]> {
|
|
1364
1425
|
if (!dataPillBase) return [];
|
|
1365
1426
|
|
|
1366
|
-
|
|
1367
|
-
if (
|
|
1427
|
+
// Collect unique field names — either from explicit list or by parsing encoded query
|
|
1428
|
+
if (!explicitFields) {
|
|
1429
|
+
var clauses = parseEncodedQuery(conditionValue);
|
|
1430
|
+
if (clauses.length === 0) return [];
|
|
1431
|
+
explicitFields = clauses.map(function (c) { return c.field; }).filter(function (f) { return !!f; });
|
|
1432
|
+
}
|
|
1433
|
+
if (explicitFields.length === 0) return [];
|
|
1368
1434
|
|
|
1369
|
-
//
|
|
1435
|
+
// De-duplicate field names
|
|
1370
1436
|
var uniqueFields: string[] = [];
|
|
1371
1437
|
var seen: Record<string, boolean> = {};
|
|
1372
|
-
for (var i = 0; i <
|
|
1373
|
-
var field =
|
|
1438
|
+
for (var i = 0; i < explicitFields.length; i++) {
|
|
1439
|
+
var field = explicitFields[i];
|
|
1374
1440
|
if (field && !seen[field]) {
|
|
1375
1441
|
seen[field] = true;
|
|
1376
1442
|
uniqueFields.push(field);
|
|
@@ -1474,7 +1540,8 @@ async function transformActionInputsForRecordAction(
|
|
|
1474
1540
|
triggerName: triggerInfo.triggerName,
|
|
1475
1541
|
table: triggerInfo.table,
|
|
1476
1542
|
tableLabel: triggerInfo.tableLabel,
|
|
1477
|
-
error: triggerInfo.error
|
|
1543
|
+
error: triggerInfo.error,
|
|
1544
|
+
debug: triggerInfo.debug
|
|
1478
1545
|
};
|
|
1479
1546
|
|
|
1480
1547
|
var dataPillBase = triggerInfo.dataPillBase; // e.g. "Created or Updated_1.current"
|
|
@@ -1733,22 +1800,46 @@ async function addFlowLogicViaGraphQL(
|
|
|
1733
1800
|
|
|
1734
1801
|
// ── Detect condition that needs data pill transformation ────────────
|
|
1735
1802
|
// Flow Designer sets conditions via a SEPARATE UPDATE after the element is created.
|
|
1736
|
-
//
|
|
1737
|
-
//
|
|
1803
|
+
// Three paths:
|
|
1804
|
+
// 1. Standard encoded query (category=software) → transform fields to {{dataPillBase.field}}
|
|
1805
|
+
// 2. Contains {{shorthand}} like {{trigger.current.X}} → rewrite to {{dataPillBase.X}} + labelCache
|
|
1806
|
+
// 3. Non-standard (JS expression, fd_data ref) → passthrough
|
|
1738
1807
|
const uuid = generateUUID();
|
|
1739
1808
|
var conditionInput = inputResult.inputs.find(function (inp: any) { return inp.name === 'condition'; });
|
|
1740
1809
|
var rawCondition = conditionInput?.value?.value || '';
|
|
1741
1810
|
var needsConditionUpdate = false;
|
|
1742
1811
|
var conditionTriggerInfo: any = null;
|
|
1743
1812
|
|
|
1744
|
-
|
|
1813
|
+
// Shorthand patterns that need rewriting to the real data pill base
|
|
1814
|
+
// e.g. {{trigger.current.category}} → {{Created or Updated_1.current.category}}
|
|
1815
|
+
var PILL_SHORTHANDS = ['trigger.current', 'current', 'trigger_record', 'trigger.record'];
|
|
1816
|
+
var hasShorthandPills = rawCondition.includes('{{') && PILL_SHORTHANDS.some(function (sh) {
|
|
1817
|
+
return rawCondition.includes('{{' + sh + '.') || rawCondition.includes('{{' + sh + '}}');
|
|
1818
|
+
});
|
|
1819
|
+
|
|
1820
|
+
if (rawCondition && rawCondition !== '^EQ' && (isStandardEncodedQuery(rawCondition) || hasShorthandPills)) {
|
|
1745
1821
|
conditionTriggerInfo = await getFlowTriggerInfo(client, flowId);
|
|
1746
1822
|
steps.trigger_info = {
|
|
1747
1823
|
dataPillBase: conditionTriggerInfo.dataPillBase, triggerName: conditionTriggerInfo.triggerName,
|
|
1748
|
-
table: conditionTriggerInfo.table, tableLabel: conditionTriggerInfo.tableLabel, error: conditionTriggerInfo.error
|
|
1824
|
+
table: conditionTriggerInfo.table, tableLabel: conditionTriggerInfo.tableLabel, error: conditionTriggerInfo.error,
|
|
1825
|
+
debug: conditionTriggerInfo.debug
|
|
1749
1826
|
};
|
|
1750
1827
|
if (conditionTriggerInfo.dataPillBase) {
|
|
1751
1828
|
needsConditionUpdate = true;
|
|
1829
|
+
|
|
1830
|
+
// If condition has shorthand pills, rewrite them to real data pill base first
|
|
1831
|
+
if (hasShorthandPills) {
|
|
1832
|
+
var pillBase = conditionTriggerInfo.dataPillBase;
|
|
1833
|
+
for (var si = 0; si < PILL_SHORTHANDS.length; si++) {
|
|
1834
|
+
var sh = PILL_SHORTHANDS[si];
|
|
1835
|
+
// Replace {{trigger.current.field}} → {{Created or Updated_1.current.field}}
|
|
1836
|
+
rawCondition = rawCondition.split('{{' + sh + '.').join('{{' + pillBase + '.');
|
|
1837
|
+
// Replace {{trigger.current}} → {{Created or Updated_1.current}}
|
|
1838
|
+
rawCondition = rawCondition.split('{{' + sh + '}}').join('{{' + pillBase + '}}');
|
|
1839
|
+
}
|
|
1840
|
+
steps.shorthand_rewrite = { original: conditionInput?.value?.value, rewritten: rawCondition };
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1752
1843
|
// Clear condition in INSERT — it will be set via separate UPDATE with labelCache
|
|
1753
1844
|
conditionInput.value = { schemaless: false, schemalessValue: '', value: '' };
|
|
1754
1845
|
steps.condition_strategy = 'two_step';
|
|
@@ -1810,11 +1901,34 @@ async function addFlowLogicViaGraphQL(
|
|
|
1810
1901
|
// The Flow Designer UI always sets conditions in a separate UPDATE after creating the element.
|
|
1811
1902
|
if (needsConditionUpdate && conditionTriggerInfo) {
|
|
1812
1903
|
var dataPillBase = conditionTriggerInfo.dataPillBase;
|
|
1813
|
-
var transformedCondition
|
|
1814
|
-
var labelCacheEntries
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1904
|
+
var transformedCondition: string;
|
|
1905
|
+
var labelCacheEntries: any[];
|
|
1906
|
+
|
|
1907
|
+
if (rawCondition.includes('{{')) {
|
|
1908
|
+
// Condition already contains data pill references (after shorthand rewrite)
|
|
1909
|
+
// Use as-is and extract field names from {{pill.field}} patterns for labelCache
|
|
1910
|
+
transformedCondition = rawCondition;
|
|
1911
|
+
var pillFields: string[] = [];
|
|
1912
|
+
var pillRx = /\{\{([^}]+)\}\}/g;
|
|
1913
|
+
var pm;
|
|
1914
|
+
while ((pm = pillRx.exec(rawCondition)) !== null) {
|
|
1915
|
+
var pParts = pm[1].split('.');
|
|
1916
|
+
if (pParts.length > 2) pillFields.push(pParts[pParts.length - 1]);
|
|
1917
|
+
}
|
|
1918
|
+
// Build labelCache using extracted field names
|
|
1919
|
+
labelCacheEntries = await buildConditionLabelCache(
|
|
1920
|
+
client, rawCondition, dataPillBase, conditionTriggerInfo.triggerName,
|
|
1921
|
+
conditionTriggerInfo.tableRef, conditionTriggerInfo.tableLabel, returnedUuid,
|
|
1922
|
+
pillFields
|
|
1923
|
+
);
|
|
1924
|
+
} else {
|
|
1925
|
+
// Plain encoded query — transform to data pill format
|
|
1926
|
+
transformedCondition = transformConditionToDataPills(rawCondition, dataPillBase);
|
|
1927
|
+
labelCacheEntries = await buildConditionLabelCache(
|
|
1928
|
+
client, rawCondition, dataPillBase, conditionTriggerInfo.triggerName,
|
|
1929
|
+
conditionTriggerInfo.tableRef, conditionTriggerInfo.tableLabel, returnedUuid
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1818
1932
|
|
|
1819
1933
|
steps.condition_transform = { original: rawCondition, transformed: transformedCondition };
|
|
1820
1934
|
steps.label_cache = { count: labelCacheEntries.length, pills: labelCacheEntries.map(function (e: any) { return e.name; }) };
|