import { CallExpressionShape, Plugin, type Shape } from '@servicenow/sdk-build-core' import { NowIdShape } from '../now-id-plugin' import { toReference } from '../utils' import { getRolesString } from './utils' function getPortalsString(portalsShape: Shape): string { const portals = portalsShape .ifArray() ?.getElements() .map((p) => { const ref = toReference(p) return typeof ref === 'string' ? ref : ref.getValue() }) .filter((id) => id !== '') if (!portals || portals.length === 0) { return '' } return [...new Set(portals)].join(',') } export const SPPageRouteMapPlugin = Plugin.create({ name: 'SPPageRouteMapPlugin', records: { sp_page_route_map: { coalesce: ['route_from_page', 'portals'], toShape(record) { const portalsStr = record.get('portals').ifString()?.getValue() ?? '' const portalsArray = portalsStr ? portalsStr .split(',') .map((p) => p.trim()) .filter((p) => p !== '') : [] const rolesStr = record.get('roles').ifString()?.getValue() ?? '' const rolesArray = rolesStr ? rolesStr .split(',') .map((r) => r.trim()) .filter((r) => r !== '') : [] return { success: true, value: new CallExpressionShape({ source: record, callee: 'SPPageRouteMap', args: [ record.transform(({ $ }) => { const config: { [key: string]: typeof $ | undefined } = { $id: $.val(NowIdShape.from(record)), routeFromPage: $.from('route_from_page'), routeToPage: $.from('route_to_page'), shortDescription: $.from('short_description').def(''), active: $.from('active').toBoolean().def(true), order: $.from('order').toNumber().def(10), } if (portalsArray.length > 0) { config['portals'] = $.val(portalsArray) } if (rolesArray.length > 0) { config['roles'] = $.val(rolesArray) } return config }), ], }), } }, }, }, shapes: [ { shape: CallExpressionShape, fileTypes: ['fluent'], async toRecord(callExpression, { factory, diagnostics }) { if (callExpression.getCallee() !== 'SPPageRouteMap') { return { success: false } } const args = callExpression.getArgument(0).asObject() const routeFromShape = args.get('routeFromPage') const routeToShape = args.get('routeToPage') const routeFromRef = toReference(routeFromShape) const routeToRef = toReference(routeToShape) const routeFromStr = typeof routeFromRef === 'string' ? routeFromRef : routeFromRef.getValue() const routeToStr = typeof routeToRef === 'string' ? routeToRef : routeToRef.getValue() if (routeFromStr !== '' && routeToStr !== '' && routeFromStr === routeToStr) { diagnostics.error( routeToShape.getOriginalNode(), `Invalid SPPageRouteMap: "routeToPage" must be different from "routeFromPage".` ) } const portalsString = getPortalsString(args.get('portals')) const rolesString = getRolesString(args.get('roles'), diagnostics) const routeMapRecord = await factory.createRecord({ source: callExpression, table: 'sp_page_route_map', explicitId: args.get('$id'), properties: args.transform(({ $ }) => ({ route_from_page: $.from('routeFromPage').map(toReference).def(''), route_to_page: $.from('routeToPage').map(toReference).def(''), short_description: $.from('shortDescription').def(''), portals: $.val(portalsString).def(''), roles: $.val(rolesString).def(''), active: $.def(true), order: $.def(10), })), }) return { success: true, value: routeMapRecord, } }, }, ], })