@servicenow/sdk-build-plugins 4.7.1 → 4.8.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/alias/alias-plugin.d.ts +2 -0
- package/dist/alias/alias-plugin.js +183 -0
- package/dist/alias/alias-plugin.js.map +1 -0
- package/dist/alias/alias-template-plugin.d.ts +2 -0
- package/dist/alias/alias-template-plugin.js +232 -0
- package/dist/alias/alias-template-plugin.js.map +1 -0
- package/dist/alias/index.d.ts +3 -0
- package/dist/alias/index.js +20 -0
- package/dist/alias/index.js.map +1 -0
- package/dist/alias/retry-policy-plugin.d.ts +2 -0
- package/dist/alias/retry-policy-plugin.js +119 -0
- package/dist/alias/retry-policy-plugin.js.map +1 -0
- package/dist/arrow-function-plugin.d.ts +1 -0
- package/dist/arrow-function-plugin.js +60 -21
- package/dist/arrow-function-plugin.js.map +1 -1
- package/dist/atf/test-plugin.js +1 -1
- package/dist/atf/test-plugin.js.map +1 -1
- package/dist/basic-syntax-plugin.js +7 -7
- package/dist/basic-syntax-plugin.js.map +1 -1
- package/dist/column/index.d.ts +2 -0
- package/dist/column/index.js +13 -0
- package/dist/column/index.js.map +1 -0
- package/dist/dashboard/dashboard-plugin.js +4 -0
- package/dist/dashboard/dashboard-plugin.js.map +1 -1
- package/dist/data-lookup-plugin.d.ts +2 -0
- package/dist/data-lookup-plugin.js +159 -0
- package/dist/data-lookup-plugin.js.map +1 -0
- package/dist/flow/plugins/flow-action-definition-plugin.js +38 -2
- package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-instance-plugin.js +1 -1
- package/dist/flow/plugins/flow-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/step-instance-plugin.js +1 -1
- package/dist/flow/plugins/step-instance-plugin.js.map +1 -1
- package/dist/flow/utils/flow-constants.d.ts +7 -0
- package/dist/flow/utils/flow-constants.js +6 -1
- package/dist/flow/utils/flow-constants.js.map +1 -1
- package/dist/flow/utils/flow-shapes.d.ts +1 -1
- package/dist/form-plugin.js +35 -24
- package/dist/form-plugin.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/now-attach-plugin.d.ts +1 -1
- package/dist/now-config-plugin.js +2 -1
- package/dist/now-config-plugin.js.map +1 -1
- package/dist/now-delete-plugin.d.ts +2 -0
- package/dist/now-delete-plugin.js +64 -0
- package/dist/now-delete-plugin.js.map +1 -0
- package/dist/record-plugin.d.ts +10 -0
- package/dist/record-plugin.js +15 -1
- package/dist/record-plugin.js.map +1 -1
- package/dist/repack/lint/Rules.js +17 -7
- package/dist/repack/lint/Rules.js.map +1 -1
- package/dist/rest-message-plugin.d.ts +2 -0
- package/dist/rest-message-plugin.js +331 -0
- package/dist/rest-message-plugin.js.map +1 -0
- package/dist/script-include-plugin.js +1 -1
- package/dist/script-include-plugin.js.map +1 -1
- package/dist/server-module-plugin/sbom-builder.js +17 -7
- package/dist/server-module-plugin/sbom-builder.js.map +1 -1
- package/dist/static-content-plugin.js +17 -7
- package/dist/static-content-plugin.js.map +1 -1
- package/dist/table-plugin.js +5 -2
- package/dist/table-plugin.js.map +1 -1
- package/package.json +6 -5
- package/src/alias/alias-plugin.ts +221 -0
- package/src/alias/alias-template-plugin.ts +271 -0
- package/src/alias/index.ts +3 -0
- package/src/alias/retry-policy-plugin.ts +138 -0
- package/src/arrow-function-plugin.ts +67 -23
- package/src/atf/test-plugin.ts +1 -1
- package/src/basic-syntax-plugin.ts +7 -7
- package/src/column/index.ts +7 -0
- package/src/dashboard/dashboard-plugin.ts +4 -0
- package/src/data-lookup-plugin.ts +191 -0
- package/src/flow/plugins/flow-action-definition-plugin.ts +49 -3
- package/src/flow/plugins/flow-instance-plugin.ts +2 -1
- package/src/flow/plugins/step-instance-plugin.ts +1 -1
- package/src/flow/utils/flow-constants.ts +8 -0
- package/src/form-plugin.ts +47 -26
- package/src/index.ts +4 -0
- package/src/now-config-plugin.ts +2 -1
- package/src/now-delete-plugin.ts +82 -0
- package/src/record-plugin.ts +17 -2
- package/src/rest-message-plugin.ts +391 -0
- package/src/script-include-plugin.ts +4 -1
- package/src/table-plugin.ts +7 -2
|
@@ -71,6 +71,10 @@ export class ArrowFunctionShape extends Shape {
|
|
|
71
71
|
return this.returnValue
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
isImplicitReturn(): boolean {
|
|
75
|
+
return this.implicitReturn
|
|
76
|
+
}
|
|
77
|
+
|
|
74
78
|
override getCode(): string {
|
|
75
79
|
const params = `(${this.getParameters()
|
|
76
80
|
.map((p) => p.getCode())
|
|
@@ -192,48 +196,88 @@ export const ArrowFunctionPlugin = Plugin.create({
|
|
|
192
196
|
{
|
|
193
197
|
shape: ArrowFunctionShape,
|
|
194
198
|
async commit(shape, target, { commit }) {
|
|
195
|
-
const
|
|
199
|
+
const originalTargetWasArrow = ts.Node.isArrowFunction(target)
|
|
200
|
+
const arrowTarget = originalTargetWasArrow
|
|
196
201
|
? target
|
|
197
202
|
: target.replaceWithText('() => {}').asKindOrThrow(ts.SyntaxKind.ArrowFunction)
|
|
198
203
|
|
|
199
|
-
const nodeStatements = arrowFunction.getStatements()
|
|
200
204
|
const shapeStatements = shape.getStatements()
|
|
201
205
|
const returnValue = shape.getReturnValue()
|
|
206
|
+
const body = arrowTarget.getBody()
|
|
202
207
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
// Preserve concise arrows when the shape is still an implicit return.
|
|
209
|
+
if (
|
|
210
|
+
originalTargetWasArrow &&
|
|
211
|
+
!ts.Node.isBlock(body) &&
|
|
212
|
+
shapeStatements.length === 0 &&
|
|
213
|
+
returnValue &&
|
|
214
|
+
shape.isImplicitReturn()
|
|
215
|
+
) {
|
|
216
|
+
if (returnValue.is(ObjectShape)) {
|
|
217
|
+
body.replaceWithText(`(${returnValue.getCode()})`)
|
|
218
|
+
} else {
|
|
207
219
|
await commit(returnValue, body)
|
|
208
|
-
return { success: true }
|
|
209
220
|
}
|
|
221
|
+
return { success: true }
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (!ts.Node.isBlock(body)) {
|
|
225
|
+
// ts-morph cannot grow expression-body arrows like `() => ({})` into
|
|
226
|
+
// block bodies with statement APIs, so convert the body to an empty block
|
|
227
|
+
// first and then continue through the normal commit flow below.
|
|
228
|
+
body.replaceWithText('{}')
|
|
210
229
|
}
|
|
211
230
|
|
|
212
|
-
const
|
|
213
|
-
|
|
231
|
+
const getNonReturnStatements = () =>
|
|
232
|
+
arrowTarget.getStatements().filter((statement) => !ts.Node.isReturnStatement(statement))
|
|
233
|
+
|
|
234
|
+
const existingStatements = getNonReturnStatements()
|
|
235
|
+
const excess = existingStatements.length - shapeStatements.length
|
|
214
236
|
for (let i = 1; i <= excess; i++) {
|
|
215
|
-
|
|
237
|
+
existingStatements[existingStatements.length - i]?.remove()
|
|
216
238
|
}
|
|
217
239
|
|
|
218
240
|
for (const [i, statement] of shapeStatements.entries()) {
|
|
219
|
-
const
|
|
220
|
-
|
|
241
|
+
const currentStatements = getNonReturnStatements()
|
|
242
|
+
const targetStatement = currentStatements[i]
|
|
243
|
+
if (targetStatement) {
|
|
244
|
+
await commit(statement, targetStatement)
|
|
245
|
+
} else {
|
|
246
|
+
// Insert before `return` so return-only bodies can grow safely.
|
|
247
|
+
const returnIndex = arrowTarget
|
|
248
|
+
.getStatements()
|
|
249
|
+
.findIndex((node) => ts.Node.isReturnStatement(node))
|
|
250
|
+
const inserted =
|
|
251
|
+
returnIndex >= 0
|
|
252
|
+
? arrowTarget.insertStatements(returnIndex, statement.getCode())[0]!
|
|
253
|
+
: arrowTarget.addStatements(statement.getCode())[0]!
|
|
254
|
+
await commit(statement, inserted)
|
|
255
|
+
}
|
|
221
256
|
}
|
|
222
257
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
258
|
+
let existingReturn = arrowTarget
|
|
259
|
+
.getStatements()
|
|
260
|
+
.find((statement) => ts.Node.isReturnStatement(statement))
|
|
261
|
+
if (!returnValue) {
|
|
262
|
+
existingReturn?.remove()
|
|
263
|
+
return { success: true }
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!existingReturn) {
|
|
267
|
+
const inserted = arrowTarget.addStatements(`return ${returnValue.getCode()}`)[0]!
|
|
268
|
+
existingReturn = ts.Node.isReturnStatement(inserted)
|
|
269
|
+
? inserted
|
|
270
|
+
: arrowTarget.getStatements().find((statement) => ts.Node.isReturnStatement(statement))
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (existingReturn) {
|
|
274
|
+
const expr = existingReturn.getExpression()
|
|
275
|
+
if (expr) {
|
|
276
|
+
await commit(returnValue, expr)
|
|
232
277
|
} else {
|
|
233
|
-
|
|
278
|
+
existingReturn.replaceWithText(`return ${returnValue.getCode()}`)
|
|
234
279
|
}
|
|
235
280
|
}
|
|
236
|
-
|
|
237
281
|
return { success: true }
|
|
238
282
|
},
|
|
239
283
|
},
|
package/src/atf/test-plugin.ts
CHANGED
|
@@ -85,13 +85,13 @@ export const BasicSyntaxPlugin = Plugin.create({
|
|
|
85
85
|
const conditionalDir = NowConfig.getConditionalDirectory(config, source.path)
|
|
86
86
|
const taxonomySubdir = tableName && taxonomy.mapping[tableName] ? taxonomy.mapping[tableName] : ''
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
// The hosted/conditional plugin prefix (e.g. `if/com.<plugin>`) is orthogonal to
|
|
89
|
+
// the taxonomy folder (e.g. `data/table`). Compose them so records keep their
|
|
90
|
+
// taxonomy organization even when they live under a conditional/hosted plugin
|
|
91
|
+
// directory, instead of the plugin prefix overriding the taxonomy (DEF0844422).
|
|
92
|
+
// `pathModule.join` drops empty segments, so any of these may be absent.
|
|
93
|
+
const prefixDir = hostedDir ?? conditionalDir ?? ''
|
|
94
|
+
const dir = pathModule.join(generatedDir, prefixDir, taxonomySubdir)
|
|
95
95
|
|
|
96
96
|
let name = pathModule.basename(source.path).replace(RegExp(`${pathModule.extname(source.path)}$`), '')
|
|
97
97
|
if (!name) {
|
|
@@ -211,6 +211,8 @@ export const DashboardPlugin = Plugin.create({
|
|
|
211
211
|
$id: $.val(NowIdShape.from(record)),
|
|
212
212
|
name: $,
|
|
213
213
|
active: $.toBoolean().def(true),
|
|
214
|
+
description: $.def(''),
|
|
215
|
+
certified: $.toBoolean().def(false),
|
|
214
216
|
tabs: $.val(tabs).def([]),
|
|
215
217
|
visibilities: $.val(visibilities).def([]),
|
|
216
218
|
permissions: $.val(permissions).def([]),
|
|
@@ -272,6 +274,8 @@ export const DashboardPlugin = Plugin.create({
|
|
|
272
274
|
properties: arg.transform(({ $ }) => ({
|
|
273
275
|
name: $,
|
|
274
276
|
active: $.def(true),
|
|
277
|
+
description: $.def(''),
|
|
278
|
+
certified: $.def(false),
|
|
275
279
|
})),
|
|
276
280
|
})
|
|
277
281
|
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { CallExpressionShape, Plugin, isSNScope } from '@servicenow/sdk-build-core'
|
|
2
|
+
import { NowIdShape } from './now-id-plugin'
|
|
3
|
+
|
|
4
|
+
const DL_DEFINITION = 'dl_definition'
|
|
5
|
+
const DL_DEFINITION_REL_MATCH = 'dl_definition_rel_match'
|
|
6
|
+
const DL_DEFINITION_REL_SET = 'dl_definition_rel_set'
|
|
7
|
+
|
|
8
|
+
export const DataLookupPlugin = Plugin.create({
|
|
9
|
+
name: 'DataLookupPlugin',
|
|
10
|
+
|
|
11
|
+
records: {
|
|
12
|
+
[DL_DEFINITION]: {
|
|
13
|
+
relationships: {
|
|
14
|
+
[DL_DEFINITION_REL_MATCH]: {
|
|
15
|
+
via: 'dl_definition',
|
|
16
|
+
descendant: true,
|
|
17
|
+
},
|
|
18
|
+
[DL_DEFINITION_REL_SET]: {
|
|
19
|
+
via: 'dl_definition',
|
|
20
|
+
descendant: true,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
async toShape(record, { descendants }) {
|
|
25
|
+
const matchRecords = descendants
|
|
26
|
+
.query(DL_DEFINITION_REL_MATCH)
|
|
27
|
+
.filter((r) => r.get('dl_definition').equals(record.getId()))
|
|
28
|
+
|
|
29
|
+
const setRecords = descendants
|
|
30
|
+
.query(DL_DEFINITION_REL_SET)
|
|
31
|
+
.filter((r) => r.get('dl_definition').equals(record.getId()))
|
|
32
|
+
|
|
33
|
+
const matchRules = matchRecords.map((r) =>
|
|
34
|
+
r.transform(({ $ }) => ({
|
|
35
|
+
$id: $.val(NowIdShape.from(r)),
|
|
36
|
+
sourceField: $.from('source_table_field'),
|
|
37
|
+
matcherField: $.from('matcher_table_field'),
|
|
38
|
+
exactMatch: $.from('exact_match').toBoolean().def(false),
|
|
39
|
+
}))
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const setRules = setRecords.map((r) =>
|
|
43
|
+
r.transform(({ $ }) => ({
|
|
44
|
+
$id: $.val(NowIdShape.from(r)),
|
|
45
|
+
targetField: $.from('source_table_field'),
|
|
46
|
+
matcherField: $.from('matcher_table_field'),
|
|
47
|
+
alwaysReplace: $.from('always_replace').toBoolean().def(false),
|
|
48
|
+
}))
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
success: true,
|
|
53
|
+
value: new CallExpressionShape({
|
|
54
|
+
source: record,
|
|
55
|
+
callee: 'DataLookup',
|
|
56
|
+
args: [
|
|
57
|
+
record.transform(({ $ }) => ({
|
|
58
|
+
$id: $.val(NowIdShape.from(record)),
|
|
59
|
+
name: $,
|
|
60
|
+
sourceTable: $.from('source_table'),
|
|
61
|
+
matcherTable: $.from('matcher_table'),
|
|
62
|
+
active: $.from('active').toBoolean().def(true),
|
|
63
|
+
runOnInsert: $.from('run_on_insert').toBoolean().def(true),
|
|
64
|
+
runOnUpdate: $.from('run_on_update').toBoolean().def(false),
|
|
65
|
+
runOnFormChange: $.from('run_on_form_change').toBoolean().def(true),
|
|
66
|
+
matchRules: $.val(matchRules.length ? matchRules : undefined),
|
|
67
|
+
setRules: $.val(setRules.length ? setRules : undefined),
|
|
68
|
+
protectionPolicy: $.from('sys_policy').def(''),
|
|
69
|
+
})),
|
|
70
|
+
],
|
|
71
|
+
}),
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
[DL_DEFINITION_REL_MATCH]: {
|
|
77
|
+
// Child records are pulled by the parent dl_definition toShape via descendants.query(),
|
|
78
|
+
// so they must not be transformed independently.
|
|
79
|
+
toShape() {
|
|
80
|
+
return { success: false }
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
[DL_DEFINITION_REL_SET]: {
|
|
85
|
+
// Same as dl_definition_rel_match — rendered inline by the parent's toShape.
|
|
86
|
+
toShape() {
|
|
87
|
+
return { success: false }
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
shapes: [
|
|
93
|
+
{
|
|
94
|
+
shape: CallExpressionShape,
|
|
95
|
+
fileTypes: ['fluent'],
|
|
96
|
+
async toRecord(callExpression, { factory, diagnostics, config }) {
|
|
97
|
+
if (callExpression.getCallee() !== 'DataLookup') {
|
|
98
|
+
return { success: false }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const arg = callExpression.getArgument(0).asObject()
|
|
102
|
+
|
|
103
|
+
const name = arg.get('name').ifString()?.getValue()
|
|
104
|
+
if (name && name.length > 40) {
|
|
105
|
+
diagnostics.error(
|
|
106
|
+
arg.get('name'),
|
|
107
|
+
`Data Lookup Definition name must be 40 characters or fewer (got ${name.length}).`
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const sourceTable = arg.get('sourceTable').ifString()?.getValue() ?? ''
|
|
112
|
+
const matcherTable = arg.get('matcherTable').ifString()?.getValue() ?? ''
|
|
113
|
+
|
|
114
|
+
const scope = config.scope
|
|
115
|
+
if (sourceTable && !sourceTable.startsWith(`${scope}_`) && !isSNScope(scope) && scope !== 'global') {
|
|
116
|
+
diagnostics.error(
|
|
117
|
+
arg.get('sourceTable'),
|
|
118
|
+
`sourceTable '${sourceTable}' must be in the same scope as the data lookup definition. Expected a table starting with '${scope}_'.`
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
if (matcherTable && !matcherTable.startsWith(`${scope}_`) && !isSNScope(scope) && scope !== 'global') {
|
|
122
|
+
diagnostics.error(
|
|
123
|
+
arg.get('matcherTable'),
|
|
124
|
+
`matcherTable '${matcherTable}' must be in the same scope as the data lookup definition. Expected a table starting with '${scope}_'.`
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const mainRecord = await factory.createRecord({
|
|
129
|
+
source: callExpression,
|
|
130
|
+
table: DL_DEFINITION,
|
|
131
|
+
explicitId: arg.get('$id'),
|
|
132
|
+
properties: arg.transform(({ $ }) => ({
|
|
133
|
+
name: $,
|
|
134
|
+
source_table: $.from('sourceTable'),
|
|
135
|
+
matcher_table: $.from('matcherTable'),
|
|
136
|
+
active: $.from('active').def(true),
|
|
137
|
+
run_on_insert: $.from('runOnInsert').def(true),
|
|
138
|
+
run_on_update: $.from('runOnUpdate').def(false),
|
|
139
|
+
run_on_form_change: $.from('runOnFormChange').def(true),
|
|
140
|
+
sys_policy: $.from('protectionPolicy'),
|
|
141
|
+
})),
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
const matchElements = arg.get('matchRules').ifArray()?.getElements() ?? []
|
|
145
|
+
const matchRecords = await Promise.all(
|
|
146
|
+
matchElements.map(async (el) => {
|
|
147
|
+
const rule = el.asObject()
|
|
148
|
+
return factory.createRecord({
|
|
149
|
+
source: el,
|
|
150
|
+
table: DL_DEFINITION_REL_MATCH,
|
|
151
|
+
explicitId: rule.get('$id'),
|
|
152
|
+
properties: rule.transform(({ $ }) => ({
|
|
153
|
+
dl_definition: $.val(mainRecord.getId()),
|
|
154
|
+
source_table_field: $.from('sourceField'),
|
|
155
|
+
matcher_table_field: $.from('matcherField'),
|
|
156
|
+
exact_match: $.from('exactMatch').def(false),
|
|
157
|
+
source_table: $.val(sourceTable),
|
|
158
|
+
matcher_table: $.val(matcherTable),
|
|
159
|
+
})),
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
const setElements = arg.get('setRules').ifArray()?.getElements() ?? []
|
|
165
|
+
const setRecords = await Promise.all(
|
|
166
|
+
setElements.map(async (el) => {
|
|
167
|
+
const rule = el.asObject()
|
|
168
|
+
return factory.createRecord({
|
|
169
|
+
source: el,
|
|
170
|
+
table: DL_DEFINITION_REL_SET,
|
|
171
|
+
explicitId: rule.get('$id'),
|
|
172
|
+
properties: rule.transform(({ $ }) => ({
|
|
173
|
+
dl_definition: $.val(mainRecord.getId()),
|
|
174
|
+
source_table_field: $.from('targetField'),
|
|
175
|
+
matcher_table_field: $.from('matcherField'),
|
|
176
|
+
always_replace: $.from('alwaysReplace').def(false),
|
|
177
|
+
source_table: $.val(sourceTable),
|
|
178
|
+
matcher_table: $.val(matcherTable),
|
|
179
|
+
})),
|
|
180
|
+
})
|
|
181
|
+
})
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
success: true,
|
|
186
|
+
value: mainRecord.with(...matchRecords, ...setRecords),
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
})
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
} from '../utils/flow-constants'
|
|
35
35
|
import { STEP_PILL_TYPE_REGEX, stripPillType, collectPillTypes } from '../utils/flow-pill-utils'
|
|
36
36
|
import { COLUMN_TYPE_TO_API } from '../../column/column-helper'
|
|
37
|
-
import {
|
|
37
|
+
import { buildComplexObjectFromSchema, parseAttributesToObject } from '../utils/schema-to-flow-object'
|
|
38
38
|
import { normalizeInputValue } from './flow-instance-plugin'
|
|
39
39
|
import { ApprovalRulesShape, ApprovalDueDateShape } from '../utils/flow-shapes'
|
|
40
40
|
import { ArrowFunctionShape } from '../../arrow-function-plugin'
|
|
@@ -1387,6 +1387,11 @@ const actionDefRelationships = {
|
|
|
1387
1387
|
via: { name: 'name', element: 'element' },
|
|
1388
1388
|
descendant: true,
|
|
1389
1389
|
},
|
|
1390
|
+
sys_complex_object: {
|
|
1391
|
+
via: [complexObjectMatchesIoRecord],
|
|
1392
|
+
descendant: true,
|
|
1393
|
+
inverse: true,
|
|
1394
|
+
},
|
|
1390
1395
|
},
|
|
1391
1396
|
},
|
|
1392
1397
|
sys_hub_input_scripts: {
|
|
@@ -1610,6 +1615,13 @@ export const ActionDefinitionPlugin = Plugin.create({
|
|
|
1610
1615
|
sys_hub_step_ext_output: {
|
|
1611
1616
|
via: 'model',
|
|
1612
1617
|
descendant: true,
|
|
1618
|
+
relationships: {
|
|
1619
|
+
sys_complex_object: {
|
|
1620
|
+
via: [complexObjectMatchesIoRecord],
|
|
1621
|
+
descendant: true,
|
|
1622
|
+
inverse: true,
|
|
1623
|
+
},
|
|
1624
|
+
},
|
|
1613
1625
|
},
|
|
1614
1626
|
sys_translated_text: {
|
|
1615
1627
|
via: 'documentkey',
|
|
@@ -1871,8 +1883,42 @@ export const ActionDefinitionPlugin = Plugin.create({
|
|
|
1871
1883
|
const mandatory = extOutput.get('mandatory')?.ifString()?.getValue() === 'true'
|
|
1872
1884
|
const internalType = extOutput.get('internal_type')?.ifString()?.getValue() ?? 'string'
|
|
1873
1885
|
// Check attributes for uiType to handle cases where internal_type is generic
|
|
1874
|
-
const
|
|
1875
|
-
const
|
|
1886
|
+
const attributesStr = extOutput.get('attributes')?.ifString()?.getValue() ?? ''
|
|
1887
|
+
const parsedAttributes = parseAttributesToObject(attributesStr)
|
|
1888
|
+
const uiType = parsedAttributes.uiType ?? internalType
|
|
1889
|
+
|
|
1890
|
+
// Handle FlowObject/FlowArray complex types via co_type_name
|
|
1891
|
+
const maybeCoTypeName = parsedAttributes.co_type_name
|
|
1892
|
+
if (maybeCoTypeName) {
|
|
1893
|
+
const coRecord = descendants.query('sys_complex_object', { name: maybeCoTypeName })
|
|
1894
|
+
let serializedContent = coRecord[0]
|
|
1895
|
+
?.get('serialized_content')
|
|
1896
|
+
?.ifString()
|
|
1897
|
+
?.getValue()
|
|
1898
|
+
let complexObjectSysId: string | undefined = coRecord[0]?.getId().getValue()
|
|
1899
|
+
if (!serializedContent) {
|
|
1900
|
+
const builtIn = builtInComplexObjects[maybeCoTypeName]
|
|
1901
|
+
serializedContent = builtIn?.data.serialized_content
|
|
1902
|
+
complexObjectSysId = undefined
|
|
1903
|
+
}
|
|
1904
|
+
if (serializedContent) {
|
|
1905
|
+
const varSysId = extOutput.getId().getValue()
|
|
1906
|
+
const isDeterministic = maybeCoTypeName === `FD${varSysId}`
|
|
1907
|
+
const schema = JSON.parse(serializedContent)
|
|
1908
|
+
outputVariablesObj[elementName] = buildComplexObjectFromSchema(
|
|
1909
|
+
extOutput,
|
|
1910
|
+
schema,
|
|
1911
|
+
parsedAttributes,
|
|
1912
|
+
isDeterministic ? undefined : complexObjectSysId,
|
|
1913
|
+
isDeterministic ? undefined : maybeCoTypeName
|
|
1914
|
+
)
|
|
1915
|
+
continue
|
|
1916
|
+
}
|
|
1917
|
+
logger.warn(
|
|
1918
|
+
`Unable to find sys_complex_object with co_type_name '${maybeCoTypeName}' for step output '${elementName}'; falling back to StringColumn`
|
|
1919
|
+
)
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1876
1922
|
const columnApiName = COLUMN_TYPE_TO_API[uiType] ?? 'StringColumn'
|
|
1877
1923
|
const columnProps: Props = { label }
|
|
1878
1924
|
if (mandatory) {
|
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
UNSUPPORTED_DATA_TYPES,
|
|
69
69
|
UTC_TIMEZONE_VALUE,
|
|
70
70
|
ELEMENT_MAPPING_FIELD_ALIASES,
|
|
71
|
+
ELEMENT_MAPPING_FIELD_ALIASES_REVERSE,
|
|
71
72
|
} from '../utils/flow-constants'
|
|
72
73
|
|
|
73
74
|
import type { ApprovalDueDateType, ApprovalRulesType } from '@servicenow/sdk-core/runtime/flow'
|
|
@@ -958,7 +959,7 @@ function processInputValue(
|
|
|
958
959
|
|
|
959
960
|
// Return standard input object
|
|
960
961
|
return {
|
|
961
|
-
name: inputName,
|
|
962
|
+
name: ELEMENT_MAPPING_FIELD_ALIASES_REVERSE[inputName] ?? inputName,
|
|
962
963
|
value: finalValue,
|
|
963
964
|
displayValue: displayValues && displayValues.has(inputName) ? displayValues.get(inputName) : finalValue,
|
|
964
965
|
scriptActive: false,
|
|
@@ -545,6 +545,14 @@ export const ELEMENT_MAPPING_FIELD_ALIASES: { [platformName: string]: string } =
|
|
|
545
545
|
__snc_dont_fail_on_error: 'dont_fail_flow_on_error',
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
+
/**
|
|
549
|
+
* Reverse of ELEMENT_MAPPING_FIELD_ALIASES — maps Fluent API names back to their
|
|
550
|
+
* platform-internal names for serialization into sys_hub_action_instance_v2.
|
|
551
|
+
*/
|
|
552
|
+
export const ELEMENT_MAPPING_FIELD_ALIASES_REVERSE: { [fluentName: string]: string } = Object.fromEntries(
|
|
553
|
+
Object.entries(ELEMENT_MAPPING_FIELD_ALIASES).map(([platform, fluent]) => [fluent, platform])
|
|
554
|
+
)
|
|
555
|
+
|
|
548
556
|
export enum ChoiceDropdown {
|
|
549
557
|
DROPDOWN_WITH_NONE = 1,
|
|
550
558
|
DROPDOWN_WITHOUT_NONE = 3,
|