@aedart/vuepress-utils
Version:
A few utilities for Vuepress.
488 lines (482 loc) • 10.8 kB
JavaScript
/**
* @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