UNPKG

@mdfriday/foundry

Version:

The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.

319 lines 7.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MENUS_BEFORE = exports.MENUS_AFTER = exports.Menus = exports.Menu = exports.MenuEntry = void 0; exports.newEmptyMenus = newEmptyMenus; const log_1 = require("../../../../pkg/log"); // Create domain-specific logger for menu operations const log = (0, log_1.getDomainLogger)('site', { component: 'menu' }); /** * MenuEntry - A single menu item with hierarchical support * TypeScript equivalent based on menu.md requirements */ class MenuEntry { constructor(options) { this._title = options.title; this._url = options.url; this._isDir = options.isDir; this._hasIndex = options.hasIndex; this._children = options.children || []; this._weight = options.weight || 0; this._identifier = options.identifier || this._url; } /** * Get menu entry title */ title() { return this._title; } /** * Get menu entry URL */ url() { return this._url; } /** * Check if this is a directory (branch) */ isDirectory() { return this._isDir; } /** * Check if this directory has an index page (leaf) */ hasIndex() { return this._hasIndex; } /** * Get child menu entries */ children() { return [...this._children]; } /** * Get menu entry weight for sorting */ weight() { return this._weight; } /** * Get menu entry identifier */ identifier() { return this._identifier; } /** * Check if this menu entry has children */ hasChildren() { return this._children.length > 0; } /** * Add a child menu entry */ addChild(child) { const newChildren = [...this._children, child]; return new MenuEntry({ title: this._title, url: this._url, isDir: this._isDir, hasIndex: this._hasIndex, children: newChildren, weight: this._weight, identifier: this._identifier, }); } /** * Convert to JSON representation as specified in menu.md */ toJSON() { return { title: this._title, url: this._url, isDir: this._isDir, hasIndex: this._hasIndex, children: this._children.map(child => child.toJSON()), }; } /** * Create a new MenuEntry with updated properties */ withChildren(children) { return new MenuEntry({ title: this._title, url: this._url, isDir: this._isDir, hasIndex: this._hasIndex, children: children, weight: this._weight, identifier: this._identifier, }); } } exports.MenuEntry = MenuEntry; /** * Menu - A collection of menu entries with sorting and filtering capabilities */ class Menu { constructor(entries = []) { this._entries = [...entries]; } /** * Get all entries */ entries() { return [...this._entries]; } /** * Get entry by index */ get(index) { return this._entries[index]; } /** * Get length */ get length() { return this._entries.length; } /** * Add a menu entry */ add(entry) { const newEntries = [...this._entries, entry]; return new Menu(newEntries).sortMenu(); } /** * Sort menu entries by weight and then by title */ sortMenu() { const sorted = [...this._entries].sort((a, b) => { // Sort by weight first if (a.weight() !== b.weight()) { if (b.weight() === 0) return -1; if (a.weight() === 0) return 1; return a.weight() - b.weight(); } // Then sort by title const titleComparison = a.title().localeCompare(b.title()); if (titleComparison !== 0) { return titleComparison; } // Finally sort by identifier return a.identifier().localeCompare(b.identifier()); }); return new Menu(sorted); } /** * Filter menu entries by predicate */ filterMenu(predicate) { const filtered = this._entries.filter(predicate); return new Menu(filtered); } /** * Find menu entry by identifier */ findByIdentifier(identifier) { return this._entries.find(entry => entry.identifier() === identifier); } /** * Find menu entry by URL */ findByUrl(url) { return this._entries.find(entry => entry.url() === url); } /** * Get all leaf entries (entries without children) */ getLeaves() { return this.filterMenu(entry => !entry.hasChildren()); } /** * Get all branch entries (entries with children) */ getBranches() { return this.filterMenu(entry => entry.hasChildren()); } /** * Convert to JSON array */ toJSON() { return this._entries.map(entry => entry.toJSON()); } /** * Iterator support */ [Symbol.iterator]() { return this._entries[Symbol.iterator](); } /** * Map over entries */ map(callback) { return this._entries.map(callback); } /** * ForEach over entries */ forEach(callback) { this._entries.forEach(callback); } } exports.Menu = Menu; /** * Menus - A collection of menus by name, supporting multiple languages * TypeScript equivalent of valueobject.Menus from Go */ class Menus { constructor(menus = new Map()) { this._menus = new Map(menus); } /** * Get menu by name */ get(name) { return this._menus.get(name); } /** * Set menu by name */ set(name, menu) { const newMenus = new Map(this._menus); newMenus.set(name, menu); return new Menus(newMenus); } /** * Get all menu names */ names() { return Array.from(this._menus.keys()); } /** * Check if menu exists */ has(name) { return this._menus.has(name); } /** * Check if menu entry has sub-menu */ hasSubMenu(entry) { const menu = this._menus.get(entry.title()); if (!menu) return false; if (menu.length === 1 && menu.get(0)?.title() === entry.title()) { return false; } return menu.length > 1; } /** * Get all menus as entries */ entries() { return Array.from(this._menus.entries()); } /** * Convert to plain object for serialization */ toJSON() { const result = {}; for (const [name, menu] of this._menus.entries()) { result[name] = menu.toJSON(); } return result; } /** * Merge with another Menus instance */ merge(other) { const newMenus = new Map(this._menus); for (const [name, menu] of other._menus.entries()) { if (newMenus.has(name)) { // Merge menu entries const existingMenu = newMenus.get(name); const mergedEntries = [...existingMenu.entries(), ...menu.entries()]; const mergedMenu = new Menu(mergedEntries).sortMenu(); newMenus.set(name, mergedMenu); } else { newMenus.set(name, menu); } } return new Menus(newMenus); } } exports.Menus = Menus; /** * Create empty menus instance */ function newEmptyMenus() { return new Menus(); } /** * Menu constants */ exports.MENUS_AFTER = "after"; exports.MENUS_BEFORE = "before"; //# sourceMappingURL=menu.js.map