@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
package/src/record-plugin.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
ServicePortal,
|
|
18
18
|
SPWidget,
|
|
19
|
+
SPHeaderFooter,
|
|
19
20
|
SPAngularProvider,
|
|
20
21
|
SPWidgetDependency,
|
|
21
22
|
CssInclude,
|
|
@@ -23,6 +24,7 @@ import {
|
|
|
23
24
|
SPPage,
|
|
24
25
|
SPTheme,
|
|
25
26
|
SPMenu,
|
|
27
|
+
SPPageRouteMap,
|
|
26
28
|
} from '@servicenow/sdk-core/runtime/service-portal'
|
|
27
29
|
import {
|
|
28
30
|
CatalogItem,
|
|
@@ -33,11 +35,12 @@ import {
|
|
|
33
35
|
} from '@servicenow/sdk-core/runtime/service-catalog'
|
|
34
36
|
import { ClientScript } from '@servicenow/sdk-core/runtime/clientscript'
|
|
35
37
|
import { ScriptAction, ScriptInclude, ScheduledScript } from '@servicenow/sdk-core/runtime/sys'
|
|
36
|
-
import { List } from '@servicenow/sdk-core/runtime/ui'
|
|
38
|
+
import { List, Form } from '@servicenow/sdk-core/runtime/ui'
|
|
37
39
|
import { Table } from '@servicenow/sdk-core/runtime/db'
|
|
38
40
|
import { RestApi } from '@servicenow/sdk-core/runtime/rest'
|
|
39
|
-
import { EmailNotification } from '@servicenow/sdk-core/runtime/notification'
|
|
41
|
+
import { EmailNotification, InboundEmailAction } from '@servicenow/sdk-core/runtime/notification'
|
|
40
42
|
import { UiAction, UiPage, UiPolicy } from '@servicenow/sdk-core/runtime/ui'
|
|
43
|
+
import { ActionStepDefinition } from '@servicenow/sdk-core/runtime/flow'
|
|
41
44
|
import { Applicability, UxListMenuConfig, Workspace } from '@servicenow/sdk-core/runtime/uxf'
|
|
42
45
|
import { Dashboard } from '@servicenow/sdk-core/runtime/dashboard'
|
|
43
46
|
import { ColumnTypeCheck, LinterCheck, ScriptOnlyCheck, TableCheck } from '@servicenow/sdk-core/runtime/instancescan'
|
|
@@ -223,6 +226,10 @@ export const TableOwnership = {
|
|
|
223
226
|
sys_script: BusinessRule.name,
|
|
224
227
|
sys_script_client: ClientScript.name,
|
|
225
228
|
sys_scope_privilege: CrossScopePrivilege.name,
|
|
229
|
+
sys_ui_form: Form.name,
|
|
230
|
+
sys_ui_section: Form.name,
|
|
231
|
+
sys_ui_form_section: Form.name,
|
|
232
|
+
sys_ui_element: Form.name,
|
|
226
233
|
sys_ui_list_element: List.name,
|
|
227
234
|
sys_ui_list: List.name,
|
|
228
235
|
sys_properties: Property.name,
|
|
@@ -230,6 +237,7 @@ export const TableOwnership = {
|
|
|
230
237
|
sys_user_role_contains: Role.name,
|
|
231
238
|
sys_script_include: ScriptInclude.name,
|
|
232
239
|
sp_widget: SPWidget.name,
|
|
240
|
+
sp_header_footer: SPHeaderFooter.name,
|
|
233
241
|
m2m_sp_widget_dependency: SPWidget.name,
|
|
234
242
|
m2m_sp_ng_pro_sp_widget: SPWidget.name,
|
|
235
243
|
sp_portal: ServicePortal.name,
|
|
@@ -248,6 +256,7 @@ export const TableOwnership = {
|
|
|
248
256
|
m2m_sp_ng_pro_sp_ng_pro: SPAngularProvider.name,
|
|
249
257
|
sp_instance_menu: SPMenu.name,
|
|
250
258
|
sp_rectangle_menu_item: SPMenu.name,
|
|
259
|
+
sp_page_route_map: SPPageRouteMap.name,
|
|
251
260
|
sys_atf_test: Test.name,
|
|
252
261
|
sys_ws_header_map: RestApi.name,
|
|
253
262
|
sys_ws_query_parameter_map: RestApi.name,
|
|
@@ -267,6 +276,7 @@ export const TableOwnership = {
|
|
|
267
276
|
sysevent_script_action: ScriptAction.name,
|
|
268
277
|
sysauto_script: ScheduledScript.name,
|
|
269
278
|
sysevent_email_action: EmailNotification.name,
|
|
279
|
+
sysevent_in_email_action: InboundEmailAction.name,
|
|
270
280
|
sys_db_object: Table.name,
|
|
271
281
|
sys_dictionary: Table.name,
|
|
272
282
|
sys_hub_flow: 'Flow',
|
|
@@ -274,10 +284,10 @@ export const TableOwnership = {
|
|
|
274
284
|
sys_hub_action_instance_v2: 'wfa.action',
|
|
275
285
|
sys_hub_sub_flow_instance_v2: 'wfa.subflow',
|
|
276
286
|
sys_hub_flow_logic_instance_v2: 'wfa.flowLogic',
|
|
277
|
-
sys_flow_step_definition:
|
|
287
|
+
sys_flow_step_definition: ActionStepDefinition.name,
|
|
278
288
|
sys_decision: 'DecisionTablePlugin',
|
|
279
289
|
sys_hub_action_type_definition: 'Action',
|
|
280
|
-
sys_hub_step_instance: 'wfa.
|
|
290
|
+
sys_hub_step_instance: 'wfa.actionStep',
|
|
281
291
|
sp_theme: SPTheme.name,
|
|
282
292
|
m2m_sp_theme_css_include: SPTheme.name,
|
|
283
293
|
m2m_sp_theme_js_include: SPTheme.name,
|
package/src/rest-api-plugin.ts
CHANGED
|
@@ -183,6 +183,7 @@ async function generateRouteAttributeRecords(
|
|
|
183
183
|
installCategory: restDef.getInstallCategory(),
|
|
184
184
|
})
|
|
185
185
|
|
|
186
|
+
const isShared = attrMap.has(attrRecord.getId().getValue())
|
|
186
187
|
checkForDuplicateRecords(attrMap, attrRecord, attr.asObject(), diagnostics)
|
|
187
188
|
|
|
188
189
|
const attributeMappingRecord = await factory.createRecord({
|
|
@@ -195,7 +196,12 @@ async function generateRouteAttributeRecords(
|
|
|
195
196
|
installCategory: restDef.getInstallCategory(),
|
|
196
197
|
})
|
|
197
198
|
|
|
198
|
-
|
|
199
|
+
if (isShared) {
|
|
200
|
+
// The attrRecord was already emitted by a previous route — only emit the mapping
|
|
201
|
+
records.push(attributeMappingRecord)
|
|
202
|
+
} else {
|
|
203
|
+
records.push(attrRecord.with(attributeMappingRecord))
|
|
204
|
+
}
|
|
199
205
|
}
|
|
200
206
|
|
|
201
207
|
return records
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from '@servicenow/sdk-build-core'
|
|
10
10
|
import { NowIdShape } from '../now-id-plugin'
|
|
11
11
|
import { NowIncludeShape } from '../now-include-plugin'
|
|
12
|
+
import { ModuleFunctionShape } from '../server-module-plugin'
|
|
12
13
|
import { createSdkDocEntry, toReference } from '../utils'
|
|
13
14
|
import { dateTimeFieldToXML, convertXMLToDateTime, formatTimeDataToDateTime, formatToUTC } from './timeZoneConverter'
|
|
14
15
|
|
|
@@ -444,13 +445,21 @@ export const ScheduledScriptPlugin = Plugin.create({
|
|
|
444
445
|
{
|
|
445
446
|
shape: CallExpressionShape,
|
|
446
447
|
fileTypes: ['fluent'],
|
|
447
|
-
async toRecord(callExpression, { factory, diagnostics }) {
|
|
448
|
+
async toRecord(callExpression, { factory, diagnostics, config }) {
|
|
448
449
|
if (callExpression.getCallee() !== 'ScheduledScript') {
|
|
449
450
|
return { success: false }
|
|
450
451
|
}
|
|
451
452
|
|
|
452
453
|
const args = callExpression.getArgument(0).asObject()
|
|
453
454
|
|
|
455
|
+
// Check if script is unresolved module
|
|
456
|
+
if (args.get('script').isUnresolved()) {
|
|
457
|
+
diagnostics.error(
|
|
458
|
+
args.get('script').getOriginalNode(),
|
|
459
|
+
`Unable to resolve the script reference, ensure the imported module is within the ${config.serverModulesDir} directory.`
|
|
460
|
+
)
|
|
461
|
+
}
|
|
462
|
+
|
|
454
463
|
// Validate executionInterval is defined when frequency is 'periodically'
|
|
455
464
|
const frequency = args.get('frequency').ifString()?.getValue()
|
|
456
465
|
if (frequency === 'periodically' && args.get('executionInterval').isUndefined()) {
|
|
@@ -667,8 +676,10 @@ export const ScheduledScriptPlugin = Plugin.create({
|
|
|
667
676
|
// Protection policy
|
|
668
677
|
sys_policy: $.from('protectionPolicy'),
|
|
669
678
|
|
|
670
|
-
// Script
|
|
671
|
-
script: $.
|
|
679
|
+
// Script - handle both module functions and strings
|
|
680
|
+
script: $.map(
|
|
681
|
+
(v) => v.if(ModuleFunctionShape)?.toString((n) => `${n}({{PARAMS}})`, []) ?? v
|
|
682
|
+
).toCdata(),
|
|
672
683
|
})),
|
|
673
684
|
})
|
|
674
685
|
|
|
@@ -255,6 +255,17 @@ export function transformCatalogBaseFieldsToShape(record: Record, $: ShapeTransf
|
|
|
255
255
|
visibleBundle: $.from('visible_bundle').toBoolean().def(true),
|
|
256
256
|
visibleGuide: $.from('visible_guide').toBoolean().def(true),
|
|
257
257
|
visibleStandalone: $.from('visible_standalone').toBoolean().def(true),
|
|
258
|
+
hideAddToCart: $.from('no_cart_v2').toBoolean().def(false),
|
|
259
|
+
hideAddToWishList: $.from('no_wishlist_v2').toBoolean().def(false),
|
|
260
|
+
hideDeliveryTime: $.from('no_delivery_time_v2').toBoolean().def(false),
|
|
261
|
+
hideQuantitySelector: $.from('no_quantity_v2').toBoolean().def(false),
|
|
262
|
+
hideSP: $.from('hide_sp').toBoolean().def(false),
|
|
263
|
+
image: $.def(''),
|
|
264
|
+
model: $.def(''),
|
|
265
|
+
mobilePictureType: $.from('mobile_picture_type')
|
|
266
|
+
.map((v: Shape) => getMobilePictureTypeFromDb(v.toString().getValue()))
|
|
267
|
+
.def('desktopPicture'),
|
|
268
|
+
makeItemNonConversational: $.from('make_item_non_conversational').toBoolean().def(false),
|
|
258
269
|
}
|
|
259
270
|
}
|
|
260
271
|
|
|
@@ -327,6 +338,17 @@ export function transformCatalogItemBaseFieldsToRecord($: ShapeTransform) {
|
|
|
327
338
|
visible_bundle: $.from('visibleBundle').def(true),
|
|
328
339
|
visible_guide: $.from('visibleGuide').def(true),
|
|
329
340
|
visible_standalone: $.from('visibleStandalone').def(true),
|
|
341
|
+
no_cart_v2: $.from('hideAddToCart').def(false),
|
|
342
|
+
no_wishlist_v2: $.from('hideAddToWishList').def(false),
|
|
343
|
+
no_delivery_time_v2: $.from('hideDeliveryTime').def(false),
|
|
344
|
+
no_quantity_v2: $.from('hideQuantitySelector').def(false),
|
|
345
|
+
hide_sp: $.from('hideSP').def(false),
|
|
346
|
+
image: $.def(''),
|
|
347
|
+
model: $.def(''),
|
|
348
|
+
mobile_picture_type: $.from('mobilePictureType')
|
|
349
|
+
.map((v: Shape) => getMobilePictureTypeToDb(v.toString().getValue()))
|
|
350
|
+
.def('use_desktop_picture'),
|
|
351
|
+
make_item_non_conversational: $.from('makeItemNonConversational').def(false),
|
|
330
352
|
}
|
|
331
353
|
}
|
|
332
354
|
|
|
@@ -375,9 +397,6 @@ export function transformCatalogItemSpecificFieldsToShape(record: Record, $: Sha
|
|
|
375
397
|
requestMethod: $.from('request_method')
|
|
376
398
|
.map((v: Shape) => (v.ifString()?.isEmpty() ? undefined : v.getValue()))
|
|
377
399
|
.def('order'),
|
|
378
|
-
hideAddToCart: $.from('no_cart_v2').toBoolean().def(false),
|
|
379
|
-
hideQuantitySelector: $.from('no_quantity_v2').toBoolean().def(false),
|
|
380
|
-
hideDeliveryTime: $.from('no_delivery_time_v2').toBoolean().def(false),
|
|
381
400
|
customCart: $.from('custom_cart').def(''),
|
|
382
401
|
recurringFrequency: $.from('recurring_frequency').def(''),
|
|
383
402
|
|
|
@@ -388,16 +407,8 @@ export function transformCatalogItemSpecificFieldsToShape(record: Record, $: Sha
|
|
|
388
407
|
noProceedCheckout: $.from('no_proceed_checkout').toBoolean().def(false),
|
|
389
408
|
noQuantity: $.from('no_quantity').toBoolean().def(false),
|
|
390
409
|
noSearch: $.from('no_search').toBoolean().def(false),
|
|
391
|
-
hideAddToWishList: $.from('no_wishlist_v2').toBoolean().def(false),
|
|
392
410
|
|
|
393
411
|
// Additional fields
|
|
394
|
-
hideSP: $.from('hide_sp').toBoolean().def(false),
|
|
395
|
-
image: $.def(''),
|
|
396
|
-
makeItemNonConversational: $.from('make_item_non_conversational').toBoolean().def(false),
|
|
397
|
-
mobilePictureType: $.from('mobile_picture_type')
|
|
398
|
-
.map((v: Shape) => getMobilePictureTypeFromDb(v.toString().getValue()))
|
|
399
|
-
.def('desktopPicture'),
|
|
400
|
-
model: $.def(''),
|
|
401
412
|
vendor: $.def(''),
|
|
402
413
|
location: $.def(''),
|
|
403
414
|
}
|
|
@@ -448,9 +459,6 @@ export function transformCatalogItemSpecificFieldsToRecord(arg: ObjectShape, $:
|
|
|
448
459
|
request_method: $.from('requestMethod')
|
|
449
460
|
.map((v: Shape) => (v.ifString()?.getValue() === 'order' ? '' : v.getValue()))
|
|
450
461
|
.def(''),
|
|
451
|
-
no_cart_v2: $.from('hideAddToCart').def(false),
|
|
452
|
-
no_quantity_v2: $.from('hideQuantitySelector').def(false),
|
|
453
|
-
no_delivery_time_v2: $.from('hideDeliveryTime').def(false),
|
|
454
462
|
custom_cart: $.from('customCart').def(''),
|
|
455
463
|
recurring_frequency: $.from('recurringFrequency').def(''),
|
|
456
464
|
|
|
@@ -461,16 +469,8 @@ export function transformCatalogItemSpecificFieldsToRecord(arg: ObjectShape, $:
|
|
|
461
469
|
no_proceed_checkout: $.from('noProceedCheckout').def(false),
|
|
462
470
|
no_quantity: $.from('noQuantity').def(false),
|
|
463
471
|
no_search: $.from('noSearch').def(false),
|
|
464
|
-
no_wishlist_v2: $.from('hideAddToWishList').def(false),
|
|
465
472
|
|
|
466
473
|
// Additional
|
|
467
|
-
hide_sp: $.from('hideSP').def(false),
|
|
468
|
-
image: $.def(''),
|
|
469
|
-
make_item_non_conversational: $.from('makeItemNonConversational').def(false),
|
|
470
|
-
mobile_picture_type: $.from('mobilePictureType')
|
|
471
|
-
.map((v: Shape) => getMobilePictureTypeToDb(v.toString().getValue()))
|
|
472
|
-
.def('use_desktop_picture'),
|
|
473
|
-
model: $.def(''),
|
|
474
474
|
vendor: $.def(''),
|
|
475
475
|
location: $.def(''),
|
|
476
476
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CallExpressionShape, Plugin } from '@servicenow/sdk-build-core'
|
|
2
|
+
import { createSdkDocEntry } from '../utils'
|
|
3
|
+
import { createWidgetToRecord, createWidgetToShape } from './utils'
|
|
4
|
+
import {
|
|
5
|
+
getDefaultClientScript,
|
|
6
|
+
SP_WIDGET_DEFAULT_HTML_TEMPLATE,
|
|
7
|
+
SP_WIDGET_DEFAULT_LINK_SCRIPT,
|
|
8
|
+
SP_WIDGET_DEFAULT_SERVER_SCRIPT,
|
|
9
|
+
} from './widget-plugin'
|
|
10
|
+
|
|
11
|
+
export const SPHeaderFooterPlugin = Plugin.create({
|
|
12
|
+
name: 'SPHeaderFooterPlugin',
|
|
13
|
+
docs: [createSdkDocEntry('SPHeaderFooter', ['sp_header_footer'])],
|
|
14
|
+
records: {
|
|
15
|
+
sp_header_footer: {
|
|
16
|
+
relationships: {
|
|
17
|
+
m2m_sp_widget_dependency: { via: 'sp_widget', descendant: true },
|
|
18
|
+
m2m_sp_ng_pro_sp_widget: { via: 'sp_widget', descendant: true },
|
|
19
|
+
sp_ng_template: { via: 'sp_widget', descendant: true },
|
|
20
|
+
},
|
|
21
|
+
async toShape(record, { descendants }) {
|
|
22
|
+
return createWidgetToShape(record, descendants, 'SPHeaderFooter', 'sp_header_footer', true)
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
m2m_sp_widget_dependency: {
|
|
26
|
+
coalesce: ['sp_widget', 'sp_dependency'],
|
|
27
|
+
},
|
|
28
|
+
m2m_sp_ng_pro_sp_widget: {
|
|
29
|
+
coalesce: ['sp_widget', 'sp_angular_provider'],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
shapes: [
|
|
33
|
+
{
|
|
34
|
+
shape: CallExpressionShape,
|
|
35
|
+
fileTypes: ['fluent'],
|
|
36
|
+
async toRecord(callExpression, { diagnostics, factory, config }) {
|
|
37
|
+
if (callExpression.getCallee() !== 'SPHeaderFooter') {
|
|
38
|
+
return { success: false }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return createWidgetToRecord(
|
|
42
|
+
callExpression,
|
|
43
|
+
{ diagnostics, factory, config },
|
|
44
|
+
{
|
|
45
|
+
callee: 'SPHeaderFooter',
|
|
46
|
+
table: 'sp_header_footer',
|
|
47
|
+
includeStaticField: true,
|
|
48
|
+
getDefaultClientScript,
|
|
49
|
+
defaultServerScript: SP_WIDGET_DEFAULT_SERVER_SCRIPT,
|
|
50
|
+
defaultLinkScript: SP_WIDGET_DEFAULT_LINK_SCRIPT,
|
|
51
|
+
defaultHtmlTemplate: SP_WIDGET_DEFAULT_HTML_TEMPLATE,
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
})
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import { NowIdShape } from '../now-id-plugin'
|
|
11
11
|
import { NowIncludeShape } from '../now-include-plugin'
|
|
12
12
|
import { toReference, getFieldAsNumber, noThrow, createSdkDocEntry } from '../utils'
|
|
13
|
+
import { getRolesString } from './utils'
|
|
13
14
|
|
|
14
15
|
const default_placeholder_dimensions = `{
|
|
15
16
|
"mobile": {
|
|
@@ -73,29 +74,6 @@ const defaultValues = {
|
|
|
73
74
|
},
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
function getRolesString(rolesShape: Shape, diagnostics: Diagnostics): string {
|
|
77
|
-
const roles = rolesShape
|
|
78
|
-
?.ifArray()
|
|
79
|
-
?.map((role) => {
|
|
80
|
-
if (role.isString()) {
|
|
81
|
-
return role.getValue()
|
|
82
|
-
}
|
|
83
|
-
if (role.isRecord()) {
|
|
84
|
-
const name = role.get('name')
|
|
85
|
-
if (name?.isString()) {
|
|
86
|
-
return name.getValue()
|
|
87
|
-
}
|
|
88
|
-
return role.getId()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
diagnostics.error(role, `roles must be strings or role records`)
|
|
92
|
-
return undefined
|
|
93
|
-
})
|
|
94
|
-
.filter((r) => r) as string[] | undefined
|
|
95
|
-
|
|
96
|
-
return roles?.toString() ?? ''
|
|
97
|
-
}
|
|
98
|
-
|
|
99
77
|
const addProperty = (obj: { [key: string]: unknown }, key: string, value: unknown) => {
|
|
100
78
|
if (
|
|
101
79
|
value === undefined ||
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
type Record,
|
|
7
7
|
type RecordId,
|
|
8
8
|
type Shape,
|
|
9
|
-
type ArrayShape,
|
|
10
9
|
type ObjectShape,
|
|
11
10
|
} from '@servicenow/sdk-build-core'
|
|
12
11
|
import isEmpty from 'lodash/isEmpty'
|
|
13
12
|
import { toReference, getFieldAsNumber, createSdkDocEntry } from '../utils'
|
|
13
|
+
import { getRolesString } from './utils'
|
|
14
14
|
|
|
15
15
|
type Dict = { [key: string]: unknown }
|
|
16
16
|
|
|
@@ -292,29 +292,6 @@ function getInstanceObject(instance: Record): object | undefined {
|
|
|
292
292
|
return instanceObject
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
/**
|
|
296
|
-
* Converts an ArrayShape of roles to a comma-separated string.
|
|
297
|
-
* Handles both role record objects and string values, removes duplicates and empty values.
|
|
298
|
-
* @param roles - ArrayShape containing role records or strings
|
|
299
|
-
* @returns Comma-separated string of unique role names or undefined if no roles
|
|
300
|
-
*/
|
|
301
|
-
function getRolesString(roles: ArrayShape | undefined): string | undefined {
|
|
302
|
-
if (!roles) {
|
|
303
|
-
return
|
|
304
|
-
}
|
|
305
|
-
const uniqueRoles = [
|
|
306
|
-
...new Set(
|
|
307
|
-
roles.getElements().map((role) => {
|
|
308
|
-
const roleName = role.isRecord()
|
|
309
|
-
? role.get('name')?.ifString()?.getValue()
|
|
310
|
-
: role.ifString()?.getValue()
|
|
311
|
-
return (roleName ?? '').trim()
|
|
312
|
-
})
|
|
313
|
-
),
|
|
314
|
-
]
|
|
315
|
-
return uniqueRoles.filter((role) => role !== '').join(',')
|
|
316
|
-
}
|
|
317
|
-
|
|
318
295
|
/**
|
|
319
296
|
* Recursively processes nested rows within a column
|
|
320
297
|
* @param columnRows - Rows that belong to the column
|
|
@@ -548,8 +525,7 @@ async function createInstanceRecords(instancesArray: Shape[], columnId: RecordId
|
|
|
548
525
|
const instance = instanceShape.asObject()
|
|
549
526
|
|
|
550
527
|
// Process roles if they exist as an array
|
|
551
|
-
const
|
|
552
|
-
const rolesString = getRolesString(rolesArray)
|
|
528
|
+
const rolesString = getRolesString(instance.get('roles'))
|
|
553
529
|
|
|
554
530
|
const instanceRecord = await factory.createRecord({
|
|
555
531
|
source: instanceShape,
|
|
@@ -749,8 +725,7 @@ export const SPPagePlugin = Plugin.create({
|
|
|
749
725
|
}
|
|
750
726
|
|
|
751
727
|
// Process roles if they exist as an array
|
|
752
|
-
const
|
|
753
|
-
const rolesString = getRolesString(rolesArray)
|
|
728
|
+
const rolesString = getRolesString(page.get('roles'))
|
|
754
729
|
|
|
755
730
|
const pageIdShape = page.get('pageId')
|
|
756
731
|
const pageId = pageIdShape.asString().getValue()
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { CallExpressionShape, Plugin, type Shape } from '@servicenow/sdk-build-core'
|
|
2
|
+
import { NowIdShape } from '../now-id-plugin'
|
|
3
|
+
import { toReference, createSdkDocEntry } from '../utils'
|
|
4
|
+
import { getRolesString } from './utils'
|
|
5
|
+
|
|
6
|
+
function getPortalsString(portalsShape: Shape): string {
|
|
7
|
+
const portals = portalsShape
|
|
8
|
+
.ifArray()
|
|
9
|
+
?.getElements()
|
|
10
|
+
.map((p) => {
|
|
11
|
+
const ref = toReference(p)
|
|
12
|
+
return typeof ref === 'string' ? ref : ref.getValue()
|
|
13
|
+
})
|
|
14
|
+
.filter((id) => id !== '')
|
|
15
|
+
|
|
16
|
+
if (!portals || portals.length === 0) {
|
|
17
|
+
return ''
|
|
18
|
+
}
|
|
19
|
+
return [...new Set(portals)].join(',')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const SPPageRouteMapPlugin = Plugin.create({
|
|
23
|
+
name: 'SPPageRouteMapPlugin',
|
|
24
|
+
docs: [createSdkDocEntry('SPPageRouteMap', ['sp_page_route_map'])],
|
|
25
|
+
records: {
|
|
26
|
+
sp_page_route_map: {
|
|
27
|
+
coalesce: ['route_from_page', 'portals'],
|
|
28
|
+
toShape(record) {
|
|
29
|
+
const portalsStr = record.get('portals').ifString()?.getValue() ?? ''
|
|
30
|
+
const portalsArray = portalsStr
|
|
31
|
+
? portalsStr
|
|
32
|
+
.split(',')
|
|
33
|
+
.map((p) => p.trim())
|
|
34
|
+
.filter((p) => p !== '')
|
|
35
|
+
: []
|
|
36
|
+
|
|
37
|
+
const rolesStr = record.get('roles').ifString()?.getValue() ?? ''
|
|
38
|
+
const rolesArray = rolesStr
|
|
39
|
+
? rolesStr
|
|
40
|
+
.split(',')
|
|
41
|
+
.map((r) => r.trim())
|
|
42
|
+
.filter((r) => r !== '')
|
|
43
|
+
: []
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
value: new CallExpressionShape({
|
|
48
|
+
source: record,
|
|
49
|
+
callee: 'SPPageRouteMap',
|
|
50
|
+
args: [
|
|
51
|
+
record.transform(({ $ }) => {
|
|
52
|
+
const config: { [key: string]: typeof $ | undefined } = {
|
|
53
|
+
$id: $.val(NowIdShape.from(record)),
|
|
54
|
+
routeFromPage: $.from('route_from_page'),
|
|
55
|
+
routeToPage: $.from('route_to_page'),
|
|
56
|
+
shortDescription: $.from('short_description').def(''),
|
|
57
|
+
active: $.from('active').toBoolean().def(true),
|
|
58
|
+
order: $.from('order').toNumber().def(10),
|
|
59
|
+
}
|
|
60
|
+
if (portalsArray.length > 0) {
|
|
61
|
+
config['portals'] = $.val(portalsArray)
|
|
62
|
+
}
|
|
63
|
+
if (rolesArray.length > 0) {
|
|
64
|
+
config['roles'] = $.val(rolesArray)
|
|
65
|
+
}
|
|
66
|
+
return config
|
|
67
|
+
}),
|
|
68
|
+
],
|
|
69
|
+
}),
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
shapes: [
|
|
75
|
+
{
|
|
76
|
+
shape: CallExpressionShape,
|
|
77
|
+
fileTypes: ['fluent'],
|
|
78
|
+
async toRecord(callExpression, { factory, diagnostics }) {
|
|
79
|
+
if (callExpression.getCallee() !== 'SPPageRouteMap') {
|
|
80
|
+
return { success: false }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const args = callExpression.getArgument(0).asObject()
|
|
84
|
+
|
|
85
|
+
const routeFromShape = args.get('routeFromPage')
|
|
86
|
+
const routeToShape = args.get('routeToPage')
|
|
87
|
+
const routeFromRef = toReference(routeFromShape)
|
|
88
|
+
const routeToRef = toReference(routeToShape)
|
|
89
|
+
const routeFromStr = typeof routeFromRef === 'string' ? routeFromRef : routeFromRef.getValue()
|
|
90
|
+
const routeToStr = typeof routeToRef === 'string' ? routeToRef : routeToRef.getValue()
|
|
91
|
+
|
|
92
|
+
if (routeFromStr !== '' && routeToStr !== '' && routeFromStr === routeToStr) {
|
|
93
|
+
diagnostics.error(
|
|
94
|
+
routeToShape.getOriginalNode(),
|
|
95
|
+
`Invalid SPPageRouteMap: "routeToPage" must be different from "routeFromPage".`
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const portalsString = getPortalsString(args.get('portals'))
|
|
100
|
+
const rolesString = getRolesString(args.get('roles'), diagnostics)
|
|
101
|
+
|
|
102
|
+
const routeMapRecord = await factory.createRecord({
|
|
103
|
+
source: callExpression,
|
|
104
|
+
table: 'sp_page_route_map',
|
|
105
|
+
explicitId: args.get('$id'),
|
|
106
|
+
properties: args.transform(({ $ }) => ({
|
|
107
|
+
route_from_page: $.from('routeFromPage').map(toReference).def(''),
|
|
108
|
+
route_to_page: $.from('routeToPage').map(toReference).def(''),
|
|
109
|
+
short_description: $.from('shortDescription').def(''),
|
|
110
|
+
portals: $.val(portalsString).def(''),
|
|
111
|
+
roles: $.val(rolesString).def(''),
|
|
112
|
+
active: $.def(true),
|
|
113
|
+
order: $.def(10),
|
|
114
|
+
})),
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
success: true,
|
|
119
|
+
value: routeMapRecord,
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
})
|
|
@@ -173,17 +173,40 @@ export const ServicePortalPlugin = Plugin.create({
|
|
|
173
173
|
)
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
-
// Extract first catalog and knowledgeBase from arrays to populate portal fields
|
|
177
176
|
const catalogsForM2M = portalArgs.get('catalogs')?.ifArray()?.getElements() ?? []
|
|
178
177
|
const knowledgeBasesForM2M = portalArgs.get('knowledgeBases')?.ifArray()?.getElements() ?? []
|
|
179
|
-
const firstCatalogFromArray =
|
|
180
|
-
catalogsForM2M.length > 0 ? catalogsForM2M[0]?.asObject()?.get('catalog') : undefined
|
|
181
|
-
const firstKnowledgeBaseFromArray =
|
|
182
|
-
knowledgeBasesForM2M.length > 0
|
|
183
|
-
? knowledgeBasesForM2M[0]?.asObject()?.get('knowledgeBase')
|
|
184
|
-
: undefined
|
|
185
178
|
|
|
186
|
-
|
|
179
|
+
const deprecatedKnowledgeBase = portalArgs.get('knowledgeBase')
|
|
180
|
+
if (deprecatedKnowledgeBase?.isDefined()) {
|
|
181
|
+
if (knowledgeBasesForM2M.length > 0) {
|
|
182
|
+
diagnostics.error(
|
|
183
|
+
deprecatedKnowledgeBase.getOriginalNode(),
|
|
184
|
+
`Cannot use both 'knowledgeBase' and 'knowledgeBases'. Remove 'knowledgeBase' and use only the 'knowledgeBases' array instead.`
|
|
185
|
+
)
|
|
186
|
+
} else {
|
|
187
|
+
diagnostics.warn(
|
|
188
|
+
deprecatedKnowledgeBase.getOriginalNode(),
|
|
189
|
+
`'knowledgeBase' is deprecated. Use the 'knowledgeBases' array instead.`
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const deprecatedCatalog = portalArgs.get('catalog')
|
|
195
|
+
if (deprecatedCatalog?.isDefined()) {
|
|
196
|
+
if (catalogsForM2M.length > 0) {
|
|
197
|
+
diagnostics.error(
|
|
198
|
+
deprecatedCatalog.getOriginalNode(),
|
|
199
|
+
`Cannot use both 'catalog' and 'catalogs'. Remove 'catalog' and use only the 'catalogs' array instead.`
|
|
200
|
+
)
|
|
201
|
+
} else {
|
|
202
|
+
diagnostics.warn(
|
|
203
|
+
deprecatedCatalog.getOriginalNode(),
|
|
204
|
+
`'catalog' is deprecated. Use the 'catalogs' array instead.`
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Build portal properties
|
|
187
210
|
const baseProperties = portalArgs.transform(({ $ }) => ({
|
|
188
211
|
title: $,
|
|
189
212
|
url_suffix: $.from('urlSuffix').def(''),
|
|
@@ -203,13 +226,13 @@ export const ServicePortalPlugin = Plugin.create({
|
|
|
203
226
|
search_application: $.from('searchApplication'),
|
|
204
227
|
alternate_portal: $.from('alternatePortal'),
|
|
205
228
|
sc_catalog_page: $.from('catalogHomePage'),
|
|
206
|
-
sc_catalog: $.val(firstCatalogFromArray),
|
|
207
|
-
kb_knowledge_base: $.val(firstKnowledgeBaseFromArray),
|
|
208
229
|
login_page: $.from('loginPage'),
|
|
209
230
|
kb_knowledge_page: $.from('knowledgeHomePage'),
|
|
210
231
|
sp_chat_queue: $.from('chatQueue'),
|
|
211
232
|
notfound_page: $.from('notFoundPage'),
|
|
212
233
|
ts_index_group: $.from('textIndexGroup'),
|
|
234
|
+
...(knowledgeBasesForM2M.length === 0 ? { kb_knowledge_base: $.from('knowledgeBase') } : {}),
|
|
235
|
+
...(catalogsForM2M.length === 0 ? { sc_catalog: $.from('catalog') } : {}),
|
|
213
236
|
enable_ais: $.from('enableAiSearch').def(false),
|
|
214
237
|
enable_certificate_based_authentication: $.from('enableCertificateBasedAuthentication').def(false),
|
|
215
238
|
default: $.from('defaultPortal').def(false),
|