@servicenow/sdk-build-plugins 4.7.2 → 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-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/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-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
|
@@ -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
|
+
})
|
|
@@ -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,
|
package/src/form-plugin.ts
CHANGED
|
@@ -268,50 +268,51 @@ function getOptionalString(record: Record, field: string, defaultValue = ''): st
|
|
|
268
268
|
* The name is needed as an attribute on the <view> XML element so the parser
|
|
269
269
|
* can create a RecordId with proper coalesce keys when re-reading the XML.
|
|
270
270
|
*/
|
|
271
|
-
function resolveView(
|
|
271
|
+
function resolveView(
|
|
272
|
+
view: ReturnType<Record['get']>,
|
|
273
|
+
database: Database
|
|
274
|
+
): { sysId: string; name: string; displayValue: string } {
|
|
272
275
|
if (view.isRecordId() || view.isRecord()) {
|
|
273
276
|
const viewId = view.isRecordId() ? view : view.getId()
|
|
274
277
|
const sysId = viewId.getValue()
|
|
275
|
-
// Try to resolve the view record to get its name
|
|
278
|
+
// Try to resolve the view record to get its name and title
|
|
276
279
|
const viewRecord = database.resolve(viewId)
|
|
277
280
|
if (viewRecord) {
|
|
278
281
|
const name = viewRecord.get('name').ifString()?.getValue() ?? ''
|
|
279
|
-
|
|
282
|
+
const displayValue = viewRecord.get('title').ifString()?.getValue() ?? name
|
|
283
|
+
return { sysId, name, displayValue }
|
|
280
284
|
}
|
|
281
285
|
// Fall back to primary key (view name) if available
|
|
282
286
|
if (view.isRecordId() && view.asRecordId().hasPrimaryKey()) {
|
|
283
287
|
const pk = view.asRecordId().getPrimaryKey()
|
|
284
288
|
if (pk && !isGUID(pk)) {
|
|
285
|
-
return { sysId, name: pk }
|
|
289
|
+
return { sysId, name: pk, displayValue: pk }
|
|
286
290
|
}
|
|
287
291
|
}
|
|
288
|
-
return { sysId, name: '' }
|
|
292
|
+
return { sysId, name: '', displayValue: '' }
|
|
289
293
|
}
|
|
290
294
|
|
|
291
295
|
const viewValue = view.getValue()
|
|
292
296
|
if (viewValue === 'NULL' || viewValue === DEFAULT_VIEW) {
|
|
293
|
-
return { sysId: DEFAULT_VIEW, name: DEFAULT_VIEW }
|
|
297
|
+
return { sysId: DEFAULT_VIEW, name: DEFAULT_VIEW, displayValue: DEFAULT_VIEW }
|
|
294
298
|
}
|
|
295
299
|
|
|
296
300
|
// View is a string - try to resolve to record ID if it exists in database
|
|
297
301
|
const viewNameStr = view.ifString()?.getValue() ?? ''
|
|
298
302
|
if (!viewNameStr) {
|
|
299
|
-
return { sysId: '', name: '' }
|
|
303
|
+
return { sysId: '', name: '', displayValue: '' }
|
|
300
304
|
}
|
|
301
305
|
|
|
302
306
|
const viewRecord = database.query('sys_ui_view').find((v) => v.get('name').ifString()?.getValue() === viewNameStr)
|
|
303
307
|
if (viewRecord) {
|
|
304
|
-
|
|
308
|
+
const displayValue = viewRecord.get('title').ifString()?.getValue() ?? viewNameStr
|
|
309
|
+
return { sysId: viewRecord.getId().getValue(), name: viewNameStr, displayValue }
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
sysId: viewNameStr,
|
|
313
|
+
name: isGUID(viewNameStr) ? '' : viewNameStr,
|
|
314
|
+
displayValue: isGUID(viewNameStr) ? '' : viewNameStr,
|
|
305
315
|
}
|
|
306
|
-
return { sysId: viewNameStr, name: isGUID(viewNameStr) ? '' : viewNameStr }
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Resolves a view value to its string representation (sys_id or name)
|
|
311
|
-
* Handles RecordId, Record, string values, and database lookups
|
|
312
|
-
*/
|
|
313
|
-
function resolveViewName(view: ReturnType<Record['get']>, database: Database): string {
|
|
314
|
-
return resolveView(view, database).sysId
|
|
315
316
|
}
|
|
316
317
|
|
|
317
318
|
type FormElement =
|
|
@@ -377,7 +378,11 @@ export const FormPlugin = Plugin.create({
|
|
|
377
378
|
const sectionName = section.get('name').asString().getValue()
|
|
378
379
|
const caption = getOptionalString(section, 'caption')
|
|
379
380
|
const sysDomain = getOptionalString(section, 'sys_domain', 'global')
|
|
380
|
-
const {
|
|
381
|
+
const {
|
|
382
|
+
sysId: viewSysId,
|
|
383
|
+
name: viewName,
|
|
384
|
+
displayValue: viewDisplayValue,
|
|
385
|
+
} = resolveView(section.get('view'), database)
|
|
381
386
|
|
|
382
387
|
const xml = create().ele('record_update')
|
|
383
388
|
const root = xml.ele('sys_ui_section', {
|
|
@@ -385,7 +390,7 @@ export const FormPlugin = Plugin.create({
|
|
|
385
390
|
section_id: section.getId().getValue(),
|
|
386
391
|
sys_domain: sysDomain,
|
|
387
392
|
table: sectionName,
|
|
388
|
-
view: viewName,
|
|
393
|
+
view: viewSysId === DEFAULT_VIEW ? '' : viewName,
|
|
389
394
|
})
|
|
390
395
|
|
|
391
396
|
// Add all sys_ui_annotation records for this section (excluding deleted ones)
|
|
@@ -427,7 +432,7 @@ export const FormPlugin = Plugin.create({
|
|
|
427
432
|
display_value: caption,
|
|
428
433
|
name: sectionName,
|
|
429
434
|
sys_domain: sysDomain,
|
|
430
|
-
view:
|
|
435
|
+
view: viewSysId,
|
|
431
436
|
})
|
|
432
437
|
.txt(section.getId().getValue())
|
|
433
438
|
child.ele('sys_user')
|
|
@@ -446,7 +451,13 @@ export const FormPlugin = Plugin.create({
|
|
|
446
451
|
sectionChild.ele('sys_user')
|
|
447
452
|
sectionChild.ele('title').txt(String(section.get('title').ifBoolean()?.getValue() ?? false))
|
|
448
453
|
sectionChild.ele('view_name')
|
|
449
|
-
|
|
454
|
+
const isDefaultView = viewSysId === DEFAULT_VIEW
|
|
455
|
+
const sectionViewAttrs = isDefaultView
|
|
456
|
+
? { name: 'NULL', display_value: DEFAULT_VIEW }
|
|
457
|
+
: viewName
|
|
458
|
+
? { name: viewName, display_value: viewDisplayValue || viewName }
|
|
459
|
+
: {}
|
|
460
|
+
sectionChild.ele('view', sectionViewAttrs).txt(viewSysId)
|
|
450
461
|
|
|
451
462
|
return {
|
|
452
463
|
success: true,
|
|
@@ -702,7 +713,11 @@ export const FormPlugin = Plugin.create({
|
|
|
702
713
|
|
|
703
714
|
const formName = form.get('name').asString().getValue()
|
|
704
715
|
const formSysDomain = getOptionalString(form, 'sys_domain', 'global')
|
|
705
|
-
const {
|
|
716
|
+
const {
|
|
717
|
+
sysId: formViewSysId,
|
|
718
|
+
name: formViewName,
|
|
719
|
+
displayValue: formViewDisplayValue,
|
|
720
|
+
} = resolveView(form.get('view'), database)
|
|
706
721
|
|
|
707
722
|
const xml = create().ele('record_update')
|
|
708
723
|
const root = xml.ele('sys_ui_form_sections', {
|
|
@@ -727,7 +742,7 @@ export const FormPlugin = Plugin.create({
|
|
|
727
742
|
display_value: formName,
|
|
728
743
|
name: formName,
|
|
729
744
|
sys_domain: formSysDomain,
|
|
730
|
-
view:
|
|
745
|
+
view: formViewSysId,
|
|
731
746
|
})
|
|
732
747
|
.txt(form.getId().getValue())
|
|
733
748
|
|
|
@@ -737,14 +752,14 @@ export const FormPlugin = Plugin.create({
|
|
|
737
752
|
|
|
738
753
|
if (section) {
|
|
739
754
|
const sectionCaption = getOptionalString(section, 'caption')
|
|
740
|
-
const
|
|
755
|
+
const { sysId: sectionViewSysId } = resolveView(section.get('view'), database)
|
|
741
756
|
child
|
|
742
757
|
.ele('sys_ui_section', {
|
|
743
758
|
caption: sectionCaption,
|
|
744
759
|
display_value: sectionCaption,
|
|
745
760
|
name: formName,
|
|
746
761
|
sys_domain: getOptionalString(section, 'sys_domain', 'global'),
|
|
747
|
-
view:
|
|
762
|
+
view: sectionViewSysId,
|
|
748
763
|
})
|
|
749
764
|
.txt(section.getId().getValue())
|
|
750
765
|
}
|
|
@@ -757,7 +772,13 @@ export const FormPlugin = Plugin.create({
|
|
|
757
772
|
formChild.ele('sys_id').txt(form.getId().getValue())
|
|
758
773
|
formChild.ele('sys_scope', { display_value: config.scope }).txt(config.scopeId)
|
|
759
774
|
formChild.ele('sys_user').txt(getOptionalString(form, 'sys_user'))
|
|
760
|
-
|
|
775
|
+
const isDefaultFormView = formViewSysId === DEFAULT_VIEW
|
|
776
|
+
const formViewAttrs = isDefaultFormView
|
|
777
|
+
? { name: 'NULL', display_value: DEFAULT_VIEW }
|
|
778
|
+
: formViewName
|
|
779
|
+
? { name: formViewName, display_value: formViewDisplayValue || formViewName }
|
|
780
|
+
: {}
|
|
781
|
+
formChild.ele('view', formViewAttrs).txt(formViewSysId)
|
|
761
782
|
formChild.ele('view_name')
|
|
762
783
|
|
|
763
784
|
return {
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './cross-scope-privilege-plugin'
|
|
|
6
6
|
export * from './record-plugin'
|
|
7
7
|
export * from './now-id-plugin'
|
|
8
8
|
export * from './now-ref-plugin'
|
|
9
|
+
export * from './now-delete-plugin'
|
|
9
10
|
export * from './now-unresolved-plugin'
|
|
10
11
|
export * from './property-plugin'
|
|
11
12
|
export * from './role-plugin'
|
|
@@ -21,6 +22,7 @@ export * from './now-include-plugin'
|
|
|
21
22
|
export * from './table-plugin'
|
|
22
23
|
export * from './column-plugin'
|
|
23
24
|
export * from './data-plugin'
|
|
25
|
+
export * from './data-lookup-plugin'
|
|
24
26
|
export * from './ui-page-plugin'
|
|
25
27
|
export * from './list-plugin'
|
|
26
28
|
export * from './ui-action-plugin'
|
|
@@ -62,6 +64,7 @@ export * from './now-attach-plugin'
|
|
|
62
64
|
export * from './sla-plugin'
|
|
63
65
|
export * from './email-notification-plugin'
|
|
64
66
|
export * from './inbound-email-action-plugin'
|
|
67
|
+
export * from './rest-message-plugin'
|
|
65
68
|
|
|
66
69
|
export * from './service-catalog'
|
|
67
70
|
export * from './ux-list-menu-config-plugin'
|
|
@@ -69,6 +72,7 @@ export * from './workspace-plugin'
|
|
|
69
72
|
export * from './dashboard/dashboard-plugin'
|
|
70
73
|
export * from './applicability-plugin'
|
|
71
74
|
export * from './instance-scan-plugin'
|
|
75
|
+
export * from './alias'
|
|
72
76
|
// non-plugins
|
|
73
77
|
export * from './atf/step-configs'
|
|
74
78
|
export { REPACK_OUTPUT_DIR, checkModuleExists, resolveModule } from './repack'
|
package/src/now-config-plugin.ts
CHANGED
|
@@ -787,6 +787,7 @@ export const NowConfigPlugin = Plugin.create({
|
|
|
787
787
|
packageResolverVersion: $.from('package_resolver_version').def(
|
|
788
788
|
config.scope === 'global' ? MODULE_RESOLUTION.V2 : MODULE_RESOLUTION.V1
|
|
789
789
|
),
|
|
790
|
+
sysCode: $.from('sys_code').def(''),
|
|
790
791
|
})),
|
|
791
792
|
}),
|
|
792
793
|
}
|
|
@@ -936,7 +937,7 @@ export const NowConfigPlugin = Plugin.create({
|
|
|
936
937
|
package_resolver_version: $.from('packageResolverVersion').def(
|
|
937
938
|
scope === 'global' ? MODULE_RESOLUTION.V2 : MODULE_RESOLUTION.V1
|
|
938
939
|
),
|
|
939
|
-
sys_code: $.from('
|
|
940
|
+
sys_code: $.from('sysCode'),
|
|
940
941
|
})),
|
|
941
942
|
})
|
|
942
943
|
|