snow-flow-test 10.0.1-test.108 → 10.0.1-test.110
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 };
|
|
@@ -247,32 +341,34 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
247
341
|
|
|
248
342
|
_bootstrapPromise = (async () => {
|
|
249
343
|
try {
|
|
250
|
-
// 3. Check if API already exists on instance
|
|
344
|
+
// 3. Check if API already exists on instance (query by api_id, more reliable than name)
|
|
251
345
|
var checkResp = await client.get('/api/now/table/sys_ws_definition', {
|
|
252
346
|
params: {
|
|
253
|
-
sysparm_query: '
|
|
254
|
-
sysparm_fields: 'sys_id,namespace
|
|
347
|
+
sysparm_query: 'api_id=' + FLOW_FACTORY_API_ID,
|
|
348
|
+
sysparm_fields: 'sys_id,api_id,namespace',
|
|
255
349
|
sysparm_limit: 1
|
|
256
350
|
}
|
|
257
351
|
});
|
|
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
|
}
|
|
265
362
|
|
|
266
|
-
// 4. Deploy the Scripted REST API
|
|
363
|
+
// 4. Deploy the Scripted REST API (do NOT set namespace — let ServiceNow assign it)
|
|
267
364
|
var apiResp = await client.post('/api/now/table/sys_ws_definition', {
|
|
268
365
|
name: FLOW_FACTORY_API_NAME,
|
|
269
366
|
api_id: FLOW_FACTORY_API_ID,
|
|
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: '
|
|
274
|
-
requires_authentication: true
|
|
275
|
-
namespace: FLOW_FACTORY_NAMESPACE
|
|
370
|
+
enforce_acl: 'false',
|
|
371
|
+
requires_authentication: true
|
|
276
372
|
});
|
|
277
373
|
|
|
278
374
|
var apiSysId = apiResp.data.result?.sys_id;
|
|
@@ -291,7 +387,7 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
291
387
|
short_description: 'Create a flow or subflow with GlideRecord (triggers all BRs + version record)',
|
|
292
388
|
operation_script: FLOW_FACTORY_SCRIPT,
|
|
293
389
|
requires_authentication: true,
|
|
294
|
-
enforce_acl: '
|
|
390
|
+
enforce_acl: 'false'
|
|
295
391
|
});
|
|
296
392
|
} catch (opError: any) {
|
|
297
393
|
// Cleanup the API definition if operation creation fails
|
|
@@ -299,18 +395,10 @@ async function ensureFlowFactoryAPI(client: any): Promise<{ namespace: string; a
|
|
|
299
395
|
throw new Error('Failed to create Scripted REST operation: ' + (opError.message || opError));
|
|
300
396
|
}
|
|
301
397
|
|
|
302
|
-
//
|
|
303
|
-
var
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
var resolvedNs = FLOW_FACTORY_NAMESPACE;
|
|
307
|
-
if (nsResp.data.result?.namespace) {
|
|
308
|
-
var nsVal = nsResp.data.result.namespace;
|
|
309
|
-
if (typeof nsVal === 'object' && nsVal.display_value) {
|
|
310
|
-
resolvedNs = nsVal.display_value;
|
|
311
|
-
} else if (typeof nsVal === 'string' && nsVal.length > 0) {
|
|
312
|
-
resolvedNs = nsVal;
|
|
313
|
-
}
|
|
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');
|
|
314
402
|
}
|
|
315
403
|
|
|
316
404
|
_flowFactoryCache = { apiSysId: apiSysId, namespace: resolvedNs, timestamp: Date.now() };
|
|
@@ -578,8 +666,23 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
578
666
|
var actionsCreated = 0;
|
|
579
667
|
var varsCreated = 0;
|
|
580
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
|
+
|
|
581
682
|
try {
|
|
582
|
-
var factory = await ensureFlowFactoryAPI(client);
|
|
683
|
+
var factory = await ensureFlowFactoryAPI(client, context.instanceUrl);
|
|
684
|
+
diagnostics.factory_bootstrap = 'success';
|
|
685
|
+
diagnostics.factory_namespace = factory.namespace;
|
|
583
686
|
|
|
584
687
|
var factoryPayload = {
|
|
585
688
|
name: flowName,
|
|
@@ -608,7 +711,8 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
608
711
|
// 404 = API was deleted externally → invalidate cache, retry once
|
|
609
712
|
if (callError.response?.status === 404) {
|
|
610
713
|
invalidateFlowFactoryCache();
|
|
611
|
-
var retryFactory = await ensureFlowFactoryAPI(client);
|
|
714
|
+
var retryFactory = await ensureFlowFactoryAPI(client, context.instanceUrl);
|
|
715
|
+
diagnostics.factory_namespace = retryFactory.namespace;
|
|
612
716
|
var retryEndpoint = '/api/' + retryFactory.namespace + '/' + FLOW_FACTORY_API_ID + '/create';
|
|
613
717
|
factoryResp = await client.post(retryEndpoint, factoryPayload);
|
|
614
718
|
} else {
|
|
@@ -618,9 +722,13 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
618
722
|
|
|
619
723
|
var factoryResult = factoryResp.data?.result || factoryResp.data;
|
|
620
724
|
if (factoryResult && factoryResult.success && factoryResult.flow_sys_id) {
|
|
725
|
+
diagnostics.factory_call = 'success';
|
|
621
726
|
flowSysId = factoryResult.flow_sys_id;
|
|
622
727
|
usedMethod = 'scripted_rest_api';
|
|
623
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'];
|
|
624
732
|
|
|
625
733
|
// Extract step details
|
|
626
734
|
var steps = factoryResult.steps || {};
|
|
@@ -643,14 +751,19 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
643
751
|
} catch (factoryError: any) {
|
|
644
752
|
// Flow Factory unavailable — fall through to Table API
|
|
645
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);
|
|
646
759
|
if (statusCode !== 403) {
|
|
647
|
-
|
|
648
|
-
factoryWarnings.push('Flow Factory unavailable (' + (statusCode || factoryError.message || 'unknown') + '), using Table API fallback');
|
|
760
|
+
factoryWarnings.push('Flow Factory unavailable (' + factoryErrMsg + '), using Table API fallback');
|
|
649
761
|
}
|
|
650
762
|
}
|
|
651
763
|
|
|
652
764
|
// ── Table API fallback (existing logic) ─────────────────────
|
|
653
765
|
if (!flowSysId) {
|
|
766
|
+
diagnostics.table_api_used = true;
|
|
654
767
|
var flowData: any = {
|
|
655
768
|
name: flowName,
|
|
656
769
|
description: flowDescription,
|
|
@@ -669,6 +782,40 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
669
782
|
var createdFlow = flowResponse.data.result;
|
|
670
783
|
flowSysId = createdFlow.sys_id;
|
|
671
784
|
|
|
785
|
+
// Create sys_hub_flow_version via Table API (critical for Flow Designer UI)
|
|
786
|
+
try {
|
|
787
|
+
var versionData: any = {
|
|
788
|
+
flow: flowSysId,
|
|
789
|
+
name: '1.0',
|
|
790
|
+
version: '1.0',
|
|
791
|
+
state: shouldActivate ? 'published' : 'draft',
|
|
792
|
+
active: true,
|
|
793
|
+
compile_state: 'compiled',
|
|
794
|
+
is_current: true,
|
|
795
|
+
flow_definition: JSON.stringify(flowDefinition)
|
|
796
|
+
};
|
|
797
|
+
if (shouldActivate) versionData.published_flow = flowSysId;
|
|
798
|
+
var versionResp = await client.post('/api/now/table/sys_hub_flow_version', versionData);
|
|
799
|
+
var versionSysId = versionResp.data.result?.sys_id;
|
|
800
|
+
if (versionSysId) {
|
|
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'];
|
|
805
|
+
// Link flow to its version
|
|
806
|
+
try {
|
|
807
|
+
await client.patch('/api/now/table/sys_hub_flow/' + flowSysId, {
|
|
808
|
+
latest_version: versionSysId
|
|
809
|
+
});
|
|
810
|
+
} catch (linkError) {
|
|
811
|
+
// Version exists but link failed — still better than no version
|
|
812
|
+
factoryWarnings.push('Version created but latest_version link failed');
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
} catch (verError: any) {
|
|
816
|
+
factoryWarnings.push('sys_hub_flow_version creation failed: ' + (verError.message || verError));
|
|
817
|
+
}
|
|
818
|
+
|
|
672
819
|
// Create trigger instance (non-manual flows only)
|
|
673
820
|
if (!isSubflow && triggerType !== 'manual') {
|
|
674
821
|
try {
|
|
@@ -775,7 +922,77 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
775
922
|
// Best-effort snapshot
|
|
776
923
|
try {
|
|
777
924
|
await client.post('/api/sn_flow_designer/flow/snapshot', { flow_id: flowSysId });
|
|
778
|
-
|
|
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
|
+
}
|
|
779
996
|
}
|
|
780
997
|
|
|
781
998
|
// ── Build summary ───────────────────────────────────────────
|
|
@@ -791,8 +1008,14 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
791
1008
|
.field('Status', shouldActivate ? 'Published (active)' : 'Draft')
|
|
792
1009
|
.field('Method', methodLabel);
|
|
793
1010
|
|
|
1011
|
+
if (diagnostics.factory_namespace) {
|
|
1012
|
+
createSummary.field('Namespace', diagnostics.factory_namespace);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
794
1015
|
if (versionCreated) {
|
|
795
|
-
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');
|
|
796
1019
|
}
|
|
797
1020
|
|
|
798
1021
|
if (!isSubflow && triggerType !== 'manual') {
|
|
@@ -809,6 +1032,24 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
809
1032
|
createSummary.warning(factoryWarnings[wi]);
|
|
810
1033
|
}
|
|
811
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
|
+
|
|
812
1053
|
return createSuccessResult({
|
|
813
1054
|
created: true,
|
|
814
1055
|
method: usedMethod,
|
|
@@ -830,7 +1071,8 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
830
1071
|
activities_created: actionsCreated,
|
|
831
1072
|
activities_requested: activitiesArg.length,
|
|
832
1073
|
variables_created: varsCreated,
|
|
833
|
-
warnings: factoryWarnings.length > 0 ? factoryWarnings : undefined
|
|
1074
|
+
warnings: factoryWarnings.length > 0 ? factoryWarnings : undefined,
|
|
1075
|
+
diagnostics: diagnostics
|
|
834
1076
|
}, {}, createSummary.build());
|
|
835
1077
|
}
|
|
836
1078
|
|
|
@@ -1183,5 +1425,5 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
1183
1425
|
}
|
|
1184
1426
|
}
|
|
1185
1427
|
|
|
1186
|
-
export const version = '
|
|
1428
|
+
export const version = '3.0.0';
|
|
1187
1429
|
export const author = 'Snow-Flow Team';
|