UNPKG

@aedart/vuepress-utils

Version:

A few utilities for Vuepress.

488 lines (482 loc) 10.8 kB
/** * @aedart/vuepress-utils * * BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>. */ 'use strict'; var vuepressUtils = require('@aedart/vuepress-utils'); /** * Archive * * @typedef {import('@vuepress/theme-default').NavbarGroupOptions} NavbarGroupOptions * @typedef {import('@vuepress/theme-default').NavbarLinkOptions} NavbarLinkOptions * @typedef {import('@vuepress/theme-default').NavGroup} NavGroup * @typedef {import('@vuepress/theme-default').SidebarOptions} SidebarOptions */ class Archive { /** * Name of this archive * * @type {string} * @private */ _name = 'Archive'; /** * Archive's path * * @type {string} * @private */ _path = '/archive'; /** * Collection to be marked as "current" * * @type {PagesCollection} * @private */ _current; /** * Collection to be marked as "next" * * @type {PagesCollection} * @private */ _next; /** * Collections in this archive * * @type {PagesCollection[]} * @private */ _collections = []; /** * Navigation label for the "current" collection * * @type {string} * @private */ _currentLabel = 'current'; /** * Navigation label for the "next" collection * * @type {string} * @private */ _nextLabel = 'next'; /** * Relative path for the "current" collection, in archive * * @type {string} * @private */ _currentPath = '/current/'; /** * Relative path for the "next" collection, in archive * * @type {string} * @private */ _nextPath = '/next/'; /** * Creates a new Archive instance * * @param {PagesCollection} current * @param {PagesCollection} next * @param {PagesCollection[]} [collections=[]] */ constructor(current, next, collections = []) { this._current = current; this._next = next; this.collections = collections; } /** * Creates a new Archive instance * * @param {PagesCollection} current * @param {PagesCollection} next * @param {PagesCollection[]} [collections=[]] * * @returns {Archive} */ static make(current, next, collections = []) { return new this(current, next, collections); } /** * @inheritdoc */ set name(name) { this._name = name; } /** * @inheritdoc */ get name() { return this._name; } /** * @inheritdoc */ set path(path) { this._path = path; } /** * @inheritdoc */ get path() { return this._path; } /** * @inheritdoc */ set current(collection) { this._current = collection; } /** * @inheritdoc */ get current() { return this._current; } /** * @inheritdoc */ set next(collection) { this._next = collection; } /** * @inheritdoc */ get next() { return this._next; } /** * @inheritdoc */ set collections(pageCollections) { pageCollections.forEach((collection) => { collection.archive = this; }); this._collections = pageCollections; } /** * @inheritdoc */ get collections() { return this.markCurrentAndNextCollections(this._collections); } /** * @inheritdoc */ set currentLabel(name) { this._currentLabel = name; } /** * @inheritdoc */ get currentLabel() { return this._currentLabel; } /** * @inheritdoc */ set nextLabel(name) { this._nextLabel = name; } /** * @inheritdoc */ get nextLabel() { return this._nextLabel; } /** * @inheritdoc */ set currentPath(path) { this._currentPath = path; } /** * @inheritdoc */ get currentPath() { return this._currentPath; } /** * @inheritdoc */ get currentFullPath() { return vuepressUtils.prefixPath(this.path, this.currentPath); } /** * @inheritdoc */ set nextPath(path) { this._nextPath = path; } /** * @inheritdoc */ get nextPath() { return this._nextPath; } /** * @inheritdoc */ get nextFullPath() { return vuepressUtils.prefixPath(this.path, this.nextPath); } /** * @inheritdoc */ asNavigationItem() { return { text: this.name, link: this.path, children: this.makeNavbarItemChildren(), }; } /** * @inheritdoc */ sidebarConfiguration() { let output = {}; this.collections.forEach((collection) => { output = Object.assign(output, collection.asSidebarObject()); }); return output; } /***************************************************************** * Internals ****************************************************************/ /** * Returns collections as list of navbar item * * @returns {(NavbarLinkOptions | NavGroup<NavbarLinkOptions>)[]} * @protected */ makeNavbarItemChildren() { const output = []; this.collections.forEach((collection) => { output.push(collection.asNavigationItem()); }); return output; } /** * "Mark" the current and next collections * * @param {PagesCollection[]} collections * * @returns {PagesCollection[]} * @protected */ markCurrentAndNextCollections(collections) { collections.forEach((collection) => { // Mark as "next" if matches... if (collection === this.next) { collection.name = this.nextLabel; collection.path = this.nextPath; } // Mark as "current" if matches... if (collection === this.current) { collection.name = this.currentLabel; collection.path = this.currentPath; } }); return collections; } } /** * Pages Collection * * @typedef {import('@vuepress/theme-default').NavGroup} NavGroup * @typedef {import('@vuepress/theme-default').NavbarLinkOptions} NavbarLinkOptions * @typedef {import('@vuepress/theme-default').SidebarObjectOptions} SidebarObjectOptions * @typedef {import('@vuepress/theme-default').SidebarArrayOptions} SidebarArrayOptions * @typedef {import('@vuepress/theme-default').SidebarItemOptions} SidebarItemOptions * @typedef {import('@vuepress/theme-default').SidebarGroupOptions} SidebarGroupOptions */ class PagesCollection { /** * Name of this collection * * @type {string} * * @private */ _name; /** * Relative path of this collection inside an archive * * @type {string} * @private */ _path; /** * Archive that this collection belongs to * * @type {Archive | null} * @private */ _archive = null; /** * The pages in this collection * * @type {SidebarArrayOptions} */ pages; /** * Creates a new pages collection instance * * @param {string} name * @param {string} path * @param {SidebarArrayOptions} [pages=[]] */ constructor(name, path, pages = []) { this._name = name; this._path = path; this.pages = pages; } /** * Creates a new pages collection instance * * @param {string} name * @param {string} path * @param {SidebarArrayOptions} [pages=[]] * * @returns {PagesCollection} */ static make(name, path, pages = []) { return new this(name, path, pages); } /** * @inheritdoc */ set name(name) { this._name = name; } /** * @inheritdoc */ get name() { return this._name; } /** * @inheritdoc */ set path(path) { this._path = path; } /** * @inheritdoc */ get path() { return this._path; } /** * @inheritdoc */ get fullPath() { return this.prefixWithArchivePath(this.path); } /** * @inheritdoc */ set archive(archive) { this._archive = archive; } /** * @inheritdoc */ get archive() { return this._archive; } /** * @inheritdoc */ asNavigationItem() { return { text: this.name, link: this.fullPath }; } /** * @inheritdoc */ asSidebarObject() { return { [this.fullPath]: this.sidebar() }; } /** * @inheritdoc */ sidebar() { return this.resolvePages(this.pages); } /***************************************************************** * Internals ****************************************************************/ /** * Resolves pages' path * * @param {SidebarArrayOptions} pages * * @returns {SidebarArrayOptions} * @protected */ resolvePages(pages) { pages.forEach((page, index, array) => { array[index] = this.resolvePage(page); }); return pages; } /** * Resolves given page's path * * @param {SidebarItemOptions} page * * @returns {SidebarItemOptions} * * @protected */ resolvePage(page) { if (typeof page === 'string') { return this.prefixWillFullPath(page); } if (!Reflect.has(page, 'children') || page.children.length === 0) { return page; } page.children.forEach((child, index, children) => { children[index] = this.resolvePage(child); }); return page; } /** * Prefix given path with {@link fullPath} * * @param {string} path * * @returns {string} * @protected */ prefixWillFullPath(path) { return vuepressUtils.prefixPath(this.fullPath, path); } /** * Prefix given path with {@link Archive.path} * * @param {string} path * @returns {string} * * @protected */ prefixWithArchivePath(path) { const prefix = (this.archive !== null) ? this.archive.path : ''; return vuepressUtils.prefixPath(prefix, path); } } exports.Archive = Archive; exports.PagesCollection = PagesCollection; module.exports = Object.assign(exports.default, exports); //# sourceMappingURL=navigation.cjs.map