snow-flow 10.0.1-dev.391 → 10.0.1-dev.392
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
|
@@ -35,7 +35,6 @@ function isSysId(value: string): boolean {
|
|
|
35
35
|
|
|
36
36
|
var FLOW_FACTORY_API_NAME = 'Snow-Flow Flow Factory';
|
|
37
37
|
var FLOW_FACTORY_API_ID = 'flow_factory';
|
|
38
|
-
var FLOW_FACTORY_NAMESPACE = 'x_snflw';
|
|
39
38
|
var FLOW_FACTORY_CACHE_TTL = 300000; // 5 minutes
|
|
40
39
|
|
|
41
40
|
var _flowFactoryCache: { apiSysId: string; namespace: string; timestamp: number } | null = null;
|
|
@@ -48,7 +47,14 @@ var _bootstrapPromise: Promise<{ namespace: string; apiSysId: string }> | null =
|
|
|
48
47
|
*/
|
|
49
48
|
var FLOW_FACTORY_SCRIPT = [
|
|
50
49
|
'(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {',
|
|
51
|
-
' var body
|
|
50
|
+
' var body;',
|
|
51
|
+
' try { body = JSON.parse(request.body.dataString); }',
|
|
52
|
+
' catch(e) { body = request.body.data; }',
|
|
53
|
+
' if (!body || typeof body !== "object") {',
|
|
54
|
+
' response.setStatus(400);',
|
|
55
|
+
' response.setBody({ success: false, error: "Invalid request body: " + typeof body });',
|
|
56
|
+
' return;',
|
|
57
|
+
' }',
|
|
52
58
|
' var result = { success: false, steps: {} };',
|
|
53
59
|
'',
|
|
54
60
|
' try {',
|
|
@@ -101,6 +107,9 @@ var FLOW_FACTORY_SCRIPT = [
|
|
|
101
107
|
' ver.setValue("version", "1.0");',
|
|
102
108
|
' ver.setValue("state", shouldActivate ? "published" : "draft");',
|
|
103
109
|
' ver.setValue("active", true);',
|
|
110
|
+
' ver.setValue("compile_state", "compiled");',
|
|
111
|
+
' ver.setValue("is_current", true);',
|
|
112
|
+
' if (shouldActivate) ver.setValue("published_flow", flowSysId);',
|
|
104
113
|
' if (body.flow_definition) {',
|
|
105
114
|
' ver.setValue("flow_definition", typeof body.flow_definition === "string" ? body.flow_definition : JSON.stringify(body.flow_definition));',
|
|
106
115
|
' }',
|
|
@@ -229,12 +238,97 @@ var FLOW_FACTORY_SCRIPT = [
|
|
|
229
238
|
'})(request, response);'
|
|
230
239
|
].join('\n');
|
|
231
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Probe the ServiceNow instance to discover the correct URL namespace for
|
|
243
|
+
* the Flow Factory Scripted REST API. Sends GET requests to candidate
|
|
244
|
+
* namespaces — a 405 (Method Not Allowed) or 401/403 confirms the namespace
|
|
245
|
+
* exists, while 404 means wrong namespace.
|
|
246
|
+
*/
|
|
247
|
+
async function probeFlowFactoryNamespace(
|
|
248
|
+
client: any,
|
|
249
|
+
apiSysId: string,
|
|
250
|
+
instanceUrl: string
|
|
251
|
+
): Promise<string | null> {
|
|
252
|
+
// Build candidate list from multiple sources
|
|
253
|
+
var candidates: string[] = [];
|
|
254
|
+
|
|
255
|
+
// 1. Read back the record's namespace field
|
|
256
|
+
try {
|
|
257
|
+
var nsResp = await client.get('/api/now/table/sys_ws_definition/' + apiSysId, {
|
|
258
|
+
params: { sysparm_fields: 'sys_id,api_id,namespace', sysparm_display_value: 'all' }
|
|
259
|
+
});
|
|
260
|
+
var record = nsResp.data.result || {};
|
|
261
|
+
var ns = record.namespace;
|
|
262
|
+
if (ns) {
|
|
263
|
+
if (typeof ns === 'object') {
|
|
264
|
+
var dv = ns.display_value || '';
|
|
265
|
+
var val = ns.value || '';
|
|
266
|
+
if (dv && /^(x_|sn_)/.test(dv)) candidates.push(dv);
|
|
267
|
+
if (val && /^(x_|sn_)/.test(val)) candidates.push(val);
|
|
268
|
+
} else if (typeof ns === 'string' && ns.length > 0 && ns !== 'Global' && ns !== 'global') {
|
|
269
|
+
candidates.push(ns);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
} catch (_) {}
|
|
273
|
+
|
|
274
|
+
// 2. Company code from sys_properties
|
|
275
|
+
try {
|
|
276
|
+
var compResp = await client.get('/api/now/table/sys_properties', {
|
|
277
|
+
params: {
|
|
278
|
+
sysparm_query: 'name=glide.appcreator.company.code',
|
|
279
|
+
sysparm_fields: 'value',
|
|
280
|
+
sysparm_limit: 1
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
var companyCode = compResp.data.result?.[0]?.value;
|
|
284
|
+
if (companyCode) candidates.push(companyCode);
|
|
285
|
+
} catch (_) {}
|
|
286
|
+
|
|
287
|
+
// 3. Instance subdomain (e.g. "dev351277" from "https://dev351277.service-now.com")
|
|
288
|
+
try {
|
|
289
|
+
var match = instanceUrl.match(/https?:\/\/([^.]+)\./);
|
|
290
|
+
if (match && match[1]) candidates.push(match[1]);
|
|
291
|
+
} catch (_) {}
|
|
292
|
+
|
|
293
|
+
// 4. Fixed fallbacks
|
|
294
|
+
candidates.push('now', 'global');
|
|
295
|
+
|
|
296
|
+
// Deduplicate
|
|
297
|
+
var seen: Record<string, boolean> = {};
|
|
298
|
+
var unique: string[] = [];
|
|
299
|
+
for (var i = 0; i < candidates.length; i++) {
|
|
300
|
+
if (!seen[candidates[i]]) {
|
|
301
|
+
seen[candidates[i]] = true;
|
|
302
|
+
unique.push(candidates[i]);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// 5. Probe each candidate — GET on a POST-only endpoint
|
|
307
|
+
for (var j = 0; j < unique.length; j++) {
|
|
308
|
+
try {
|
|
309
|
+
await client.get('/api/' + unique[j] + '/' + FLOW_FACTORY_API_ID + '/create');
|
|
310
|
+
return unique[j]; // 200 = endpoint exists (unlikely but valid)
|
|
311
|
+
} catch (probeError: any) {
|
|
312
|
+
var status = probeError.response?.status;
|
|
313
|
+
if (status === 405 || status === 401 || status === 403) {
|
|
314
|
+
return unique[j]; // Namespace correct — method or auth rejected
|
|
315
|
+
}
|
|
316
|
+
// 404 = wrong namespace, try next
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return null; // No namespace matched — factory unreachable
|
|
321
|
+
}
|
|
322
|
+
|
|
232
323
|
/**
|
|
233
324
|
* Ensure the Flow Factory Scripted REST API exists on the ServiceNow instance.
|
|
234
325
|
* Idempotent — checks cache first, then instance, deploys only if missing.
|
|
235
|
-
* Uses
|
|
326
|
+
* Uses namespace probing (HTTP GET) instead of record field parsing.
|
|
236
327
|
*/
|
|
237
|
-
async function ensureFlowFactoryAPI(
|
|
328
|
+
async function ensureFlowFactoryAPI(
|
|
329
|
+
client: any,
|
|
330
|
+
instanceUrl: string
|
|
331
|
+
): Promise<{ namespace: string; apiSysId: string }> {
|
|
238
332
|
// 1. Check in-memory cache
|
|
239
333
|
if (_flowFactoryCache && (Date.now() - _flowFactoryCache.timestamp) < FLOW_FACTORY_CACHE_TTL) {
|
|
240
334
|
return { namespace: _flowFactoryCache.namespace, apiSysId: _flowFactoryCache.apiSysId };
|
|
@@ -258,7 +352,10 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
258
352
|
|
|
259
353
|
if (checkResp.data.result && checkResp.data.result.length > 0) {
|
|
260
354
|
var existing = checkResp.data.result[0];
|
|
261
|
-
var ns =
|
|
355
|
+
var ns = await probeFlowFactoryNamespace(client, existing.sys_id, instanceUrl);
|
|
356
|
+
if (!ns) {
|
|
357
|
+
throw new Error('Flow Factory API exists (sys_id=' + existing.sys_id + ') but namespace could not be resolved via HTTP probing');
|
|
358
|
+
}
|
|
262
359
|
_flowFactoryCache = { apiSysId: existing.sys_id, namespace: ns, timestamp: Date.now() };
|
|
263
360
|
return { namespace: ns, apiSysId: existing.sys_id };
|
|
264
361
|
}
|
|
@@ -270,7 +367,7 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
270
367
|
active: true,
|
|
271
368
|
short_description: 'Bootstrapped by Snow-Flow MCP for reliable Flow Designer creation via GlideRecord',
|
|
272
369
|
is_versioned: false,
|
|
273
|
-
enforce_acl: '
|
|
370
|
+
enforce_acl: 'false',
|
|
274
371
|
requires_authentication: true
|
|
275
372
|
});
|
|
276
373
|
|
|
@@ -290,7 +387,7 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
290
387
|
short_description: 'Create a flow or subflow with GlideRecord (triggers all BRs + version record)',
|
|
291
388
|
operation_script: FLOW_FACTORY_SCRIPT,
|
|
292
389
|
requires_authentication: true,
|
|
293
|
-
enforce_acl: '
|
|
390
|
+
enforce_acl: 'false'
|
|
294
391
|
});
|
|
295
392
|
} catch (opError: any) {
|
|
296
393
|
// Cleanup the API definition if operation creation fails
|
|
@@ -298,11 +395,11 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
298
395
|
throw new Error('Failed to create Scripted REST operation: ' + (opError.message || opError));
|
|
299
396
|
}
|
|
300
397
|
|
|
301
|
-
// 6.
|
|
302
|
-
var
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
398
|
+
// 6. Probe to discover the namespace ServiceNow assigned
|
|
399
|
+
var resolvedNs = await probeFlowFactoryNamespace(client, apiSysId, instanceUrl);
|
|
400
|
+
if (!resolvedNs) {
|
|
401
|
+
throw new Error('Flow Factory API created (sys_id=' + apiSysId + ') but namespace could not be resolved via HTTP probing');
|
|
402
|
+
}
|
|
306
403
|
|
|
307
404
|
_flowFactoryCache = { apiSysId: apiSysId, namespace: resolvedNs, timestamp: Date.now() };
|
|
308
405
|
return { namespace: resolvedNs, apiSysId: apiSysId };
|
|
@@ -315,29 +412,6 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
315
412
|
return _bootstrapPromise;
|
|
316
413
|
}
|
|
317
414
|
|
|
318
|
-
/**
|
|
319
|
-
* Extract the URL namespace from a sys_ws_definition record.
|
|
320
|
-
* The namespace field can be a string, a reference object, or empty.
|
|
321
|
-
* For global scope APIs the namespace is typically the instance company prefix or 'now'.
|
|
322
|
-
*/
|
|
323
|
-
function resolveNamespaceFromRecord(record: any): string {
|
|
324
|
-
var ns = record.namespace;
|
|
325
|
-
if (!ns) return FLOW_FACTORY_NAMESPACE;
|
|
326
|
-
|
|
327
|
-
// display_value / value pair (sysparm_display_value=all)
|
|
328
|
-
if (typeof ns === 'object') {
|
|
329
|
-
// display_value is the scope name like "Global" or "x_snflw" — use value for sys_id, display_value for name
|
|
330
|
-
var dv = ns.display_value || '';
|
|
331
|
-
// If display_value looks like a scope namespace (x_something, sn_something, now, global), use it
|
|
332
|
-
if (dv && dv !== 'Global' && dv !== 'global') return dv;
|
|
333
|
-
// For Global scope, fall through to default
|
|
334
|
-
}
|
|
335
|
-
if (typeof ns === 'string' && ns.length > 0 && ns.length < 100) {
|
|
336
|
-
return ns;
|
|
337
|
-
}
|
|
338
|
-
return FLOW_FACTORY_NAMESPACE;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
415
|
/**
|
|
342
416
|
* Invalidate the Flow Factory cache (e.g. on 404 when API was deleted externally).
|
|
343
417
|
*/
|
|
@@ -592,8 +666,23 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
592
666
|
var actionsCreated = 0;
|
|
593
667
|
var varsCreated = 0;
|
|
594
668
|
|
|
669
|
+
// Diagnostics: track every step for debugging "flow cannot be found" issues
|
|
670
|
+
var diagnostics: any = {
|
|
671
|
+
factory_bootstrap: null,
|
|
672
|
+
factory_namespace: null,
|
|
673
|
+
factory_call: null,
|
|
674
|
+
table_api_used: false,
|
|
675
|
+
version_created: false,
|
|
676
|
+
version_method: null,
|
|
677
|
+
version_fields_set: [] as string[],
|
|
678
|
+
snapshot_result: null,
|
|
679
|
+
post_verify: null
|
|
680
|
+
};
|
|
681
|
+
|
|
595
682
|
try {
|
|
596
|
-
var factory = await ensureFlowFactoryAPI(client);
|
|
683
|
+
var factory = await ensureFlowFactoryAPI(client, context.instanceUrl);
|
|
684
|
+
diagnostics.factory_bootstrap = 'success';
|
|
685
|
+
diagnostics.factory_namespace = factory.namespace;
|
|
597
686
|
|
|
598
687
|
var factoryPayload = {
|
|
599
688
|
name: flowName,
|
|
@@ -622,7 +711,8 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
622
711
|
// 404 = API was deleted externally → invalidate cache, retry once
|
|
623
712
|
if (callError.response?.status === 404) {
|
|
624
713
|
invalidateFlowFactoryCache();
|
|
625
|
-
var retryFactory = await ensureFlowFactoryAPI(client);
|
|
714
|
+
var retryFactory = await ensureFlowFactoryAPI(client, context.instanceUrl);
|
|
715
|
+
diagnostics.factory_namespace = retryFactory.namespace;
|
|
626
716
|
var retryEndpoint = '/api/' + retryFactory.namespace + '/' + FLOW_FACTORY_API_ID + '/create';
|
|
627
717
|
factoryResp = await client.post(retryEndpoint, factoryPayload);
|
|
628
718
|
} else {
|
|
@@ -632,9 +722,13 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
632
722
|
|
|
633
723
|
var factoryResult = factoryResp.data?.result || factoryResp.data;
|
|
634
724
|
if (factoryResult && factoryResult.success && factoryResult.flow_sys_id) {
|
|
725
|
+
diagnostics.factory_call = 'success';
|
|
635
726
|
flowSysId = factoryResult.flow_sys_id;
|
|
636
727
|
usedMethod = 'scripted_rest_api';
|
|
637
728
|
versionCreated = !!factoryResult.version_created;
|
|
729
|
+
diagnostics.version_created = versionCreated;
|
|
730
|
+
diagnostics.version_method = 'factory';
|
|
731
|
+
diagnostics.version_fields_set = ['flow', 'name', 'version', 'state', 'active', 'compile_state', 'is_current', 'published_flow'];
|
|
638
732
|
|
|
639
733
|
// Extract step details
|
|
640
734
|
var steps = factoryResult.steps || {};
|
|
@@ -657,14 +751,19 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
657
751
|
} catch (factoryError: any) {
|
|
658
752
|
// Flow Factory unavailable — fall through to Table API
|
|
659
753
|
var statusCode = factoryError.response?.status;
|
|
754
|
+
var factoryErrMsg = statusCode
|
|
755
|
+
? 'HTTP ' + statusCode + ': ' + (factoryError.response?.data?.error?.message || factoryError.message || 'unknown')
|
|
756
|
+
: (factoryError.message || 'unknown');
|
|
757
|
+
diagnostics.factory_bootstrap = diagnostics.factory_bootstrap || ('error: ' + factoryErrMsg);
|
|
758
|
+
diagnostics.factory_call = diagnostics.factory_call || ('error: ' + factoryErrMsg);
|
|
660
759
|
if (statusCode !== 403) {
|
|
661
|
-
|
|
662
|
-
factoryWarnings.push('Flow Factory unavailable (' + (statusCode || factoryError.message || 'unknown') + '), using Table API fallback');
|
|
760
|
+
factoryWarnings.push('Flow Factory unavailable (' + factoryErrMsg + '), using Table API fallback');
|
|
663
761
|
}
|
|
664
762
|
}
|
|
665
763
|
|
|
666
764
|
// ── Table API fallback (existing logic) ─────────────────────
|
|
667
765
|
if (!flowSysId) {
|
|
766
|
+
diagnostics.table_api_used = true;
|
|
668
767
|
var flowData: any = {
|
|
669
768
|
name: flowName,
|
|
670
769
|
description: flowDescription,
|
|
@@ -691,12 +790,18 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
691
790
|
version: '1.0',
|
|
692
791
|
state: shouldActivate ? 'published' : 'draft',
|
|
693
792
|
active: true,
|
|
793
|
+
compile_state: 'compiled',
|
|
794
|
+
is_current: true,
|
|
694
795
|
flow_definition: JSON.stringify(flowDefinition)
|
|
695
796
|
};
|
|
797
|
+
if (shouldActivate) versionData.published_flow = flowSysId;
|
|
696
798
|
var versionResp = await client.post('/api/now/table/sys_hub_flow_version', versionData);
|
|
697
799
|
var versionSysId = versionResp.data.result?.sys_id;
|
|
698
800
|
if (versionSysId) {
|
|
699
801
|
versionCreated = true;
|
|
802
|
+
diagnostics.version_created = true;
|
|
803
|
+
diagnostics.version_method = 'table_api';
|
|
804
|
+
diagnostics.version_fields_set = ['flow', 'name', 'version', 'state', 'active', 'compile_state', 'is_current', 'published_flow'];
|
|
700
805
|
// Link flow to its version
|
|
701
806
|
try {
|
|
702
807
|
await client.patch('/api/now/table/sys_hub_flow/' + flowSysId, {
|
|
@@ -817,7 +922,77 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
817
922
|
// Best-effort snapshot
|
|
818
923
|
try {
|
|
819
924
|
await client.post('/api/sn_flow_designer/flow/snapshot', { flow_id: flowSysId });
|
|
820
|
-
|
|
925
|
+
diagnostics.snapshot_result = 'success';
|
|
926
|
+
} catch (snapError: any) {
|
|
927
|
+
diagnostics.snapshot_result = 'error: ' + (snapError.response?.status || snapError.message || 'unknown');
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// ── Post-creation verification ─────────────────────────────
|
|
932
|
+
if (flowSysId) {
|
|
933
|
+
try {
|
|
934
|
+
var verifyResp = await client.get('/api/now/table/sys_hub_flow/' + flowSysId, {
|
|
935
|
+
params: { sysparm_fields: 'sys_id,name,latest_version' }
|
|
936
|
+
});
|
|
937
|
+
var verifyFlow = verifyResp.data.result;
|
|
938
|
+
var hasLatestVersion = !!(verifyFlow && verifyFlow.latest_version);
|
|
939
|
+
|
|
940
|
+
// Check if version record exists
|
|
941
|
+
var verCheckResp = await client.get('/api/now/table/sys_hub_flow_version', {
|
|
942
|
+
params: {
|
|
943
|
+
sysparm_query: 'flow=' + flowSysId,
|
|
944
|
+
sysparm_fields: 'sys_id,name,state,compile_state,is_current',
|
|
945
|
+
sysparm_limit: 1
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
var verRecords = verCheckResp.data.result || [];
|
|
949
|
+
var hasVersionRecord = verRecords.length > 0;
|
|
950
|
+
|
|
951
|
+
diagnostics.post_verify = {
|
|
952
|
+
flow_exists: true,
|
|
953
|
+
has_latest_version_ref: hasLatestVersion,
|
|
954
|
+
version_record_exists: hasVersionRecord,
|
|
955
|
+
version_details: hasVersionRecord ? {
|
|
956
|
+
sys_id: verRecords[0].sys_id,
|
|
957
|
+
state: verRecords[0].state,
|
|
958
|
+
compile_state: verRecords[0].compile_state,
|
|
959
|
+
is_current: verRecords[0].is_current
|
|
960
|
+
} : null
|
|
961
|
+
};
|
|
962
|
+
|
|
963
|
+
// If version record is missing, retry creation
|
|
964
|
+
if (!hasVersionRecord && !versionCreated) {
|
|
965
|
+
try {
|
|
966
|
+
var retryVersionData: any = {
|
|
967
|
+
flow: flowSysId,
|
|
968
|
+
name: '1.0',
|
|
969
|
+
version: '1.0',
|
|
970
|
+
state: shouldActivate ? 'published' : 'draft',
|
|
971
|
+
active: true,
|
|
972
|
+
compile_state: 'compiled',
|
|
973
|
+
is_current: true,
|
|
974
|
+
flow_definition: JSON.stringify(flowDefinition)
|
|
975
|
+
};
|
|
976
|
+
if (shouldActivate) retryVersionData.published_flow = flowSysId;
|
|
977
|
+
|
|
978
|
+
var retryVerResp = await client.post('/api/now/table/sys_hub_flow_version', retryVersionData);
|
|
979
|
+
var retryVerSysId = retryVerResp.data.result?.sys_id;
|
|
980
|
+
if (retryVerSysId) {
|
|
981
|
+
versionCreated = true;
|
|
982
|
+
diagnostics.version_created = true;
|
|
983
|
+
diagnostics.version_method = (diagnostics.version_method || 'table_api') + ' (retry)';
|
|
984
|
+
try {
|
|
985
|
+
await client.patch('/api/now/table/sys_hub_flow/' + flowSysId, { latest_version: retryVerSysId });
|
|
986
|
+
} catch (_) {}
|
|
987
|
+
factoryWarnings.push('Version record was missing — created via post-verify retry');
|
|
988
|
+
}
|
|
989
|
+
} catch (retryErr: any) {
|
|
990
|
+
factoryWarnings.push('Post-verify version retry failed: ' + (retryErr.message || retryErr));
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
} catch (verifyErr: any) {
|
|
994
|
+
diagnostics.post_verify = { error: verifyErr.message || 'verification failed' };
|
|
995
|
+
}
|
|
821
996
|
}
|
|
822
997
|
|
|
823
998
|
// ── Build summary ───────────────────────────────────────────
|
|
@@ -833,8 +1008,14 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
833
1008
|
.field('Status', shouldActivate ? 'Published (active)' : 'Draft')
|
|
834
1009
|
.field('Method', methodLabel);
|
|
835
1010
|
|
|
1011
|
+
if (diagnostics.factory_namespace) {
|
|
1012
|
+
createSummary.field('Namespace', diagnostics.factory_namespace);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
836
1015
|
if (versionCreated) {
|
|
837
|
-
createSummary.field('Version', 'v1.0 created');
|
|
1016
|
+
createSummary.field('Version', 'v1.0 created' + (diagnostics.version_method ? ' (' + diagnostics.version_method + ')' : ''));
|
|
1017
|
+
} else {
|
|
1018
|
+
createSummary.warning('Version record NOT created — flow may show "cannot be found" in Flow Designer');
|
|
838
1019
|
}
|
|
839
1020
|
|
|
840
1021
|
if (!isSubflow && triggerType !== 'manual') {
|
|
@@ -851,6 +1032,24 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
851
1032
|
createSummary.warning(factoryWarnings[wi]);
|
|
852
1033
|
}
|
|
853
1034
|
|
|
1035
|
+
// Diagnostics section
|
|
1036
|
+
createSummary.blank().line('Diagnostics:');
|
|
1037
|
+
createSummary.indented('Factory bootstrap: ' + (diagnostics.factory_bootstrap || 'not attempted'));
|
|
1038
|
+
createSummary.indented('Factory namespace: ' + (diagnostics.factory_namespace || 'n/a'));
|
|
1039
|
+
createSummary.indented('Factory call: ' + (diagnostics.factory_call || 'not attempted'));
|
|
1040
|
+
createSummary.indented('Table API used: ' + diagnostics.table_api_used);
|
|
1041
|
+
createSummary.indented('Version created: ' + diagnostics.version_created + (diagnostics.version_method ? ' (' + diagnostics.version_method + ')' : ''));
|
|
1042
|
+
createSummary.indented('Snapshot: ' + (diagnostics.snapshot_result || 'n/a'));
|
|
1043
|
+
if (diagnostics.post_verify) {
|
|
1044
|
+
if (diagnostics.post_verify.error) {
|
|
1045
|
+
createSummary.indented('Post-verify: error — ' + diagnostics.post_verify.error);
|
|
1046
|
+
} else {
|
|
1047
|
+
createSummary.indented('Post-verify: flow=' + diagnostics.post_verify.flow_exists +
|
|
1048
|
+
', version_record=' + diagnostics.post_verify.version_record_exists +
|
|
1049
|
+
', latest_version_ref=' + diagnostics.post_verify.has_latest_version_ref);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
854
1053
|
return createSuccessResult({
|
|
855
1054
|
created: true,
|
|
856
1055
|
method: usedMethod,
|
|
@@ -872,7 +1071,8 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
872
1071
|
activities_created: actionsCreated,
|
|
873
1072
|
activities_requested: activitiesArg.length,
|
|
874
1073
|
variables_created: varsCreated,
|
|
875
|
-
warnings: factoryWarnings.length > 0 ? factoryWarnings : undefined
|
|
1074
|
+
warnings: factoryWarnings.length > 0 ? factoryWarnings : undefined,
|
|
1075
|
+
diagnostics: diagnostics
|
|
876
1076
|
}, {}, createSummary.build());
|
|
877
1077
|
}
|
|
878
1078
|
|
|
@@ -1225,5 +1425,5 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
1225
1425
|
}
|
|
1226
1426
|
}
|
|
1227
1427
|
|
|
1228
|
-
export const version = '
|
|
1428
|
+
export const version = '3.0.0';
|
|
1229
1429
|
export const author = 'Snow-Flow Team';
|