@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
|
@@ -1,5 +1,163 @@
|
|
|
1
1
|
import { NowIncludeShape } from '../now-include-plugin'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type Record,
|
|
4
|
+
Shape,
|
|
5
|
+
type RecordId,
|
|
6
|
+
type Diagnostics,
|
|
7
|
+
type Factory,
|
|
8
|
+
CallExpressionShape,
|
|
9
|
+
isGUID,
|
|
10
|
+
} from '@servicenow/sdk-build-core'
|
|
11
|
+
import { noThrow, reverseObject } from '../utils'
|
|
12
|
+
import { WidgetCategories } from '@servicenow/sdk-core/runtime/service-portal'
|
|
13
|
+
import { NowIdShape } from '../now-id-plugin'
|
|
14
|
+
|
|
15
|
+
function convertOptionSchemaKeys(optionSchema: unknown, convertKey: (key: string) => string): unknown {
|
|
16
|
+
if (!Array.isArray(optionSchema)) {
|
|
17
|
+
return optionSchema
|
|
18
|
+
}
|
|
19
|
+
return optionSchema.map((option: globalThis.Record<string, unknown>) =>
|
|
20
|
+
Object.fromEntries(Object.entries(option).map(([k, v]) => [convertKey(k), v]))
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const toCamelCase = (key: string) => key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Shared toShape implementation for SPWidget and SPHeaderFooter
|
|
28
|
+
*/
|
|
29
|
+
export async function createWidgetToShape(
|
|
30
|
+
record: Record,
|
|
31
|
+
descendants: { query: (table: string) => Record[] },
|
|
32
|
+
callee: 'SPWidget' | 'SPHeaderFooter',
|
|
33
|
+
tablePrefix: string = 'sp_widget',
|
|
34
|
+
includeStaticField: boolean = false
|
|
35
|
+
) {
|
|
36
|
+
const folderName =
|
|
37
|
+
record.get('id')?.asString()?.getValue()?.replace(/[\s-]/g, '_') ||
|
|
38
|
+
record.get('name')?.asString()?.getValue()?.toLowerCase().replace(/[\s-]/g, '_')
|
|
39
|
+
const dependencies = descendants.query('m2m_sp_widget_dependency')
|
|
40
|
+
const angularProviders = descendants.query('m2m_sp_ng_pro_sp_widget')
|
|
41
|
+
const templates = descendants.query('sp_ng_template').map((template) => {
|
|
42
|
+
return {
|
|
43
|
+
$id: template.getId(),
|
|
44
|
+
id: template.get('id'),
|
|
45
|
+
htmlTemplate: template.get('template'),
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const category = reverseObject(WidgetCategories)[record.get('category').ifString()?.getValue() || '']
|
|
50
|
+
const serverScript = await createIncludeShape(
|
|
51
|
+
record,
|
|
52
|
+
record.get('script'),
|
|
53
|
+
'server_script',
|
|
54
|
+
'js',
|
|
55
|
+
folderName,
|
|
56
|
+
tablePrefix
|
|
57
|
+
)
|
|
58
|
+
const clientScript = await createIncludeShape(
|
|
59
|
+
record,
|
|
60
|
+
record.get('client_script'),
|
|
61
|
+
'client_script',
|
|
62
|
+
'js',
|
|
63
|
+
folderName,
|
|
64
|
+
tablePrefix
|
|
65
|
+
)
|
|
66
|
+
const css = await createIncludeShape(record, record.get('css'), 'style', 'scss', folderName, tablePrefix)
|
|
67
|
+
const htmlTemplate = await createIncludeShape(
|
|
68
|
+
record,
|
|
69
|
+
record.get('template'),
|
|
70
|
+
'template',
|
|
71
|
+
'html',
|
|
72
|
+
folderName,
|
|
73
|
+
tablePrefix
|
|
74
|
+
)
|
|
75
|
+
const linkScript = await createIncludeShape(
|
|
76
|
+
record,
|
|
77
|
+
record.get('link'),
|
|
78
|
+
'link-script',
|
|
79
|
+
'js',
|
|
80
|
+
folderName,
|
|
81
|
+
tablePrefix
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
success: true,
|
|
86
|
+
value: new CallExpressionShape({
|
|
87
|
+
source: record,
|
|
88
|
+
callee,
|
|
89
|
+
args: [
|
|
90
|
+
record.transform(({ $ }) => {
|
|
91
|
+
const baseTransform = {
|
|
92
|
+
$id: $.val(NowIdShape.from(record)),
|
|
93
|
+
name: $,
|
|
94
|
+
category: $.val(category).def('custom'),
|
|
95
|
+
clientScript: $.val(clientScript).def(''),
|
|
96
|
+
serverScript: $.val(serverScript).def(''),
|
|
97
|
+
controllerAs: $.from('controller_as').def('c'),
|
|
98
|
+
htmlTemplate: $.val(htmlTemplate).def(''),
|
|
99
|
+
customCss: $.val(css).def(''),
|
|
100
|
+
dataTable: $.from('data_table')
|
|
101
|
+
.map((v: Shape) => {
|
|
102
|
+
const val = v.ifString()?.getValue()
|
|
103
|
+
return val && val.trim() !== '' ? val : 'sp_instance'
|
|
104
|
+
})
|
|
105
|
+
.def('sp_instance'),
|
|
106
|
+
demoData: $.from('demo_data')
|
|
107
|
+
.map((d: Shape) => {
|
|
108
|
+
const json = d.ifString()?.getValue()
|
|
109
|
+
|
|
110
|
+
const parsed = noThrow(() => json && JSON.parse(json))
|
|
111
|
+
return parsed instanceof Error ? json : parsed
|
|
112
|
+
})
|
|
113
|
+
.def(''),
|
|
114
|
+
description: $.def(''),
|
|
115
|
+
docs: $.def(''),
|
|
116
|
+
fields: $.from('field_list')
|
|
117
|
+
.map((fields: Shape) => {
|
|
118
|
+
const fieldStr = fields.ifString()?.getValue()
|
|
119
|
+
const fieldArray = fieldStr?.split(',').filter((f: string) => f.trim())
|
|
120
|
+
return fieldArray && fieldArray.length > 0 ? fieldArray : undefined
|
|
121
|
+
})
|
|
122
|
+
.def(undefined),
|
|
123
|
+
hasPreview: $.from('has_preview').toBoolean().def(false),
|
|
124
|
+
id: $.def(''),
|
|
125
|
+
internal: $.toBoolean().def(false),
|
|
126
|
+
linkScript: $.val(linkScript).def(''),
|
|
127
|
+
roles: $.map((role: Shape) => {
|
|
128
|
+
const roleStr = role.ifString()?.getValue()
|
|
129
|
+
const roleArray = roleStr?.split(',').filter((r: string) => r.trim())
|
|
130
|
+
return roleArray && roleArray.length > 0 ? roleArray : undefined
|
|
131
|
+
}).def(undefined),
|
|
132
|
+
servicenow: $.toBoolean().def(false),
|
|
133
|
+
optionSchema: $.from('option_schema')
|
|
134
|
+
.map((v: Shape) => {
|
|
135
|
+
const json = v.ifString()?.getValue()
|
|
136
|
+
const parsed = noThrow(() => json && JSON.parse(json))
|
|
137
|
+
const result = parsed instanceof Error ? json : parsed
|
|
138
|
+
return convertOptionSchemaKeys(result, toCamelCase)
|
|
139
|
+
})
|
|
140
|
+
.def(''),
|
|
141
|
+
public: $.toBoolean().def(false),
|
|
142
|
+
dependencies: $.val(
|
|
143
|
+
dependencies.length > 0 ? dependencies.map((dep) => dep.get('sp_dependency')) : undefined
|
|
144
|
+
),
|
|
145
|
+
angularProviders: $.val(
|
|
146
|
+
angularProviders.length > 0
|
|
147
|
+
? angularProviders.map((ap) => ap.get('sp_angular_provider'))
|
|
148
|
+
: undefined
|
|
149
|
+
),
|
|
150
|
+
templates: $.val(templates.length > 0 ? templates : undefined),
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return includeStaticField
|
|
154
|
+
? { ...baseTransform, static: $.from('static').toBoolean().def(false) }
|
|
155
|
+
: baseTransform
|
|
156
|
+
}),
|
|
157
|
+
],
|
|
158
|
+
}),
|
|
159
|
+
}
|
|
160
|
+
}
|
|
3
161
|
|
|
4
162
|
/**
|
|
5
163
|
* Creates a NowIncludeShape with a custom file path suffix and extension
|
|
@@ -9,9 +167,10 @@ export async function createIncludeShape(
|
|
|
9
167
|
content: string | Shape,
|
|
10
168
|
suffix: string,
|
|
11
169
|
extension: 'js' | 'html' | 'scss',
|
|
12
|
-
folderName: string
|
|
170
|
+
folderName: string,
|
|
171
|
+
tablePrefix: string = 'sp_widget'
|
|
13
172
|
): Promise<NowIncludeShape> {
|
|
14
|
-
const baseName =
|
|
173
|
+
const baseName = `${tablePrefix}_${folderName}`
|
|
15
174
|
const includedText = content instanceof Shape ? content.toString().getValue() : content
|
|
16
175
|
|
|
17
176
|
return new NowIncludeShape({
|
|
@@ -23,6 +182,248 @@ export async function createIncludeShape(
|
|
|
23
182
|
|
|
24
183
|
export const DEFAULT_ORDER = 100
|
|
25
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Shared toRecord implementation for SPWidget and SPHeaderFooter
|
|
187
|
+
*/
|
|
188
|
+
export async function createWidgetToRecord(
|
|
189
|
+
callExpression: CallExpressionShape,
|
|
190
|
+
{
|
|
191
|
+
diagnostics,
|
|
192
|
+
factory,
|
|
193
|
+
config,
|
|
194
|
+
}: {
|
|
195
|
+
diagnostics: Diagnostics
|
|
196
|
+
factory: Factory
|
|
197
|
+
config: { scope: string }
|
|
198
|
+
},
|
|
199
|
+
options: {
|
|
200
|
+
callee: 'SPWidget' | 'SPHeaderFooter'
|
|
201
|
+
table: 'sp_widget' | 'sp_header_footer'
|
|
202
|
+
includeStaticField?: boolean
|
|
203
|
+
getDefaultClientScript: (controller: string) => string
|
|
204
|
+
defaultServerScript: string
|
|
205
|
+
defaultLinkScript: string
|
|
206
|
+
defaultHtmlTemplate: string
|
|
207
|
+
}
|
|
208
|
+
) {
|
|
209
|
+
const { table, includeStaticField = false } = options
|
|
210
|
+
const widget = callExpression.getArgument(0).asObject()
|
|
211
|
+
const dependencies =
|
|
212
|
+
widget
|
|
213
|
+
.get('dependencies')
|
|
214
|
+
.ifArray()
|
|
215
|
+
?.map((dep) => (dep.isString() ? dep.getValue() : dep.ifRecord()?.getId()))
|
|
216
|
+
.filter((dep) => dep) ?? []
|
|
217
|
+
const angularProviders =
|
|
218
|
+
widget
|
|
219
|
+
.get('angularProviders')
|
|
220
|
+
.ifArray()
|
|
221
|
+
?.map((ap) => (ap.isString() ? ap.getValue() : ap.ifRecord()?.getId()))
|
|
222
|
+
.filter((ap) => ap) ?? []
|
|
223
|
+
|
|
224
|
+
const templates: Array<{ $id: string; id: unknown; htmlTemplate: unknown }> =
|
|
225
|
+
widget
|
|
226
|
+
.get('templates')
|
|
227
|
+
.ifArray()
|
|
228
|
+
?.map((shp) => shp.getValue() as { $id: string; id: unknown; htmlTemplate: unknown }) ?? []
|
|
229
|
+
const widgetId = widget.get('id').ifString()
|
|
230
|
+
if (widgetId && !/^[a-zA-Z0-9_-]+$/g.test(widgetId.getValue())) {
|
|
231
|
+
diagnostics.error(
|
|
232
|
+
widgetId.getOriginalNode(),
|
|
233
|
+
`Invalid value: must contain only alphanumeric, -, or _ characters`
|
|
234
|
+
)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const clientScript = widget.get('clientScript')
|
|
238
|
+
const clientScriptValue =
|
|
239
|
+
clientScript instanceof NowIncludeShape ? clientScript.getValue() : clientScript.ifString()?.getValue()
|
|
240
|
+
if (clientScriptValue && clientScriptValue.trim().length > 0) {
|
|
241
|
+
const clientScriptPattern =
|
|
242
|
+
/^(function|api\.controller\s?=\s?function)\s?([$a-z_][$0-9a-z_]*)?\s?\(.*\)\s?\n?{/i
|
|
243
|
+
if (!clientScriptPattern.test(clientScriptValue.trim())) {
|
|
244
|
+
diagnostics.error(
|
|
245
|
+
clientScript.getOriginalNode(),
|
|
246
|
+
`Client controller must contain a JavaScript function. Example: api.controller = function($scope) { ... }`
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const htmlTemplate = widget.get('htmlTemplate')
|
|
252
|
+
const htmlTemplateValue =
|
|
253
|
+
htmlTemplate instanceof NowIncludeShape ? htmlTemplate.getValue() : htmlTemplate.ifString()?.getValue()
|
|
254
|
+
if (htmlTemplateValue && htmlTemplateValue.length > 0 && htmlTemplateValue.indexOf('href="#"') > 0) {
|
|
255
|
+
diagnostics.error(
|
|
256
|
+
htmlTemplate.getOriginalNode(),
|
|
257
|
+
`Do not use href="#" in the Service Portal, use href="javascript:void(0)" instead`
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const roles = widget
|
|
262
|
+
.get('roles')
|
|
263
|
+
.ifArray()
|
|
264
|
+
?.map((role) => {
|
|
265
|
+
if (role.isString()) {
|
|
266
|
+
return role
|
|
267
|
+
}
|
|
268
|
+
if (role.isRecord()) {
|
|
269
|
+
return role.get('name')
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return undefined
|
|
273
|
+
})
|
|
274
|
+
.filter((role) => role) as Shape[] | undefined
|
|
275
|
+
|
|
276
|
+
if (roles) {
|
|
277
|
+
roles
|
|
278
|
+
.filter((role) => isGUID(role.getValue() as string))
|
|
279
|
+
.forEach((role) =>
|
|
280
|
+
diagnostics.error(
|
|
281
|
+
role!.getOriginalNode(),
|
|
282
|
+
`expecting role names or role records created by the Role or Record plugins, not sys_ids`
|
|
283
|
+
)
|
|
284
|
+
)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const controller = widget.get('controllerAs').ifString()?.getValue() || 'c'
|
|
288
|
+
const servicenow =
|
|
289
|
+
(widget.get('servicenow').ifBoolean()?.getValue() &&
|
|
290
|
+
(config.scope.startsWith('sn_') || config.scope.startsWith('snc_'))) ||
|
|
291
|
+
false
|
|
292
|
+
|
|
293
|
+
const widgetRecord = await factory.createRecord({
|
|
294
|
+
source: callExpression,
|
|
295
|
+
table,
|
|
296
|
+
explicitId: widget.get('$id'),
|
|
297
|
+
properties: widget.transform(({ $ }) => {
|
|
298
|
+
const baseTransform = {
|
|
299
|
+
name: $,
|
|
300
|
+
category: $.map((v) => {
|
|
301
|
+
const catKey = v.ifString()?.getValue() || ''
|
|
302
|
+
return WidgetCategories[catKey as keyof typeof WidgetCategories]
|
|
303
|
+
}).def('custom'),
|
|
304
|
+
client_script: $.from('clientScript').def(options.getDefaultClientScript(controller)),
|
|
305
|
+
script: $.from('serverScript').def(options.defaultServerScript),
|
|
306
|
+
controller_as: $.from('controllerAs').def('c'),
|
|
307
|
+
template: $.from('htmlTemplate').def(options.defaultHtmlTemplate),
|
|
308
|
+
css: $.from('customCss').def(''),
|
|
309
|
+
data_table: $.from('dataTable').def('sp_instance'),
|
|
310
|
+
demo_data: $.from('demoData')
|
|
311
|
+
.map((v) => (v.ifString() || v instanceof NowIncludeShape ? v : JSON.stringify(v.getValue())))
|
|
312
|
+
.def(''),
|
|
313
|
+
description: $.def(''),
|
|
314
|
+
docs: $.map((v) => (v.isString() ? v : v.ifRecord()?.getId())),
|
|
315
|
+
field_list: $.from('fields')
|
|
316
|
+
.map((v) => v.getValue()?.toString())
|
|
317
|
+
.def(''),
|
|
318
|
+
has_preview: $.from('hasPreview').toBoolean().def(false),
|
|
319
|
+
id: $.def(''),
|
|
320
|
+
internal: $.def(false),
|
|
321
|
+
servicenow: $.val(servicenow),
|
|
322
|
+
link: $.from('linkScript').def(options.defaultLinkScript),
|
|
323
|
+
roles: $.val(roles?.map((r) => r.getValue()).toString()).def(''),
|
|
324
|
+
option_schema: $.from('optionSchema')
|
|
325
|
+
.map((v) => {
|
|
326
|
+
const json = v.getValue()
|
|
327
|
+
const converted = convertOptionSchemaKeys(json, (key: string) =>
|
|
328
|
+
key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`)
|
|
329
|
+
)
|
|
330
|
+
return converted && JSON.stringify(converted)
|
|
331
|
+
})
|
|
332
|
+
.def(''),
|
|
333
|
+
public: $.def(false),
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return includeStaticField
|
|
337
|
+
? { ...baseTransform, static: $.from('static').toBoolean().def(false) }
|
|
338
|
+
: baseTransform
|
|
339
|
+
}),
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
return {
|
|
343
|
+
success: true,
|
|
344
|
+
value: widgetRecord.with(
|
|
345
|
+
...(await Promise.all(
|
|
346
|
+
templates.map(async (template) => {
|
|
347
|
+
return await factory.createRecord({
|
|
348
|
+
source: callExpression,
|
|
349
|
+
table: 'sp_ng_template',
|
|
350
|
+
explicitId: template.$id,
|
|
351
|
+
properties: {
|
|
352
|
+
id: template.id,
|
|
353
|
+
sp_widget: widgetRecord.getId(),
|
|
354
|
+
template: template.htmlTemplate,
|
|
355
|
+
},
|
|
356
|
+
})
|
|
357
|
+
})
|
|
358
|
+
)),
|
|
359
|
+
...(await Promise.all(
|
|
360
|
+
dependencies.map(async (dep) => {
|
|
361
|
+
return await factory.createRecord({
|
|
362
|
+
source: callExpression,
|
|
363
|
+
table: 'm2m_sp_widget_dependency',
|
|
364
|
+
properties: {
|
|
365
|
+
sp_dependency: dep!,
|
|
366
|
+
sp_widget: widgetRecord.getId(),
|
|
367
|
+
},
|
|
368
|
+
})
|
|
369
|
+
})
|
|
370
|
+
)),
|
|
371
|
+
...(await Promise.all(
|
|
372
|
+
angularProviders.map(async (ap) => {
|
|
373
|
+
return await factory.createRecord({
|
|
374
|
+
source: callExpression,
|
|
375
|
+
table: 'm2m_sp_ng_pro_sp_widget',
|
|
376
|
+
properties: {
|
|
377
|
+
sp_angular_provider: ap!,
|
|
378
|
+
sp_widget: widgetRecord.getId(),
|
|
379
|
+
},
|
|
380
|
+
})
|
|
381
|
+
})
|
|
382
|
+
))
|
|
383
|
+
),
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Converts a roles Shape (array of strings, Role() expressions, or Record references)
|
|
389
|
+
* to a deduplicated comma-separated string of role names.
|
|
390
|
+
* @param rolesShape - Shape containing the roles array
|
|
391
|
+
* @param diagnostics - Optional diagnostics for reporting invalid role entries
|
|
392
|
+
* @returns Comma-separated string of unique role names, or empty string if no roles
|
|
393
|
+
*/
|
|
394
|
+
export function getRolesString(rolesShape: Shape, diagnostics?: Diagnostics): string {
|
|
395
|
+
const roles = rolesShape
|
|
396
|
+
.ifArray()
|
|
397
|
+
?.getElements()
|
|
398
|
+
.map((role) => {
|
|
399
|
+
if (role.isString()) {
|
|
400
|
+
return role.getValue()
|
|
401
|
+
}
|
|
402
|
+
if (role instanceof CallExpressionShape) {
|
|
403
|
+
const name = role.getArgument(0).asObject().get('name')
|
|
404
|
+
if (name.isString()) {
|
|
405
|
+
return name.getValue()
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (role.isRecord()) {
|
|
409
|
+
const name = role.get('name')
|
|
410
|
+
if (name?.isString()) {
|
|
411
|
+
return name.getValue()
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (diagnostics) {
|
|
415
|
+
diagnostics.error(role, 'roles must be strings or role records')
|
|
416
|
+
}
|
|
417
|
+
return undefined
|
|
418
|
+
})
|
|
419
|
+
.filter((r): r is string => r !== undefined && r.trim() !== '')
|
|
420
|
+
|
|
421
|
+
if (!roles || roles.length === 0) {
|
|
422
|
+
return ''
|
|
423
|
+
}
|
|
424
|
+
return [...new Set(roles)].join(',')
|
|
425
|
+
}
|
|
426
|
+
|
|
26
427
|
export async function getIncludeRecords(
|
|
27
428
|
shape: Shape,
|
|
28
429
|
parentId: Shape,
|