@servicenow/sdk-build-plugins 4.5.0 → 4.6.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/dist/column-plugin.js +3 -7
- package/dist/column-plugin.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-diagnostics.js +5 -5
- package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -1
- package/dist/flow/plugins/flow-action-definition-plugin.js +1229 -54
- package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-data-pill-plugin.js +5 -2
- package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-definition-plugin.js +16 -42
- package/dist/flow/plugins/flow-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-diagnostics-plugin.d.ts +2 -2
- package/dist/flow/plugins/flow-diagnostics-plugin.js +2 -2
- package/dist/flow/plugins/flow-instance-plugin.js +68 -22
- package/dist/flow/plugins/flow-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/step-definition-plugin.js +2 -1
- package/dist/flow/plugins/step-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/step-instance-plugin.d.ts +9 -1
- package/dist/flow/plugins/step-instance-plugin.js +649 -136
- package/dist/flow/plugins/step-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/wfa-datapill-plugin.js +20 -5
- package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -1
- package/dist/flow/post-install.js +1 -0
- package/dist/flow/post-install.js.map +1 -1
- package/dist/flow/utils/complex-object-resolver.js +4 -1
- package/dist/flow/utils/complex-object-resolver.js.map +1 -1
- package/dist/flow/utils/complex-objects.js +1 -1
- package/dist/flow/utils/complex-objects.js.map +1 -1
- package/dist/flow/utils/flow-constants.d.ts +66 -2
- package/dist/flow/utils/flow-constants.js +402 -6
- package/dist/flow/utils/flow-constants.js.map +1 -1
- package/dist/flow/utils/flow-io-to-record.d.ts +1 -1
- package/dist/flow/utils/flow-io-to-record.js +37 -16
- package/dist/flow/utils/flow-io-to-record.js.map +1 -1
- package/dist/flow/utils/flow-shapes.js +4 -0
- package/dist/flow/utils/flow-shapes.js.map +1 -1
- package/dist/flow/utils/label-cache-parser.d.ts +9 -2
- package/dist/flow/utils/label-cache-parser.js +32 -4
- package/dist/flow/utils/label-cache-parser.js.map +1 -1
- package/dist/flow/utils/pill-shape-helpers.d.ts +15 -0
- package/dist/flow/utils/pill-shape-helpers.js +35 -0
- package/dist/flow/utils/pill-shape-helpers.js.map +1 -0
- package/dist/flow/utils/pill-string-parser.js +1 -0
- package/dist/flow/utils/pill-string-parser.js.map +1 -1
- package/dist/flow/utils/schema-to-flow-object.d.ts +6 -1
- package/dist/flow/utils/schema-to-flow-object.js +131 -15
- package/dist/flow/utils/schema-to-flow-object.js.map +1 -1
- package/dist/flow/utils/utils.d.ts +1 -0
- package/dist/flow/utils/utils.js +6 -1
- package/dist/flow/utils/utils.js.map +1 -1
- package/dist/form-plugin.js +7 -9
- package/dist/form-plugin.js.map +1 -1
- package/dist/inbound-email-action-plugin.d.ts +10 -0
- package/dist/inbound-email-action-plugin.js +128 -0
- package/dist/inbound-email-action-plugin.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/instance-scan-plugin.js +0 -5
- package/dist/instance-scan-plugin.js.map +1 -1
- package/dist/property-plugin.js +1 -1
- package/dist/property-plugin.js.map +1 -1
- package/dist/record-plugin.d.ts +7 -0
- package/dist/record-plugin.js +10 -2
- package/dist/record-plugin.js.map +1 -1
- package/dist/rest-api-plugin.js +8 -1
- package/dist/rest-api-plugin.js.map +1 -1
- package/dist/schedule-script/scheduled-script-plugin.js +8 -3
- package/dist/schedule-script/scheduled-script-plugin.js.map +1 -1
- package/dist/service-catalog/service-catalog-base.d.ts +18 -18
- package/dist/service-catalog/service-catalog-base.js +22 -22
- package/dist/service-catalog/service-catalog-base.js.map +1 -1
- package/dist/service-portal/header-footer-plugin.d.ts +2 -0
- package/dist/service-portal/header-footer-plugin.js +50 -0
- package/dist/service-portal/header-footer-plugin.js.map +1 -0
- package/dist/service-portal/menu-plugin.js +3 -22
- package/dist/service-portal/menu-plugin.js.map +1 -1
- package/dist/service-portal/page-plugin.js +3 -24
- package/dist/service-portal/page-plugin.js.map +1 -1
- package/dist/service-portal/page-route-map-plugin.d.ts +2 -0
- package/dist/service-portal/page-route-map-plugin.js +114 -0
- package/dist/service-portal/page-route-map-plugin.js.map +1 -0
- package/dist/service-portal/portal-plugin.js +21 -8
- package/dist/service-portal/portal-plugin.js.map +1 -1
- package/dist/service-portal/utils.d.ts +40 -2
- package/dist/service-portal/utils.js +283 -2
- package/dist/service-portal/utils.js.map +1 -1
- package/dist/service-portal/widget-plugin.js +9 -218
- package/dist/service-portal/widget-plugin.js.map +1 -1
- package/dist/static-content-plugin.js +4 -0
- package/dist/static-content-plugin.js.map +1 -1
- package/dist/table-plugin.js +190 -26
- package/dist/table-plugin.js.map +1 -1
- package/dist/ui-action-plugin.js +1 -4
- package/dist/ui-action-plugin.js.map +1 -1
- package/dist/ui-page-plugin.js +68 -13
- package/dist/ui-page-plugin.js.map +1 -1
- package/dist/view-plugin.js +8 -3
- package/dist/view-plugin.js.map +1 -1
- package/dist/workspace-plugin.js +39 -36
- package/dist/workspace-plugin.js.map +1 -1
- package/package.json +5 -4
- package/src/column-plugin.ts +3 -8
- package/src/flow/flow-logic/flow-logic-diagnostics.ts +5 -6
- package/src/flow/plugins/flow-action-definition-plugin.ts +1581 -61
- package/src/flow/plugins/flow-data-pill-plugin.ts +5 -2
- package/src/flow/plugins/flow-definition-plugin.ts +12 -47
- package/src/flow/plugins/flow-diagnostics-plugin.ts +2 -2
- package/src/flow/plugins/flow-instance-plugin.ts +98 -22
- package/src/flow/plugins/step-definition-plugin.ts +2 -1
- package/src/flow/plugins/step-instance-plugin.ts +772 -156
- package/src/flow/plugins/wfa-datapill-plugin.ts +25 -5
- package/src/flow/post-install.ts +1 -0
- package/src/flow/utils/complex-object-resolver.ts +4 -1
- package/src/flow/utils/complex-objects.ts +1 -1
- package/src/flow/utils/flow-constants.ts +421 -5
- package/src/flow/utils/flow-io-to-record.ts +43 -17
- package/src/flow/utils/flow-shapes.ts +4 -0
- package/src/flow/utils/label-cache-parser.ts +33 -4
- package/src/flow/utils/pill-shape-helpers.ts +42 -0
- package/src/flow/utils/pill-string-parser.ts +1 -0
- package/src/flow/utils/schema-to-flow-object.ts +183 -15
- package/src/flow/utils/utils.ts +12 -1
- package/src/form-plugin.ts +1 -3
- package/src/inbound-email-action-plugin.ts +145 -0
- package/src/index.ts +4 -0
- package/src/instance-scan-plugin.ts +0 -5
- package/src/property-plugin.ts +4 -1
- package/src/record-plugin.ts +14 -4
- package/src/rest-api-plugin.ts +7 -1
- package/src/schedule-script/scheduled-script-plugin.ts +14 -3
- package/src/service-catalog/service-catalog-base.ts +22 -22
- package/src/service-portal/header-footer-plugin.ts +57 -0
- package/src/service-portal/menu-plugin.ts +1 -23
- package/src/service-portal/page-plugin.ts +3 -28
- package/src/service-portal/page-route-map-plugin.ts +124 -0
- package/src/service-portal/portal-plugin.ts +33 -10
- package/src/service-portal/utils.ts +404 -3
- package/src/service-portal/widget-plugin.ts +14 -290
- package/src/static-content-plugin.ts +3 -0
- package/src/table-plugin.ts +226 -36
- package/src/ui-action-plugin.ts +1 -8
- package/src/ui-page-plugin.ts +76 -13
- package/src/view-plugin.ts +10 -4
- package/src/workspace-plugin.ts +43 -43
|
@@ -91,10 +91,13 @@ export function determineRootIdentifierAndPath(
|
|
|
91
91
|
let pathStr = ''
|
|
92
92
|
|
|
93
93
|
switch (propertyNames[1]) {
|
|
94
|
-
case 'inputs':
|
|
95
|
-
|
|
94
|
+
case 'inputs': {
|
|
95
|
+
// Detect if inside Action() body → emit {{action.xxx}}, otherwise {{subflow.xxx}}
|
|
96
|
+
const actionAncestor = findAncestorByCalleeName(propertyAccessShape.getOriginalNode(), 'Action')
|
|
97
|
+
rootIdentifier = actionAncestor ? 'action' : 'subflow'
|
|
96
98
|
pathStr = propertyNames.slice(2).join('.')
|
|
97
99
|
break
|
|
100
|
+
}
|
|
98
101
|
case 'flowVariables':
|
|
99
102
|
// For params.flowVariables (schema reference), use 'flowVariables' as identifier with empty path
|
|
100
103
|
// For params.flowVariables.someVar (property access), use 'flow_variable' as identifier
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
type Diagnostics,
|
|
18
18
|
ts,
|
|
19
19
|
deleteMultipleDiff,
|
|
20
|
-
StringLiteralShape,
|
|
21
20
|
type Logger,
|
|
22
21
|
} from '@servicenow/sdk-build-core'
|
|
23
22
|
import { gzipSync } from 'node:zlib'
|
|
@@ -55,6 +54,7 @@ import {
|
|
|
55
54
|
createPropertyAccessFromPath,
|
|
56
55
|
} from '../utils/pill-string-parser'
|
|
57
56
|
import { isDataPill } from '../utils/complex-object-resolver'
|
|
57
|
+
import { wrapWithDataPillCall, extractDataPillNames } from '../utils/pill-shape-helpers'
|
|
58
58
|
import { ArrayShape } from '@servicenow/sdk-build-core'
|
|
59
59
|
import { processFlowInputs, processFlowOutputs, processFlowVariables } from '../utils/flow-variable-processor'
|
|
60
60
|
import { buildUuidToIdentifierMap, processInstanceForDatapills, uuidToRecordMap } from '../utils/datapill-transformer'
|
|
@@ -211,7 +211,7 @@ import { ApprovalDueDateShape, ApprovalRulesShape } from '../utils/flow-shapes'
|
|
|
211
211
|
|
|
212
212
|
/**
|
|
213
213
|
* Traverse ancestors to find the topmost ArrowFunction and extract its parameter name
|
|
214
|
-
* This finds the ArrowFunction that's an argument to Flow/
|
|
214
|
+
* This finds the ArrowFunction that's an argument to Flow/Subflow, ignoring nested
|
|
215
215
|
* ArrowFunctions from control flow APIs like If, ElseIf, ForEach.
|
|
216
216
|
*
|
|
217
217
|
* @param shape - The shape to start traversing from
|
|
@@ -446,45 +446,6 @@ function processShapeForDatapills(
|
|
|
446
446
|
* @param dataType - The data type string (default: 'string')
|
|
447
447
|
* @returns CallExpressionShape wrapping the expression with wfa.dataPill()
|
|
448
448
|
*/
|
|
449
|
-
function wrapWithDataPillCall(
|
|
450
|
-
expression: PropertyAccessShape | IdentifierShape,
|
|
451
|
-
source: Record,
|
|
452
|
-
dataType = 'string'
|
|
453
|
-
): CallExpressionShape {
|
|
454
|
-
return new CallExpressionShape({
|
|
455
|
-
source,
|
|
456
|
-
callee: 'wfa.dataPill',
|
|
457
|
-
args: [expression, new StringLiteralShape({ source, literalText: dataType })],
|
|
458
|
-
})
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Extract all datapill names from a string value containing datapill patterns
|
|
463
|
-
* Handles both UUID-based pills ({{uuid.property}}) and semantic pills ({{prefix.path}})
|
|
464
|
-
*
|
|
465
|
-
* @param stringValue - String that may contain datapill patterns
|
|
466
|
-
* @returns Array of datapill names (e.g., ["trigger.table_name", "uuid.record.number"])
|
|
467
|
-
*/
|
|
468
|
-
function extractDataPillNames(stringValue: string): string[] {
|
|
469
|
-
const dataPillNames: string[] = []
|
|
470
|
-
|
|
471
|
-
// Match all datapill patterns: {{...}}
|
|
472
|
-
const pillPattern = /\{\{([^}]+)\}\}/g
|
|
473
|
-
const matches = Array.from(stringValue.matchAll(pillPattern))
|
|
474
|
-
|
|
475
|
-
for (const match of matches) {
|
|
476
|
-
if (match[1]) {
|
|
477
|
-
// Extract the content inside {{}} and split by | to get just the name part
|
|
478
|
-
// (some pills may have type info like {{pill.name|string}})
|
|
479
|
-
const pillContent = match[1].split('|')[0]
|
|
480
|
-
if (pillContent) {
|
|
481
|
-
dataPillNames.push(pillContent)
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
return dataPillNames
|
|
487
|
-
}
|
|
488
449
|
|
|
489
450
|
/**
|
|
490
451
|
* Wrap all PropertyAccessShape expressions in a TemplateExpressionShape with wfa.dataPill()
|
|
@@ -615,16 +576,17 @@ function extractAllPills(
|
|
|
615
576
|
const pipeIndex = content.indexOf('|')
|
|
616
577
|
const cleanContent = pipeIndex !== -1 ? content.substring(0, pipeIndex) : content
|
|
617
578
|
|
|
618
|
-
//
|
|
619
|
-
//
|
|
579
|
+
// Match UUID-based pills: both bare UUID (action/subflow outputs) and step[UUID] (action step outputs)
|
|
580
|
+
// Bare: {{uuid.property}} → e.g., action/subflow instance output
|
|
581
|
+
// Step: {{step[uuid].property}} → e.g., action step output
|
|
620
582
|
const uuidMatch = cleanContent.match(
|
|
621
|
-
/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.([a-zA-Z_][a-zA-Z0-9_.]*[a-zA-Z0-9_])$/
|
|
583
|
+
/^(?:step\[([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\]|([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}))\.([a-zA-Z_][a-zA-Z0-9_.]*[a-zA-Z0-9_])$/
|
|
622
584
|
)
|
|
623
585
|
|
|
624
586
|
if (uuidMatch) {
|
|
625
587
|
// This is a UUID-based pill
|
|
626
|
-
const uuid = uuidMatch[1]
|
|
627
|
-
const property = uuidMatch[
|
|
588
|
+
const uuid = uuidMatch[1] ?? uuidMatch[2]
|
|
589
|
+
const property = uuidMatch[3]
|
|
628
590
|
|
|
629
591
|
if (!uuid || !property) {
|
|
630
592
|
continue
|
|
@@ -633,7 +595,10 @@ function extractAllPills(
|
|
|
633
595
|
const identifier = uuidToIdentifierMap.get(uuid)
|
|
634
596
|
|
|
635
597
|
if (identifier) {
|
|
636
|
-
// PRESERVE EXISTING LOGIC: Apply forEach parameter handling
|
|
598
|
+
// PRESERVE EXISTING LOGIC: Apply forEach parameter handling.
|
|
599
|
+
// Note: With the consolidated regex, this is now called for step[UUID] pills too
|
|
600
|
+
// (previously only bare UUID pills hit this code). This is harmless since action
|
|
601
|
+
// step CIDs are never forEach parameters, so isForEachParam will always be false.
|
|
637
602
|
const isForEachParam = isForEachParameter(identifier, uuid)
|
|
638
603
|
let expression: PropertyAccessShape | IdentifierShape
|
|
639
604
|
|
|
@@ -90,8 +90,8 @@ function isInsideFlowContext(node: ts.Node): boolean {
|
|
|
90
90
|
* - wfa.flowLogic.goBackTo
|
|
91
91
|
* - wfa.flowLogic.tryCatch
|
|
92
92
|
* - wfa.flowLogic.doInParallel
|
|
93
|
-
* - FlowObject (must be within Flow/Subflow/
|
|
94
|
-
* - FlowArray (must be within Flow/Subflow/
|
|
93
|
+
* - FlowObject (must be within Flow/Subflow/Action/TriggerDefinition)
|
|
94
|
+
* - FlowArray (must be within Flow/Subflow/Action/TriggerDefinition)
|
|
95
95
|
*/
|
|
96
96
|
export const FlowDiagnosticsPlugin = Plugin.create({
|
|
97
97
|
name: 'FlowDiagnosticsPlugin',
|
|
@@ -166,10 +166,13 @@ export function normalizeInputValue(value: string, uiType?: string, source?: Sou
|
|
|
166
166
|
// Create a StringShape from the value and use ApprovalRulesShape.from() to parse it
|
|
167
167
|
return ApprovalRulesShape.from(source, Shape.from(source, value).asString())
|
|
168
168
|
} else if (uiType === APPROVAL_DUE_DATE_DATA_TYPE_VALUE) {
|
|
169
|
-
// Check if source is a Record before accessing action_type
|
|
169
|
+
// Check if source is a Record before accessing action_type or step_type.
|
|
170
|
+
// Flow context uses action_type; action definition context uses step_type.
|
|
170
171
|
if (source instanceof Record) {
|
|
171
172
|
const actionType = source.get(ACTION_TYPE_KEY_NAME)?.ifDefined()?.asString()?.getValue()
|
|
172
|
-
|
|
173
|
+
const stepType = source.get('step_type')?.ifDefined()?.asString()?.getValue()
|
|
174
|
+
const typeId = actionType ?? stepType
|
|
175
|
+
if (typeId && APPROVAL_DUE_DATE_INPUT_FIELD_ACTIONS.includes(typeId)) {
|
|
173
176
|
// Create a StringShape from the value and use ApprovalDueDateShape.from() to parse it
|
|
174
177
|
return ApprovalDueDateShape.from(source, Shape.from(source, value).asString())
|
|
175
178
|
}
|
|
@@ -277,10 +280,6 @@ function buildInstanceToShape({
|
|
|
277
280
|
}
|
|
278
281
|
|
|
279
282
|
const coreActionIdentifier = getCoreActionIdentifier(sysId)
|
|
280
|
-
if (callee === ACTION_INSTANCE_API_NAME && !coreActionIdentifier) {
|
|
281
|
-
logger.warn(`Custom actions are not supported, action = ${sysId}`)
|
|
282
|
-
return { success: false }
|
|
283
|
-
}
|
|
284
283
|
|
|
285
284
|
const action = database
|
|
286
285
|
.query('sys_hub_action_type_definition')
|
|
@@ -327,13 +326,12 @@ function buildInstanceToShape({
|
|
|
327
326
|
if (inputsShape === undefined) {
|
|
328
327
|
return { success: false as const }
|
|
329
328
|
}
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (waitForCompletion) {
|
|
329
|
+
const waitForCompletionValue = record.get('wait_for_completion')?.getValue()
|
|
330
|
+
const isWaitForCompletionFalse = waitForCompletionValue === false || waitForCompletionValue === 'false'
|
|
331
|
+
if (isWaitForCompletionFalse) {
|
|
334
332
|
inputsShape = inputsShape
|
|
335
|
-
? inputsShape.merge({ waitForCompletion })
|
|
336
|
-
: Shape.from(record, { waitForCompletion }).asObject()
|
|
333
|
+
? inputsShape.merge({ waitForCompletion: false })
|
|
334
|
+
: Shape.from(record, { waitForCompletion: false }).asObject()
|
|
337
335
|
}
|
|
338
336
|
|
|
339
337
|
const configArg = new ObjectShape({
|
|
@@ -533,6 +531,7 @@ export const FlowInstancePlugin = Plugin.create({
|
|
|
533
531
|
factory,
|
|
534
532
|
source: callExpression,
|
|
535
533
|
transform,
|
|
534
|
+
diagnostics,
|
|
536
535
|
})
|
|
537
536
|
}
|
|
538
537
|
|
|
@@ -728,6 +727,7 @@ async function buildActionInstance({
|
|
|
728
727
|
const values = actionDef
|
|
729
728
|
? await prepareActionInstanceValueJson(inputs, actionDef, transform, logger, diagnostics)
|
|
730
729
|
: undefined
|
|
730
|
+
|
|
731
731
|
const actionDefRecord = actionDef instanceof Record ? actionDef : undefined
|
|
732
732
|
const instanceProps = inputs.transform(({ $ }) => ({
|
|
733
733
|
active: $.val(true),
|
|
@@ -767,6 +767,7 @@ async function buildSubflowInstance({
|
|
|
767
767
|
uuid,
|
|
768
768
|
source,
|
|
769
769
|
transform,
|
|
770
|
+
diagnostics,
|
|
770
771
|
}: {
|
|
771
772
|
subflowDef: Record | StringShape | undefined
|
|
772
773
|
inputs: ObjectShape
|
|
@@ -776,8 +777,11 @@ async function buildSubflowInstance({
|
|
|
776
777
|
uuid: string | undefined
|
|
777
778
|
source: Source
|
|
778
779
|
transform: Transform
|
|
780
|
+
diagnostics: Diagnostics
|
|
779
781
|
}): Promise<Record | undefined> {
|
|
780
|
-
const values = subflowDef
|
|
782
|
+
const values = subflowDef
|
|
783
|
+
? await prepareSubflowInstanceValueJson(inputs, subflowDef, transform, diagnostics)
|
|
784
|
+
: undefined
|
|
781
785
|
|
|
782
786
|
const subflowDefRecord = subflowDef instanceof Record ? subflowDef : undefined
|
|
783
787
|
const instanceProps = inputs.transform(({ $ }) => ({
|
|
@@ -789,7 +793,7 @@ async function buildSubflowInstance({
|
|
|
789
793
|
generation_source: $.val(''),
|
|
790
794
|
subflow: $.val(subflowDefRecord?.getId()?.getValue() || subflowDef?.getValue() || ''),
|
|
791
795
|
subflow_inputs: $.val(values),
|
|
792
|
-
wait_for_completion: $.from('waitForCompletion').def(
|
|
796
|
+
wait_for_completion: $.from('waitForCompletion').def(true),
|
|
793
797
|
sys_class_name: $.val('sys_hub_sub_flow_instance_v2'),
|
|
794
798
|
parent_ui_id: $.def(''),
|
|
795
799
|
}))
|
|
@@ -1052,6 +1056,61 @@ function processDefaultOrHiddenInput(
|
|
|
1052
1056
|
return undefined
|
|
1053
1057
|
}
|
|
1054
1058
|
|
|
1059
|
+
/**
|
|
1060
|
+
* Validates mandatory fields on raw shapes before datapill or inline script resolution. Only `StringShape`
|
|
1061
|
+
* values are validated for emptiness. Runtime-evaluated shapes (data pills, template expressions, inline
|
|
1062
|
+
* scripts, identifiers) are exempt because their values cannot be determined at build time.
|
|
1063
|
+
*
|
|
1064
|
+
* @param definition - The action or subflow definition record containing input definitions.
|
|
1065
|
+
* @param instanceInputs - The raw ObjectShape of user-provided input values before resolution.
|
|
1066
|
+
* @param diagnostics - Diagnostics instance for reporting validation errors.
|
|
1067
|
+
* @param inputTable - The table name for input definitions (e.g., 'sys_hub_action_input' or 'sys_hub_flow_input').
|
|
1068
|
+
* @param definitionName - Optional name of the action or subflow for more specific error messages.
|
|
1069
|
+
* @returns The filtered input definition records for reuse, or undefined if no definition.
|
|
1070
|
+
*/
|
|
1071
|
+
function validateMandatoryFields(
|
|
1072
|
+
definition: Record | undefined,
|
|
1073
|
+
instanceInputs: ObjectShape,
|
|
1074
|
+
diagnostics: Diagnostics,
|
|
1075
|
+
inputTable: string,
|
|
1076
|
+
definitionName?: string
|
|
1077
|
+
): Record[] | undefined {
|
|
1078
|
+
const inputDefinitions = definition
|
|
1079
|
+
? definition.flat().filter((record) => record.getTable() === inputTable)
|
|
1080
|
+
: undefined
|
|
1081
|
+
|
|
1082
|
+
if (inputDefinitions) {
|
|
1083
|
+
const rawEntries = new Map(instanceInputs.entries({ resolve: false }))
|
|
1084
|
+
|
|
1085
|
+
for (const inputDefinition of inputDefinitions) {
|
|
1086
|
+
const inputName = inputDefinition.get('element')?.asString()?.getValue() ?? ''
|
|
1087
|
+
if (!inputName) {
|
|
1088
|
+
continue
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
const isMandatory = inputDefinition.get('mandatory')?.ifBoolean()?.getValue() ?? false
|
|
1092
|
+
if (!isMandatory) {
|
|
1093
|
+
continue
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
const rawShape = rawEntries.get(inputName)
|
|
1097
|
+
if (!rawShape) {
|
|
1098
|
+
continue
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
if (rawShape.isString() && rawShape.isEmpty()) {
|
|
1102
|
+
const context = definitionName ? ` in action '${definitionName}'` : ''
|
|
1103
|
+
diagnostics.error(
|
|
1104
|
+
rawShape,
|
|
1105
|
+
`Mandatory field '${inputName}'${context} cannot be an empty string. Please provide a non-empty value.`
|
|
1106
|
+
)
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
return inputDefinitions
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1055
1114
|
/**
|
|
1056
1115
|
* Resolve a catalog item record from a Shape (direct Record, TemplateExpressionShape, or IdentifierShape).
|
|
1057
1116
|
*/
|
|
@@ -1237,14 +1296,24 @@ async function prepareActionInstanceValueJson(
|
|
|
1237
1296
|
}
|
|
1238
1297
|
const isActionDefString = actionDef instanceof StringShape
|
|
1239
1298
|
|
|
1299
|
+
// Resolve action name early for use in validation messages and special handling
|
|
1300
|
+
const actionSysId = actionDefRecord?.getId()?.getValue()
|
|
1301
|
+
const actionName = typeof actionSysId === 'string' ? CORE_ACTIONS_SYS_ID_NAME_MAP[actionSysId] : undefined
|
|
1302
|
+
|
|
1303
|
+
const definitionInputs = validateMandatoryFields(
|
|
1304
|
+
actionDefRecord,
|
|
1305
|
+
instanceInputs,
|
|
1306
|
+
diagnostics,
|
|
1307
|
+
'sys_hub_action_input',
|
|
1308
|
+
actionName
|
|
1309
|
+
)
|
|
1310
|
+
|
|
1240
1311
|
// Special handling for getCatalogVariables action
|
|
1241
1312
|
let overrideValues = new Map<string, string>()
|
|
1242
1313
|
let displayValues = new Map<string, string>()
|
|
1243
1314
|
let unsupportedFieldsForAction: string[] | undefined
|
|
1244
1315
|
|
|
1245
1316
|
if (actionDefRecord) {
|
|
1246
|
-
const actionSysId = actionDefRecord.getId().getValue()
|
|
1247
|
-
const actionName = typeof actionSysId === 'string' ? CORE_ACTIONS_SYS_ID_NAME_MAP[actionSysId] : undefined
|
|
1248
1317
|
unsupportedFieldsForAction = actionName ? INLINE_SCRIPT_UNSUPPORTED_FIELDS[actionName] : undefined
|
|
1249
1318
|
|
|
1250
1319
|
// Check if this is the getCatalogVariables action or createCatalogTask action
|
|
@@ -1287,9 +1356,8 @@ async function prepareActionInstanceValueJson(
|
|
|
1287
1356
|
|
|
1288
1357
|
// When isActionDefString is true, there's no action definition in fluent
|
|
1289
1358
|
// We expect arbitrary inputs and should process all provided inputs directly
|
|
1290
|
-
if (actionDefRecord) {
|
|
1291
|
-
// When action definition record is present, process only definition inputs
|
|
1292
|
-
const definitionInputs = actionDefRecord.flat().filter((v) => v.getTable() === 'sys_hub_action_input')
|
|
1359
|
+
if (actionDefRecord && definitionInputs) {
|
|
1360
|
+
// When action definition record is present, process only the definition inputs.
|
|
1293
1361
|
const providedInputNames = new Set(objShape.keys())
|
|
1294
1362
|
|
|
1295
1363
|
for (const inputDef of definitionInputs) {
|
|
@@ -1351,8 +1419,15 @@ async function prepareActionInstanceValueJson(
|
|
|
1351
1419
|
async function prepareSubflowInstanceValueJson(
|
|
1352
1420
|
instanceInputs: ObjectShape,
|
|
1353
1421
|
subflowDef: Record | StringShape,
|
|
1354
|
-
transform: Transform
|
|
1422
|
+
transform: Transform,
|
|
1423
|
+
diagnostics: Diagnostics
|
|
1355
1424
|
) {
|
|
1425
|
+
const subflowDefRecord = subflowDef.isRecord() ? subflowDef.as(Record) : undefined
|
|
1426
|
+
const subflowName = subflowDefRecord?.get('name')?.ifString()?.getValue()
|
|
1427
|
+
|
|
1428
|
+
// Validate mandatory fields on raw shapes before any resolution.
|
|
1429
|
+
validateMandatoryFields(subflowDefRecord, instanceInputs, diagnostics, 'sys_hub_flow_input', subflowName)
|
|
1430
|
+
|
|
1356
1431
|
// Check for datapills and resolve them
|
|
1357
1432
|
const dataPillResults = await checkAndResolveDataPills(instanceInputs, transform)
|
|
1358
1433
|
|
|
@@ -1386,8 +1461,9 @@ async function prepareSubflowInstanceValueJson(
|
|
|
1386
1461
|
value: primitiveValue,
|
|
1387
1462
|
internalType: undefined,
|
|
1388
1463
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1464
|
+
|
|
1465
|
+
if (subflowDefRecord) {
|
|
1466
|
+
resolvedValue = resolveComplexInput(key, primitiveValue, subflowDefRecord, 'sys_hub_flow_input')
|
|
1391
1467
|
}
|
|
1392
1468
|
|
|
1393
1469
|
const result: globalThis.Record<string, unknown> = {
|
|
@@ -2,12 +2,13 @@ import { CallExpressionShape, Plugin } from '@servicenow/sdk-build-core'
|
|
|
2
2
|
import { buildVariableShapes } from '../utils/flow-io-to-record'
|
|
3
3
|
import { NowIdShape } from '../../now-id-plugin'
|
|
4
4
|
import { generateXML } from '../utils/flow-to-xml'
|
|
5
|
+
import { createSdkDocEntry } from '../../utils'
|
|
5
6
|
/**
|
|
6
7
|
* Plugin for processing StepDefinition calls
|
|
7
8
|
*/
|
|
8
9
|
export const StepDefinitionPlugin = Plugin.create({
|
|
9
10
|
name: 'StepDefinitionPlugin',
|
|
10
|
-
docs: [],
|
|
11
|
+
docs: [createSdkDocEntry('ActionStepDefinition', ['sys_flow_step_definition'])],
|
|
11
12
|
records: {
|
|
12
13
|
sys_flow_step_definition: {
|
|
13
14
|
relationships: {
|