| const fs = require('node:fs'); |
| const path = require('node:path'); |
| const { assignCategorySlugs } = require('./slugs'); |
|
|
| const MENAV_EXTENSION_CONFIG_FILE = 'menav-config.json'; |
|
|
| function getSubmenuForNavItem(navItem, config) { |
| if (!navItem || !navItem.id || !config) { |
| return null; |
| } |
|
|
| if (config[navItem.id] && Array.isArray(config[navItem.id].categories)) |
| return config[navItem.id].categories; |
|
|
| return null; |
| } |
|
|
| function makeJsonSafeForHtmlScript(jsonString) { |
| if (typeof jsonString !== 'string') { |
| return ''; |
| } |
|
|
| return jsonString.replace(/<\/script/gi, '<\\/script'); |
| } |
|
|
| function resolveTemplateNameForPage(pageId, config) { |
| if (!pageId) return 'page'; |
|
|
| const pageConfig = config && config[pageId] ? config[pageId] : null; |
| const explicit = pageConfig && pageConfig.template ? String(pageConfig.template).trim() : ''; |
| if (explicit) return explicit; |
|
|
| const candidatePath = path.join(process.cwd(), 'templates', 'pages', `${pageId}.hbs`); |
| if (fs.existsSync(candidatePath)) return pageId; |
|
|
| return 'page'; |
| } |
|
|
| function buildExtensionConfig(renderData) { |
| const version = |
| renderData && |
| renderData._meta && |
| renderData._meta.version && |
| String(renderData._meta.version).trim() |
| ? String(renderData._meta.version).trim() |
| : process.env.npm_package_version || '1.0.0'; |
|
|
| const pageTemplates = {}; |
| if (renderData && Array.isArray(renderData.navigation)) { |
| renderData.navigation.forEach((navItem) => { |
| const pageId = navItem && navItem.id ? String(navItem.id).trim() : ''; |
| if (!pageId) return; |
| pageTemplates[pageId] = resolveTemplateNameForPage(pageId, renderData); |
| }); |
| } |
|
|
| const allowedSchemes = |
| renderData && |
| renderData.site && |
| renderData.site.security && |
| Array.isArray(renderData.site.security.allowedSchemes) |
| ? renderData.site.security.allowedSchemes |
| : null; |
|
|
| return { |
| version, |
| timestamp: new Date().toISOString(), |
| icons: renderData && renderData.icons ? renderData.icons : undefined, |
| data: { |
| homePageId: renderData && renderData.homePageId ? renderData.homePageId : null, |
| pageTemplates, |
| site: allowedSchemes ? { security: { allowedSchemes } } : undefined, |
| }, |
| }; |
| } |
|
|
| function prepareRenderData(config) { |
| const renderData = { ...config }; |
|
|
| renderData._meta = { |
| generated_at: new Date(), |
| version: process.env.npm_package_version || '1.0.0', |
| generator: 'MeNav', |
| }; |
|
|
| if (!Array.isArray(renderData.navigation)) { |
| renderData.navigation = []; |
| } |
|
|
| if (Array.isArray(renderData.navigation)) { |
| renderData.navigation = renderData.navigation.map((item, index) => { |
| const navItem = { |
| ...item, |
| isActive: index === 0, |
| id: item.id || `nav-${index}`, |
| active: index === 0, |
| }; |
|
|
| const submenu = getSubmenuForNavItem(navItem, renderData); |
| if (submenu) { |
| navItem.submenu = submenu; |
| } |
|
|
| return navItem; |
| }); |
| } |
|
|
| renderData.homePageId = |
| renderData.navigation && renderData.navigation[0] ? renderData.navigation[0].id : null; |
|
|
| if (Array.isArray(renderData.navigation)) { |
| renderData.navigation.forEach((navItem) => { |
| const pageConfig = renderData[navItem.id]; |
| if (pageConfig && Array.isArray(pageConfig.categories)) { |
| assignCategorySlugs(pageConfig.categories, new Map()); |
| } |
| }); |
| } |
|
|
| const extensionConfig = buildExtensionConfig(renderData); |
| renderData.extensionConfig = extensionConfig; |
| renderData.extensionConfigUrl = `./${MENAV_EXTENSION_CONFIG_FILE}`; |
| renderData.configJSON = makeJsonSafeForHtmlScript( |
| JSON.stringify({ |
| ...extensionConfig, |
| configUrl: renderData.extensionConfigUrl, |
| }) |
| ); |
|
|
| renderData.navigationData = renderData.navigation; |
|
|
| if (Array.isArray(renderData.social)) { |
| renderData.socialLinks = renderData.social; |
| } |
|
|
| return renderData; |
| } |
|
|
| module.exports = { |
| MENAV_EXTENSION_CONFIG_FILE, |
| getSubmenuForNavItem, |
| resolveTemplateNameForPage, |
| buildExtensionConfig, |
| prepareRenderData, |
| }; |
|
|