@sonisoft/now-sdk-ext-core 3.7.0 → 3.9.0
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/README.md +732 -732
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/sn/amb/AMBClient.js +1 -1
- package/dist/sn/amb/AMBClient.js.map +1 -1
- package/dist/sn/amb/ServerConnection.d.ts +1 -1
- package/dist/sn/amb/ServerConnection.js +23 -18
- package/dist/sn/amb/ServerConnection.js.map +1 -1
- package/dist/sn/amb/SubscriptionCommandSender.js +1 -1
- package/dist/sn/flow/FlowManager.d.ts +51 -2
- package/dist/sn/flow/FlowManager.js +425 -195
- package/dist/sn/flow/FlowManager.js.map +1 -1
- package/dist/sn/flow/FlowModels.d.ts +211 -0
- package/package.json +166 -166
|
@@ -537,6 +537,233 @@ export class FlowManager {
|
|
|
537
537
|
};
|
|
538
538
|
}
|
|
539
539
|
}
|
|
540
|
+
// ================================================================
|
|
541
|
+
// Flow Context Details API (ProcessFlow Operations)
|
|
542
|
+
// ================================================================
|
|
543
|
+
/**
|
|
544
|
+
* Get detailed flow execution context via the ProcessFlow operations API.
|
|
545
|
+
*
|
|
546
|
+
* Returns rich execution data including per-action timing, inputs, outputs,
|
|
547
|
+
* execution metadata (who ran it, test vs production, runtime, etc.), and
|
|
548
|
+
* optionally the full flow definition snapshot.
|
|
549
|
+
*
|
|
550
|
+
* This uses `GET /api/now/processflow/operations/flow/context/{id}` which is
|
|
551
|
+
* the same endpoint Flow Designer uses to display execution details.
|
|
552
|
+
*
|
|
553
|
+
* Note: The execution report (`flowReport`) requires operations view / flow
|
|
554
|
+
* logging to be enabled. If not available, `flowReportAvailabilityDetails`
|
|
555
|
+
* will contain information about why.
|
|
556
|
+
*
|
|
557
|
+
* @param contextId The sys_id of the flow context (from sys_flow_context)
|
|
558
|
+
* @param scope Optional scope sys_id for the transaction scope query parameter
|
|
559
|
+
* @param includeFlowDefinition Whether to include the full flow definition snapshot (default: false)
|
|
560
|
+
* @returns FlowContextDetailsResult with execution context and report
|
|
561
|
+
*/
|
|
562
|
+
async getFlowContextDetails(contextId, scope, includeFlowDefinition = false) {
|
|
563
|
+
this._validateContextId(contextId);
|
|
564
|
+
this._logger.info(`Getting flow context details: ${contextId}`);
|
|
565
|
+
const pfr = new ProcessFlowRequest(this._instance);
|
|
566
|
+
const query = scope ? { sysparm_transaction_scope: scope } : undefined;
|
|
567
|
+
try {
|
|
568
|
+
const response = await pfr.get('operations/flow/context/{context_id}', { context_id: contextId }, query);
|
|
569
|
+
const result = response?.data?.result ?? response?.bodyObject?.result;
|
|
570
|
+
if (!result) {
|
|
571
|
+
return {
|
|
572
|
+
success: false,
|
|
573
|
+
contextId,
|
|
574
|
+
errorMessage: 'Unexpected response structure from processflow operations API: no result field',
|
|
575
|
+
rawResponse: response
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
const flowContext = this._mapFlowContextInfo(result.flowContext);
|
|
579
|
+
const flowDef = result.flow;
|
|
580
|
+
const flowReport = this._mapFlowExecutionReport(result.flowReport, flowDef);
|
|
581
|
+
const reportAvailability = result.flowReportAvailabilityDetails;
|
|
582
|
+
this._logger.info(`Flow context details fetched: state=${flowContext?.state ?? 'unknown'}`);
|
|
583
|
+
return {
|
|
584
|
+
success: true,
|
|
585
|
+
contextId,
|
|
586
|
+
flowContext,
|
|
587
|
+
flowReport,
|
|
588
|
+
flowReportAvailabilityDetails: reportAvailability,
|
|
589
|
+
flowDefinition: includeFlowDefinition ? result.flow : undefined,
|
|
590
|
+
rawResponse: result
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
catch (error) {
|
|
594
|
+
const err = error;
|
|
595
|
+
this._logger.error(`Error fetching flow context details "${contextId}": ${err.message}`);
|
|
596
|
+
return {
|
|
597
|
+
success: false,
|
|
598
|
+
contextId,
|
|
599
|
+
errorMessage: `Failed to fetch flow context details: ${err.message}`
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
// ================================================================
|
|
604
|
+
// Flow Logs API (sys_flow_log Table)
|
|
605
|
+
// ================================================================
|
|
606
|
+
/**
|
|
607
|
+
* Retrieve flow execution logs from the sys_flow_log table.
|
|
608
|
+
*
|
|
609
|
+
* Returns log entries associated with a flow context, including error messages,
|
|
610
|
+
* step-level logs, and cancellation reasons. Log entries may be empty for
|
|
611
|
+
* simple successful executions.
|
|
612
|
+
*
|
|
613
|
+
* @param contextId The sys_id of the flow context to get logs for
|
|
614
|
+
* @param options Optional query options (limit, order direction)
|
|
615
|
+
* @returns FlowLogResult with array of log entries
|
|
616
|
+
*/
|
|
617
|
+
async getFlowLogs(contextId, options) {
|
|
618
|
+
this._validateContextId(contextId);
|
|
619
|
+
if (options?.limit !== undefined && (options.limit < 1 || !Number.isInteger(options.limit))) {
|
|
620
|
+
throw new Error('Limit must be a positive integer');
|
|
621
|
+
}
|
|
622
|
+
this._logger.info(`Getting flow logs for context: ${contextId}`);
|
|
623
|
+
const limit = options?.limit ?? 100;
|
|
624
|
+
const orderDir = options?.orderDirection ?? 'asc';
|
|
625
|
+
const orderBy = orderDir === 'desc' ? 'ORDERBYDESCorder' : 'ORDERBYorder';
|
|
626
|
+
const tableRequest = new TableAPIRequest(this._instance);
|
|
627
|
+
try {
|
|
628
|
+
const response = await tableRequest.get('sys_flow_log', {
|
|
629
|
+
sysparm_query: `context=${contextId}^${orderBy}`,
|
|
630
|
+
sysparm_fields: 'sys_id,level,message,action,operation,order,sys_created_on,sys_created_by',
|
|
631
|
+
sysparm_limit: String(limit)
|
|
632
|
+
});
|
|
633
|
+
const records = response?.data?.result ?? response?.bodyObject?.result ?? [];
|
|
634
|
+
const entries = records.map((r) => ({
|
|
635
|
+
sysId: r.sys_id,
|
|
636
|
+
level: r.level,
|
|
637
|
+
message: r.message,
|
|
638
|
+
action: r.action,
|
|
639
|
+
operation: r.operation,
|
|
640
|
+
order: r.order,
|
|
641
|
+
createdOn: r.sys_created_on,
|
|
642
|
+
createdBy: r.sys_created_by
|
|
643
|
+
}));
|
|
644
|
+
this._logger.info(`Flow logs fetched: ${entries.length} entries`);
|
|
645
|
+
return {
|
|
646
|
+
success: true,
|
|
647
|
+
contextId,
|
|
648
|
+
entries,
|
|
649
|
+
rawResponse: records
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
catch (error) {
|
|
653
|
+
const err = error;
|
|
654
|
+
this._logger.error(`Error fetching flow logs for "${contextId}": ${err.message}`);
|
|
655
|
+
return {
|
|
656
|
+
success: false,
|
|
657
|
+
contextId,
|
|
658
|
+
entries: [],
|
|
659
|
+
errorMessage: `Failed to fetch flow logs: ${err.message}`
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Map the raw flowContext object from the operations API to a typed FlowContextInfo.
|
|
665
|
+
* @internal
|
|
666
|
+
*/
|
|
667
|
+
_mapFlowContextInfo(raw) {
|
|
668
|
+
if (!raw)
|
|
669
|
+
return undefined;
|
|
670
|
+
const execSource = raw.executionSource;
|
|
671
|
+
return {
|
|
672
|
+
flowId: String(raw.flowId ?? ''),
|
|
673
|
+
name: String(raw.name ?? ''),
|
|
674
|
+
state: String(raw.state ?? ''),
|
|
675
|
+
runTime: String(raw.runTime ?? ''),
|
|
676
|
+
isTestRun: raw.isTestRun === true,
|
|
677
|
+
executedAs: String(raw.executedAs ?? ''),
|
|
678
|
+
flowInitiatedBy: String(raw.flowInitiatedBy ?? ''),
|
|
679
|
+
reporting: String(raw.reporting ?? ''),
|
|
680
|
+
debugMode: raw.debugMode === true,
|
|
681
|
+
executionSource: {
|
|
682
|
+
callingSource: execSource?.callingSource ?? '',
|
|
683
|
+
executionSourceTable: execSource?.executionSourceTable ?? '',
|
|
684
|
+
executionSourceRecord: execSource?.executionSourceRecord ?? '',
|
|
685
|
+
executionSourceRecordDisplay: execSource?.executionSourceRecordDisplay ?? ''
|
|
686
|
+
},
|
|
687
|
+
enableOpsViewExpansion: raw.enableOpsViewExpansion === true,
|
|
688
|
+
flowRetentionPolicyCandidate: raw.flowRetentionPolicyCandidate === true
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Map the raw flowReport object from the operations API to a typed FlowExecutionReport.
|
|
693
|
+
* Cross-references with the flow definition to resolve human-readable step names.
|
|
694
|
+
* @internal
|
|
695
|
+
*/
|
|
696
|
+
_mapFlowExecutionReport(raw, flowDef) {
|
|
697
|
+
if (!raw)
|
|
698
|
+
return undefined;
|
|
699
|
+
// Build a lookup from action instance ID → { actionTypeName, comment }
|
|
700
|
+
const actionLookup = this._buildActionInstanceLookup(flowDef);
|
|
701
|
+
const mapActionReports = (reports) => {
|
|
702
|
+
if (!reports)
|
|
703
|
+
return {};
|
|
704
|
+
const result = {};
|
|
705
|
+
for (const [key, report] of Object.entries(reports)) {
|
|
706
|
+
const lookup = actionLookup.get(key);
|
|
707
|
+
const actionTypeName = lookup?.actionTypeName;
|
|
708
|
+
const stepComment = lookup?.comment;
|
|
709
|
+
const stepLabel = actionTypeName
|
|
710
|
+
? (stepComment ? `${actionTypeName} (${stepComment})` : actionTypeName)
|
|
711
|
+
: (stepComment || undefined);
|
|
712
|
+
result[key] = {
|
|
713
|
+
fStepCount: String(report.fStepCount ?? ''),
|
|
714
|
+
actionName: String(report.actionName ?? ''),
|
|
715
|
+
instanceReference: String(report.instanceReference ?? ''),
|
|
716
|
+
stepLabel,
|
|
717
|
+
actionTypeName,
|
|
718
|
+
stepComment,
|
|
719
|
+
operationsCore: (report.operationsCore ?? { error: '', state: '', startTime: '', order: '', runTime: '' }),
|
|
720
|
+
relatedLinks: (report.relatedLinks ?? {}),
|
|
721
|
+
operationsOutput: (report.operationsOutput ?? { data: {} }),
|
|
722
|
+
operationsInput: (report.operationsInput ?? { data: {} }),
|
|
723
|
+
reportId: String(report.reportId ?? '')
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
return result;
|
|
727
|
+
};
|
|
728
|
+
return {
|
|
729
|
+
flowId: String(raw.flowId ?? ''),
|
|
730
|
+
domainSeparationEnabled: raw.domainSeparationEnabled === true,
|
|
731
|
+
executionDomain: String(raw.executionDomain ?? ''),
|
|
732
|
+
actionOperationsReports: mapActionReports(raw.actionOperationsReports),
|
|
733
|
+
subflowOperationsReports: mapActionReports(raw.subflowOperationsReports),
|
|
734
|
+
iterationOperationsReports: (raw.iterationOperationsReports ?? {}),
|
|
735
|
+
instanceReference: String(raw.instanceReference ?? ''),
|
|
736
|
+
operationsCore: (raw.operationsCore ?? { error: '', state: '', startTime: '', order: '', runTime: '' }),
|
|
737
|
+
relatedLinks: (raw.relatedLinks ?? {}),
|
|
738
|
+
operationsOutput: (raw.operationsOutput ?? { data: {} }),
|
|
739
|
+
operationsInput: (raw.operationsInput ?? { data: {} }),
|
|
740
|
+
reportId: String(raw.reportId ?? '')
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Build a lookup map from action instance ID to human-readable names
|
|
745
|
+
* by scanning the flow definition's actionInstances array.
|
|
746
|
+
* @internal
|
|
747
|
+
*/
|
|
748
|
+
_buildActionInstanceLookup(flowDef) {
|
|
749
|
+
const lookup = new Map();
|
|
750
|
+
if (!flowDef)
|
|
751
|
+
return lookup;
|
|
752
|
+
const actionInstances = flowDef.actionInstances;
|
|
753
|
+
if (!Array.isArray(actionInstances))
|
|
754
|
+
return lookup;
|
|
755
|
+
for (const instance of actionInstances) {
|
|
756
|
+
const id = instance.id;
|
|
757
|
+
if (!id)
|
|
758
|
+
continue;
|
|
759
|
+
const actionType = instance.actionType;
|
|
760
|
+
const actionTypeName = (actionType?.displayName ?? actionType?.name)
|
|
761
|
+
|| undefined;
|
|
762
|
+
const comment = instance.comment || undefined;
|
|
763
|
+
lookup.set(id, { actionTypeName, comment });
|
|
764
|
+
}
|
|
765
|
+
return lookup;
|
|
766
|
+
}
|
|
540
767
|
/**
|
|
541
768
|
* Extract the result from a ProcessFlow API response, handling both
|
|
542
769
|
* Axios-style (data.result) and RequestHandler-style (bodyObject.result) response shapes.
|
|
@@ -567,60 +794,60 @@ export class FlowManager {
|
|
|
567
794
|
}
|
|
568
795
|
const hasInputs = options.inputs && Object.keys(options.inputs).length > 0;
|
|
569
796
|
const inputsChain = hasInputs ? `\n .withInputs(inputs)` : '';
|
|
570
|
-
return `(function() {
|
|
571
|
-
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
572
|
-
try {
|
|
573
|
-
var inputs = ${inputsJson};
|
|
574
|
-
|
|
575
|
-
var result = sn_fd.FlowAPI.getRunner()
|
|
576
|
-
.${type}('${scopedName}')
|
|
577
|
-
.${modeMethod}()${optionalChain}${inputsChain}
|
|
578
|
-
.run();
|
|
579
|
-
|
|
580
|
-
var envelope = {
|
|
581
|
-
__flowResult: true,
|
|
582
|
-
success: true,
|
|
583
|
-
flowObjectName: '' + result.getFlowObjectName(),
|
|
584
|
-
flowObjectType: '' + result.getFlowObjectType(),
|
|
585
|
-
contextId: result.getContextId() ? '' + result.getContextId() : null,
|
|
586
|
-
executionDate: result.getDate() ? '' + result.getDate() : null,
|
|
587
|
-
domainId: result.getDomainId() ? '' + result.getDomainId() : null,
|
|
588
|
-
outputs: null,
|
|
589
|
-
debugOutput: '' + result.debug(),
|
|
590
|
-
errorMessage: null
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
try {
|
|
594
|
-
var rawOutputs = result.getOutputs();
|
|
595
|
-
if (rawOutputs) {
|
|
596
|
-
var outputObj = {};
|
|
597
|
-
for (var key in rawOutputs) {
|
|
598
|
-
if (rawOutputs.hasOwnProperty(key)) {
|
|
599
|
-
outputObj[key] = '' + rawOutputs[key];
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
envelope.outputs = outputObj;
|
|
603
|
-
}
|
|
604
|
-
} catch (outErr) {
|
|
605
|
-
envelope.outputs = null;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
gs.info(__RESULT_MARKER + JSON.stringify(envelope));
|
|
609
|
-
} catch (ex) {
|
|
610
|
-
var errorEnvelope = {
|
|
611
|
-
__flowResult: true,
|
|
612
|
-
success: false,
|
|
613
|
-
flowObjectName: '${scopedName}',
|
|
614
|
-
flowObjectType: '${type}',
|
|
615
|
-
contextId: null,
|
|
616
|
-
executionDate: null,
|
|
617
|
-
domainId: null,
|
|
618
|
-
outputs: null,
|
|
619
|
-
debugOutput: '',
|
|
620
|
-
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
621
|
-
};
|
|
622
|
-
gs.info(__RESULT_MARKER + JSON.stringify(errorEnvelope));
|
|
623
|
-
}
|
|
797
|
+
return `(function() {
|
|
798
|
+
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
799
|
+
try {
|
|
800
|
+
var inputs = ${inputsJson};
|
|
801
|
+
|
|
802
|
+
var result = sn_fd.FlowAPI.getRunner()
|
|
803
|
+
.${type}('${scopedName}')
|
|
804
|
+
.${modeMethod}()${optionalChain}${inputsChain}
|
|
805
|
+
.run();
|
|
806
|
+
|
|
807
|
+
var envelope = {
|
|
808
|
+
__flowResult: true,
|
|
809
|
+
success: true,
|
|
810
|
+
flowObjectName: '' + result.getFlowObjectName(),
|
|
811
|
+
flowObjectType: '' + result.getFlowObjectType(),
|
|
812
|
+
contextId: result.getContextId() ? '' + result.getContextId() : null,
|
|
813
|
+
executionDate: result.getDate() ? '' + result.getDate() : null,
|
|
814
|
+
domainId: result.getDomainId() ? '' + result.getDomainId() : null,
|
|
815
|
+
outputs: null,
|
|
816
|
+
debugOutput: '' + result.debug(),
|
|
817
|
+
errorMessage: null
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
try {
|
|
821
|
+
var rawOutputs = result.getOutputs();
|
|
822
|
+
if (rawOutputs) {
|
|
823
|
+
var outputObj = {};
|
|
824
|
+
for (var key in rawOutputs) {
|
|
825
|
+
if (rawOutputs.hasOwnProperty(key)) {
|
|
826
|
+
outputObj[key] = '' + rawOutputs[key];
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
envelope.outputs = outputObj;
|
|
830
|
+
}
|
|
831
|
+
} catch (outErr) {
|
|
832
|
+
envelope.outputs = null;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
gs.info(__RESULT_MARKER + JSON.stringify(envelope));
|
|
836
|
+
} catch (ex) {
|
|
837
|
+
var errorEnvelope = {
|
|
838
|
+
__flowResult: true,
|
|
839
|
+
success: false,
|
|
840
|
+
flowObjectName: '${scopedName}',
|
|
841
|
+
flowObjectType: '${type}',
|
|
842
|
+
contextId: null,
|
|
843
|
+
executionDate: null,
|
|
844
|
+
domainId: null,
|
|
845
|
+
outputs: null,
|
|
846
|
+
debugOutput: '',
|
|
847
|
+
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
848
|
+
};
|
|
849
|
+
gs.info(__RESULT_MARKER + JSON.stringify(errorEnvelope));
|
|
850
|
+
}
|
|
624
851
|
})();`;
|
|
625
852
|
}
|
|
626
853
|
/** Serialize inputs for embedding in the generated script. */
|
|
@@ -717,11 +944,14 @@ export class FlowManager {
|
|
|
717
944
|
// ================================================================
|
|
718
945
|
// Lifecycle Script Builders
|
|
719
946
|
// ================================================================
|
|
720
|
-
/** Validate that a context ID is non-empty. */
|
|
947
|
+
/** Validate that a context ID is a non-empty 32-character hex sys_id. */
|
|
721
948
|
_validateContextId(contextId) {
|
|
722
949
|
if (!contextId || contextId.trim().length === 0) {
|
|
723
950
|
throw new Error('Context ID is required');
|
|
724
951
|
}
|
|
952
|
+
if (!/^[0-9a-f]{32}$/i.test(contextId.trim())) {
|
|
953
|
+
throw new Error(`Invalid context ID format: "${contextId}". Expected a 32-character hex sys_id.`);
|
|
954
|
+
}
|
|
725
955
|
}
|
|
726
956
|
/** Escape a string for embedding in a generated SN script single-quoted string. */
|
|
727
957
|
_escapeForScript(str) {
|
|
@@ -730,149 +960,149 @@ export class FlowManager {
|
|
|
730
960
|
/** Build script to query sys_flow_context status. */
|
|
731
961
|
_buildContextStatusScript(contextId) {
|
|
732
962
|
const escapedId = this._escapeForScript(contextId);
|
|
733
|
-
return `(function() {
|
|
734
|
-
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
735
|
-
try {
|
|
736
|
-
var gr = new GlideRecord('sys_flow_context');
|
|
737
|
-
if (gr.get('${escapedId}')) {
|
|
738
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
739
|
-
__flowResult: true,
|
|
740
|
-
success: true,
|
|
741
|
-
contextId: '${escapedId}',
|
|
742
|
-
found: true,
|
|
743
|
-
state: '' + gr.getValue('state'),
|
|
744
|
-
name: '' + gr.getValue('name'),
|
|
745
|
-
started: gr.getValue('started') ? '' + gr.getValue('started') : null,
|
|
746
|
-
ended: gr.getValue('ended') ? '' + gr.getValue('ended') : null,
|
|
747
|
-
errorMessage: null
|
|
748
|
-
}));
|
|
749
|
-
} else {
|
|
750
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
751
|
-
__flowResult: true,
|
|
752
|
-
success: true,
|
|
753
|
-
contextId: '${escapedId}',
|
|
754
|
-
found: false,
|
|
755
|
-
state: null,
|
|
756
|
-
name: null,
|
|
757
|
-
started: null,
|
|
758
|
-
ended: null,
|
|
759
|
-
errorMessage: null
|
|
760
|
-
}));
|
|
761
|
-
}
|
|
762
|
-
} catch (ex) {
|
|
763
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
764
|
-
__flowResult: true,
|
|
765
|
-
success: false,
|
|
766
|
-
contextId: '${escapedId}',
|
|
767
|
-
found: false,
|
|
768
|
-
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
769
|
-
}));
|
|
770
|
-
}
|
|
963
|
+
return `(function() {
|
|
964
|
+
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
965
|
+
try {
|
|
966
|
+
var gr = new GlideRecord('sys_flow_context');
|
|
967
|
+
if (gr.get('${escapedId}')) {
|
|
968
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
969
|
+
__flowResult: true,
|
|
970
|
+
success: true,
|
|
971
|
+
contextId: '${escapedId}',
|
|
972
|
+
found: true,
|
|
973
|
+
state: '' + gr.getValue('state'),
|
|
974
|
+
name: '' + gr.getValue('name'),
|
|
975
|
+
started: gr.getValue('started') ? '' + gr.getValue('started') : null,
|
|
976
|
+
ended: gr.getValue('ended') ? '' + gr.getValue('ended') : null,
|
|
977
|
+
errorMessage: null
|
|
978
|
+
}));
|
|
979
|
+
} else {
|
|
980
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
981
|
+
__flowResult: true,
|
|
982
|
+
success: true,
|
|
983
|
+
contextId: '${escapedId}',
|
|
984
|
+
found: false,
|
|
985
|
+
state: null,
|
|
986
|
+
name: null,
|
|
987
|
+
started: null,
|
|
988
|
+
ended: null,
|
|
989
|
+
errorMessage: null
|
|
990
|
+
}));
|
|
991
|
+
}
|
|
992
|
+
} catch (ex) {
|
|
993
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
994
|
+
__flowResult: true,
|
|
995
|
+
success: false,
|
|
996
|
+
contextId: '${escapedId}',
|
|
997
|
+
found: false,
|
|
998
|
+
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
999
|
+
}));
|
|
1000
|
+
}
|
|
771
1001
|
})();`;
|
|
772
1002
|
}
|
|
773
1003
|
/** Build script to retrieve flow outputs via FlowAPI.getOutputs(). */
|
|
774
1004
|
_buildGetOutputsScript(contextId) {
|
|
775
1005
|
const escapedId = this._escapeForScript(contextId);
|
|
776
|
-
return `(function() {
|
|
777
|
-
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
778
|
-
try {
|
|
779
|
-
var outputs = sn_fd.FlowAPI.getOutputs('${escapedId}');
|
|
780
|
-
var outputObj = {};
|
|
781
|
-
if (outputs) {
|
|
782
|
-
for (var key in outputs) {
|
|
783
|
-
if (outputs.hasOwnProperty(key)) {
|
|
784
|
-
outputObj[key] = '' + outputs[key];
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
789
|
-
__flowResult: true,
|
|
790
|
-
success: true,
|
|
791
|
-
contextId: '${escapedId}',
|
|
792
|
-
outputs: outputObj,
|
|
793
|
-
errorMessage: null
|
|
794
|
-
}));
|
|
795
|
-
} catch (ex) {
|
|
796
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
797
|
-
__flowResult: true,
|
|
798
|
-
success: false,
|
|
799
|
-
contextId: '${escapedId}',
|
|
800
|
-
outputs: null,
|
|
801
|
-
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
802
|
-
}));
|
|
803
|
-
}
|
|
1006
|
+
return `(function() {
|
|
1007
|
+
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
1008
|
+
try {
|
|
1009
|
+
var outputs = sn_fd.FlowAPI.getOutputs('${escapedId}');
|
|
1010
|
+
var outputObj = {};
|
|
1011
|
+
if (outputs) {
|
|
1012
|
+
for (var key in outputs) {
|
|
1013
|
+
if (outputs.hasOwnProperty(key)) {
|
|
1014
|
+
outputObj[key] = '' + outputs[key];
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1019
|
+
__flowResult: true,
|
|
1020
|
+
success: true,
|
|
1021
|
+
contextId: '${escapedId}',
|
|
1022
|
+
outputs: outputObj,
|
|
1023
|
+
errorMessage: null
|
|
1024
|
+
}));
|
|
1025
|
+
} catch (ex) {
|
|
1026
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1027
|
+
__flowResult: true,
|
|
1028
|
+
success: false,
|
|
1029
|
+
contextId: '${escapedId}',
|
|
1030
|
+
outputs: null,
|
|
1031
|
+
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
1032
|
+
}));
|
|
1033
|
+
}
|
|
804
1034
|
})();`;
|
|
805
1035
|
}
|
|
806
1036
|
/** Build script to retrieve flow error via FlowAPI.getErrorMessage(). */
|
|
807
1037
|
_buildGetErrorScript(contextId) {
|
|
808
1038
|
const escapedId = this._escapeForScript(contextId);
|
|
809
|
-
return `(function() {
|
|
810
|
-
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
811
|
-
try {
|
|
812
|
-
var errorMsg = sn_fd.FlowAPI.getErrorMessage('${escapedId}');
|
|
813
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
814
|
-
__flowResult: true,
|
|
815
|
-
success: true,
|
|
816
|
-
contextId: '${escapedId}',
|
|
817
|
-
flowErrorMessage: errorMsg ? '' + errorMsg : null,
|
|
818
|
-
errorMessage: null
|
|
819
|
-
}));
|
|
820
|
-
} catch (ex) {
|
|
821
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
822
|
-
__flowResult: true,
|
|
823
|
-
success: false,
|
|
824
|
-
contextId: '${escapedId}',
|
|
825
|
-
flowErrorMessage: null,
|
|
826
|
-
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
827
|
-
}));
|
|
828
|
-
}
|
|
1039
|
+
return `(function() {
|
|
1040
|
+
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
1041
|
+
try {
|
|
1042
|
+
var errorMsg = sn_fd.FlowAPI.getErrorMessage('${escapedId}');
|
|
1043
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1044
|
+
__flowResult: true,
|
|
1045
|
+
success: true,
|
|
1046
|
+
contextId: '${escapedId}',
|
|
1047
|
+
flowErrorMessage: errorMsg ? '' + errorMsg : null,
|
|
1048
|
+
errorMessage: null
|
|
1049
|
+
}));
|
|
1050
|
+
} catch (ex) {
|
|
1051
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1052
|
+
__flowResult: true,
|
|
1053
|
+
success: false,
|
|
1054
|
+
contextId: '${escapedId}',
|
|
1055
|
+
flowErrorMessage: null,
|
|
1056
|
+
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
1057
|
+
}));
|
|
1058
|
+
}
|
|
829
1059
|
})();`;
|
|
830
1060
|
}
|
|
831
1061
|
/** Build script to cancel a flow via FlowAPI.cancel(). */
|
|
832
1062
|
_buildCancelScript(contextId, reason) {
|
|
833
1063
|
const escapedId = this._escapeForScript(contextId);
|
|
834
1064
|
const escapedReason = this._escapeForScript(reason);
|
|
835
|
-
return `(function() {
|
|
836
|
-
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
837
|
-
try {
|
|
838
|
-
sn_fd.FlowAPI.cancel('${escapedId}', '${escapedReason}');
|
|
839
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
840
|
-
__flowResult: true,
|
|
841
|
-
success: true,
|
|
842
|
-
contextId: '${escapedId}',
|
|
843
|
-
errorMessage: null
|
|
844
|
-
}));
|
|
845
|
-
} catch (ex) {
|
|
846
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
847
|
-
__flowResult: true,
|
|
848
|
-
success: false,
|
|
849
|
-
contextId: '${escapedId}',
|
|
850
|
-
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
851
|
-
}));
|
|
852
|
-
}
|
|
1065
|
+
return `(function() {
|
|
1066
|
+
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
1067
|
+
try {
|
|
1068
|
+
sn_fd.FlowAPI.cancel('${escapedId}', '${escapedReason}');
|
|
1069
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1070
|
+
__flowResult: true,
|
|
1071
|
+
success: true,
|
|
1072
|
+
contextId: '${escapedId}',
|
|
1073
|
+
errorMessage: null
|
|
1074
|
+
}));
|
|
1075
|
+
} catch (ex) {
|
|
1076
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1077
|
+
__flowResult: true,
|
|
1078
|
+
success: false,
|
|
1079
|
+
contextId: '${escapedId}',
|
|
1080
|
+
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
1081
|
+
}));
|
|
1082
|
+
}
|
|
853
1083
|
})();`;
|
|
854
1084
|
}
|
|
855
1085
|
/** Build script to publish a flow via FlowAPI.publish(). */
|
|
856
1086
|
_buildPublishScript(flowSysId) {
|
|
857
1087
|
const escapedId = this._escapeForScript(flowSysId);
|
|
858
|
-
return `(function() {
|
|
859
|
-
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
860
|
-
try {
|
|
861
|
-
sn_fd.FlowAPI.publish('${escapedId}');
|
|
862
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
863
|
-
__flowResult: true,
|
|
864
|
-
success: true,
|
|
865
|
-
flowSysId: '${escapedId}',
|
|
866
|
-
errorMessage: null
|
|
867
|
-
}));
|
|
868
|
-
} catch (ex) {
|
|
869
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
870
|
-
__flowResult: true,
|
|
871
|
-
success: false,
|
|
872
|
-
flowSysId: '${escapedId}',
|
|
873
|
-
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
874
|
-
}));
|
|
875
|
-
}
|
|
1088
|
+
return `(function() {
|
|
1089
|
+
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
1090
|
+
try {
|
|
1091
|
+
sn_fd.FlowAPI.publish('${escapedId}');
|
|
1092
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1093
|
+
__flowResult: true,
|
|
1094
|
+
success: true,
|
|
1095
|
+
flowSysId: '${escapedId}',
|
|
1096
|
+
errorMessage: null
|
|
1097
|
+
}));
|
|
1098
|
+
} catch (ex) {
|
|
1099
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1100
|
+
__flowResult: true,
|
|
1101
|
+
success: false,
|
|
1102
|
+
flowSysId: '${escapedId}',
|
|
1103
|
+
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
1104
|
+
}));
|
|
1105
|
+
}
|
|
876
1106
|
})();`;
|
|
877
1107
|
}
|
|
878
1108
|
/** Build script to send a message to a paused flow via FlowAPI.sendMessage(). */
|
|
@@ -880,24 +1110,24 @@ export class FlowManager {
|
|
|
880
1110
|
const escapedId = this._escapeForScript(contextId);
|
|
881
1111
|
const escapedMessage = this._escapeForScript(message);
|
|
882
1112
|
const escapedPayload = this._escapeForScript(payload);
|
|
883
|
-
return `(function() {
|
|
884
|
-
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
885
|
-
try {
|
|
886
|
-
sn_fd.FlowAPI.sendMessage('${escapedId}', '${escapedMessage}', '${escapedPayload}');
|
|
887
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
888
|
-
__flowResult: true,
|
|
889
|
-
success: true,
|
|
890
|
-
contextId: '${escapedId}',
|
|
891
|
-
errorMessage: null
|
|
892
|
-
}));
|
|
893
|
-
} catch (ex) {
|
|
894
|
-
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
895
|
-
__flowResult: true,
|
|
896
|
-
success: false,
|
|
897
|
-
contextId: '${escapedId}',
|
|
898
|
-
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
899
|
-
}));
|
|
900
|
-
}
|
|
1113
|
+
return `(function() {
|
|
1114
|
+
var __RESULT_MARKER = '${RESULT_MARKER}';
|
|
1115
|
+
try {
|
|
1116
|
+
sn_fd.FlowAPI.sendMessage('${escapedId}', '${escapedMessage}', '${escapedPayload}');
|
|
1117
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1118
|
+
__flowResult: true,
|
|
1119
|
+
success: true,
|
|
1120
|
+
contextId: '${escapedId}',
|
|
1121
|
+
errorMessage: null
|
|
1122
|
+
}));
|
|
1123
|
+
} catch (ex) {
|
|
1124
|
+
gs.info(__RESULT_MARKER + JSON.stringify({
|
|
1125
|
+
__flowResult: true,
|
|
1126
|
+
success: false,
|
|
1127
|
+
contextId: '${escapedId}',
|
|
1128
|
+
errorMessage: '' + (ex.getMessage ? ex.getMessage() : ex)
|
|
1129
|
+
}));
|
|
1130
|
+
}
|
|
901
1131
|
})();`;
|
|
902
1132
|
}
|
|
903
1133
|
}
|