import { CallExpressionShape, Plugin } from '@servicenow/sdk-build-core' import { NowIdShape } from '../now-id-plugin' import { DEFAULT_ORDER, getIncludeRecords } from './utils' export const SPThemePlugin = Plugin.create({ name: 'SPThemePlugin', records: { sp_theme: { relationships: { m2m_sp_theme_js_include: { via: 'sp_theme', descendant: true }, m2m_sp_theme_css_include: { via: 'sp_theme', descendant: true }, }, toShape(record, { descendants }) { const cssIncludeRecords = descendants.query('m2m_sp_theme_css_include') const cssIncludes = cssIncludeRecords .map((m2m) => { const orderValue = m2m.get('order') const order = (orderValue?.ifString()?.isEmpty() ? undefined : orderValue?.toNumber()?.getValue()) ?? DEFAULT_ORDER return { order, include: m2m.get('sp_css_include'), } }) .sort((a, b) => a.order - b.order) const jsIncludeRecords = descendants.query('m2m_sp_theme_js_include') const jsIncludes = jsIncludeRecords .map((m2m) => { const orderValue = m2m.get('order') const order = (orderValue?.ifString()?.isEmpty() ? undefined : orderValue?.toNumber()?.getValue()) ?? DEFAULT_ORDER return { order, include: m2m.get('sp_js_include'), } }) .sort((a, b) => a.order - b.order) const themeOptions = record.transform(({ $ }) => ({ $id: $.val(NowIdShape.from(record)), name: $, customCss: $.from('css_variables').def(''), header: $.def(''), footer: $.def(''), fixedHeader: $.from('navbar_fixed').toBoolean().def(true), fixedFooter: $.from('footer_fixed').toBoolean().def(true), turnOffScssCompilation: $.from('turn_off_scss_compilation').toBoolean().def(false), matchingNextExperienceTheme: $.from('matching_now_experience_theme').def(''), cssIncludes: $.val(cssIncludes.length > 0 ? cssIncludes : undefined), jsIncludes: $.val(jsIncludes.length > 0 ? jsIncludes : undefined), icon: $.def(''), logo: $.def(''), logoAltText: $.from('logo_alt_text').def(''), })) return { success: true, value: new CallExpressionShape({ source: record, callee: 'SPTheme', args: [themeOptions], }), } }, }, m2m_sp_theme_css_include: { coalesce: ['sp_css_include', 'sp_theme'], }, m2m_sp_theme_js_include: { coalesce: ['sp_js_include', 'sp_theme'], }, }, shapes: [ { shape: CallExpressionShape, fileTypes: ['fluent'], async toRecord(callExpression, { diagnostics, factory }) { if (callExpression.getCallee() !== 'SPTheme') { return { success: false } } const theme = callExpression.getArgument(0).asObject() const themeRecord = await factory.createRecord({ source: callExpression, table: 'sp_theme', explicitId: theme.get('$id'), properties: theme.transform(({ $ }) => ({ name: $, css_variables: $.from('customCss').def(''), header: $, footer: $, navbar_fixed: $.from('fixedHeader').def(true), footer_fixed: $.from('fixedFooter').def(true), turn_off_scss_compilation: $.from('turnOffScssCompilation').def(false), matching_now_experience_theme: $.from('matchingNextExperienceTheme').def(''), icon: $, logo: $, logo_alt_text: $.from('logoAltText').def(''), })), }) const cssIncludes = await getIncludeRecords( theme.get('cssIncludes'), themeRecord.getId(), factory, 'm2m_sp_theme_css_include', 'sp_css_include', 'sp_theme', diagnostics ) const jsIncludes = await getIncludeRecords( theme.get('jsIncludes'), themeRecord.getId(), factory, 'm2m_sp_theme_js_include', 'sp_js_include', 'sp_theme', diagnostics ) return { success: true, value: themeRecord.with(...cssIncludes, ...jsIncludes), } }, }, ], })