@jpmorganchase/mosaic-plugins 0.1.0-beta.7 → 0.1.0-beta.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/$AliasPlugin.d.ts +10 -0
- package/dist/$AliasPlugin.js +34 -46
- package/dist/$AliasPlugin.js.map +1 -1
- package/dist/$CodeModPlugin.d.ts +7 -0
- package/dist/$CodeModPlugin.js +12 -28
- package/dist/$CodeModPlugin.js.map +1 -1
- package/dist/$RefPlugin.d.ts +31 -0
- package/dist/$RefPlugin.js +109 -108
- package/dist/$RefPlugin.js.map +1 -1
- package/dist/$TagPlugin.d.ts +28 -0
- package/dist/$TagPlugin.js +24 -44
- package/dist/$TagPlugin.js.map +1 -1
- package/dist/BreadcrumbsPlugin.d.ts +19 -0
- package/dist/BreadcrumbsPlugin.js +78 -34
- package/dist/BreadcrumbsPlugin.js.map +1 -1
- package/dist/BrokenLinksPlugin.d.ts +10 -0
- package/dist/BrokenLinksPlugin.js +80 -0
- package/dist/BrokenLinksPlugin.js.map +1 -0
- package/dist/FragmentPlugin.d.ts +3 -0
- package/dist/FragmentPlugin.js +61 -0
- package/dist/FragmentPlugin.js.map +1 -0
- package/dist/LazyPagePlugin.d.ts +14 -0
- package/dist/LazyPagePlugin.js +46 -79
- package/dist/LazyPagePlugin.js.map +1 -1
- package/dist/PagesWithoutFileExtPlugin.d.ts +9 -0
- package/dist/PagesWithoutFileExtPlugin.js +14 -29
- package/dist/PagesWithoutFileExtPlugin.js.map +1 -1
- package/dist/PropsTablePlugin.d.ts +6 -0
- package/dist/PropsTablePlugin.js +88 -0
- package/dist/PropsTablePlugin.js.map +1 -0
- package/dist/PublicAssetsPlugin.d.ts +18 -0
- package/dist/PublicAssetsPlugin.js +28 -0
- package/dist/PublicAssetsPlugin.js.map +1 -0
- package/dist/ReadingTimePlugin.d.ts +10 -0
- package/dist/ReadingTimePlugin.js +39 -0
- package/dist/ReadingTimePlugin.js.map +1 -0
- package/dist/SearchIndexPlugin.d.ts +56 -0
- package/dist/SearchIndexPlugin.js +154 -0
- package/dist/SearchIndexPlugin.js.map +1 -0
- package/dist/SharedConfigPlugin.d.ts +14 -0
- package/dist/SharedConfigPlugin.js +124 -32
- package/dist/SharedConfigPlugin.js.map +1 -1
- package/dist/SidebarPlugin.d.ts +44 -0
- package/dist/SidebarPlugin.js +235 -88
- package/dist/SidebarPlugin.js.map +1 -1
- package/dist/SiteMapPlugin.d.ts +9 -0
- package/dist/SiteMapPlugin.js +20 -34
- package/dist/SiteMapPlugin.js.map +1 -1
- package/dist/TableOfContentsPlugin.d.ts +20 -0
- package/dist/TableOfContentsPlugin.js +44 -0
- package/dist/TableOfContentsPlugin.js.map +1 -0
- package/dist/utils/PluginError.d.ts +7 -0
- package/dist/utils/PluginError.js +13 -0
- package/dist/utils/PluginError.js.map +1 -0
- package/dist/utils/createPageTest.d.ts +1 -0
- package/dist/utils/createPageTest.js +8 -0
- package/dist/utils/createPageTest.js.map +1 -0
- package/dist/utils/mergePageContent.d.ts +16 -0
- package/dist/utils/mergePageContent.js +23 -0
- package/dist/utils/mergePageContent.js.map +1 -0
- package/dist/utils/normaliseRefs.d.ts +1 -0
- package/dist/utils/normaliseRefs.js +52 -69
- package/dist/utils/normaliseRefs.js.map +1 -1
- package/dist/utils/sortSidebarData.d.ts +19 -0
- package/dist/utils/sortSidebarData.js +35 -0
- package/dist/utils/sortSidebarData.js.map +1 -0
- package/package.json +42 -19
- package/CHANGELOG.md +0 -79
- package/dist/LocalFolderSavePlugin.js +0 -48
- package/dist/LocalFolderSavePlugin.js.map +0 -1
- package/dist/NextPrevPagePlugin.js +0 -63
- package/dist/NextPrevPagePlugin.js.map +0 -1
- package/dist/ReadingTimePlugin.mjs +0 -119
- package/dist/ReadingTimePlugin.mjs.map +0 -1
- package/dist/SearchIndexPlugin.mjs +0 -268
- package/dist/SearchIndexPlugin.mjs.map +0 -1
- package/dist/TableOfContentsPlugin.mjs +0 -131
- package/dist/TableOfContentsPlugin.mjs.map +0 -1
|
@@ -1,50 +1,142 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const flatten_1 = __importDefault(require("lodash/flatten"));
|
|
16
|
-
const path_1 = __importDefault(require("path"));
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { flatten } from 'lodash-es';
|
|
4
|
+
import deepmerge from 'deepmerge';
|
|
5
|
+
import { createPageTest } from './utils/createPageTest.js';
|
|
17
6
|
function createFileGlob(url, pageExtensions) {
|
|
18
7
|
if (pageExtensions.length === 1) {
|
|
19
8
|
return `${url}${pageExtensions[0]}`;
|
|
20
9
|
}
|
|
21
10
|
return `${url}{${pageExtensions.join(',')}}`;
|
|
22
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* https://stackoverflow.com/a/50549047
|
|
14
|
+
* compute inner relative to outer
|
|
15
|
+
* If it's not contained, the first component of the resulting path will be .., so that's what we check for
|
|
16
|
+
*/
|
|
17
|
+
function isWithin(outer, inner) {
|
|
18
|
+
const outerParentDir = path.posix.resolve(path.posix.dirname(outer), '../');
|
|
19
|
+
const innerParentDir = path.posix.resolve(path.posix.dirname(inner), '../');
|
|
20
|
+
const rel = path.posix.relative(outerParentDir, innerParentDir);
|
|
21
|
+
return !rel.startsWith('../') && rel !== '..';
|
|
22
|
+
}
|
|
23
23
|
/**
|
|
24
24
|
* Plugin that crawls the page hierarchy to find the closest `sharedConfig` from any parent index's page metadata.
|
|
25
25
|
* It then exports a JSON file (name: `options.filename`) into each directory with the merged config for that level
|
|
26
26
|
*/
|
|
27
27
|
const SharedConfigPlugin = {
|
|
28
|
-
$
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
async $afterSource(pages, { ignorePages, pageExtensions, config, namespace }) {
|
|
29
|
+
const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
|
|
30
|
+
let finalSharedConfig;
|
|
31
|
+
const indexPages = pages.filter(page => path.posix.basename(page.fullPath, path.posix.extname(page.fullPath)) === 'index' &&
|
|
32
|
+
isNonHiddenPage(page.fullPath));
|
|
33
|
+
const indexPagesWithSharedConfig = indexPages.filter(page => page.sharedConfig !== undefined);
|
|
34
|
+
if (indexPagesWithSharedConfig.length === 0 && indexPages.length > 0) {
|
|
35
|
+
const rootPath = indexPages[0].fullPath;
|
|
36
|
+
const applyNamespaceSharedConfig = {
|
|
37
|
+
[`${crypto.randomUUID()}`]: {
|
|
38
|
+
paths: indexPages.map(indexPage => indexPage.fullPath),
|
|
39
|
+
rootPath,
|
|
40
|
+
namespace
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
};
|
|
43
|
+
config.setData({ applyNamespaceSharedConfig });
|
|
44
|
+
return pages;
|
|
45
|
+
}
|
|
46
|
+
for (const page of indexPagesWithSharedConfig) {
|
|
47
|
+
if (finalSharedConfig === undefined) {
|
|
48
|
+
// first shared config we have found so seed the finalSharedConfig
|
|
49
|
+
finalSharedConfig = page.sharedConfig;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
for (let i = 1; i < indexPagesWithSharedConfig.length; i++) {
|
|
53
|
+
if (isWithin(indexPagesWithSharedConfig[i].fullPath, page.fullPath)) {
|
|
54
|
+
// found another shared config so merge and apply to the page
|
|
55
|
+
finalSharedConfig = deepmerge(finalSharedConfig, page.sharedConfig);
|
|
56
|
+
page.sharedConfig = finalSharedConfig;
|
|
57
|
+
page.frameOverrides = { $ref: '#/sharedConfig' };
|
|
58
|
+
}
|
|
44
59
|
}
|
|
45
60
|
}
|
|
61
|
+
}
|
|
62
|
+
return pages;
|
|
63
|
+
},
|
|
64
|
+
async $beforeSend(mutableFilesystem, { config, serialiser, ignorePages, pageExtensions }, options) {
|
|
65
|
+
const indexPagePaths = await mutableFilesystem.promises.glob(createFileGlob('**/index', pageExtensions), {
|
|
66
|
+
ignore: [options.filename, ...flatten(ignorePages.map(ignore => [ignore, `**/${ignore}`]))],
|
|
67
|
+
cwd: '/'
|
|
46
68
|
});
|
|
69
|
+
const sharedConfigFiles = [];
|
|
70
|
+
const indexPagesWithoutConfig = [];
|
|
71
|
+
for (const indexPagePath of indexPagePaths) {
|
|
72
|
+
const sharedConfigFile = path.posix.join(path.posix.dirname(String(indexPagePath)), options.filename);
|
|
73
|
+
const page = await serialiser.deserialise(String(indexPagePath), await mutableFilesystem.promises.readFile(String(indexPagePath)));
|
|
74
|
+
if (page.sharedConfig) {
|
|
75
|
+
config.setRef(sharedConfigFile, ['config', '$ref'], `${String(indexPagePath)}#/sharedConfig`);
|
|
76
|
+
await mutableFilesystem.promises.writeFile(sharedConfigFile, '{}');
|
|
77
|
+
sharedConfigFiles.push(sharedConfigFile);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
indexPagesWithoutConfig.push(page.fullPath);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// apply closest shared config
|
|
84
|
+
if (sharedConfigFiles.length > 0) {
|
|
85
|
+
let closestSharedConfigIndex = 0;
|
|
86
|
+
for (const pagePath of indexPagesWithoutConfig) {
|
|
87
|
+
for (let i = 0; i < sharedConfigFiles.length; i++) {
|
|
88
|
+
if (isWithin(sharedConfigFiles[i], pagePath)) {
|
|
89
|
+
closestSharedConfigIndex = i;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const sharedConfigFile = path.posix.join(path.posix.dirname(String(pagePath)), options.filename);
|
|
93
|
+
const closestSharedConfig = path.posix.resolve(path.dirname(String(pagePath)), sharedConfigFiles[closestSharedConfigIndex]);
|
|
94
|
+
config.setAliases(closestSharedConfig, [sharedConfigFile]);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
async afterUpdate(mutableFilesystem, { sharedFilesystem, globalConfig, namespace }, options) {
|
|
99
|
+
const { applyNamespaceSharedConfig } = globalConfig.data;
|
|
100
|
+
if (applyNamespaceSharedConfig === undefined) {
|
|
101
|
+
// there is no source that exists that has told us it needs to share a namespace shared-config
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// find all the entries that match the namespace the plugin is running against
|
|
105
|
+
const namespaceSharedConfigs = Object.keys(applyNamespaceSharedConfig)
|
|
106
|
+
.filter(key => applyNamespaceSharedConfig[key].namespace === namespace)
|
|
107
|
+
.map(key => applyNamespaceSharedConfig?.[key] || []);
|
|
108
|
+
for (const namespaceSharedConfig of namespaceSharedConfigs) {
|
|
109
|
+
if (await mutableFilesystem.promises.exists(namespaceSharedConfig.rootPath)) {
|
|
110
|
+
// a source does need a namespace shared config but the source running this plugin is the source that needs it
|
|
111
|
+
// so we don't need to do anything here
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
for (const applyPath of namespaceSharedConfig.paths) {
|
|
115
|
+
if (!(await sharedFilesystem.promises.exists(applyPath))) {
|
|
116
|
+
sharedFilesystem.promises.mkdir(path.posix.dirname(String(applyPath)), {
|
|
117
|
+
recursive: true
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
let parentDir = path.posix.join(path.posix.dirname(String(applyPath)), '../');
|
|
121
|
+
let closestSharedConfigPath = path.posix.join(parentDir, options.filename);
|
|
122
|
+
while (parentDir !== path.posix.sep) {
|
|
123
|
+
// walk up the directories in the path to find the closest shared config file
|
|
124
|
+
closestSharedConfigPath = path.posix.join(parentDir, options.filename);
|
|
125
|
+
if (await mutableFilesystem.promises.exists(closestSharedConfigPath)) {
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
parentDir = path.posix.join(path.posix.dirname(String(closestSharedConfigPath)), '../');
|
|
129
|
+
}
|
|
130
|
+
const aliasSharedConfigPath = path.posix.join(path.posix.dirname(String(applyPath)), options.filename);
|
|
131
|
+
if ((await mutableFilesystem.promises.exists(closestSharedConfigPath)) &&
|
|
132
|
+
!(await sharedFilesystem.promises.exists(aliasSharedConfigPath))) {
|
|
133
|
+
console.log(`[Mosaic][Plugin] Source has no shared config. Root index page is: ${namespaceSharedConfig.rootPath}`);
|
|
134
|
+
console.log('[Mosaic][Plugin] Copying shared config ', closestSharedConfigPath, '-->', aliasSharedConfigPath);
|
|
135
|
+
await sharedFilesystem.promises.writeFile(aliasSharedConfigPath, await mutableFilesystem.promises.readFile(closestSharedConfigPath));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
47
139
|
}
|
|
48
140
|
};
|
|
49
|
-
|
|
141
|
+
export default SharedConfigPlugin;
|
|
50
142
|
//# sourceMappingURL=SharedConfigPlugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedConfigPlugin.js","sourceRoot":"","sources":["../src/SharedConfigPlugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SharedConfigPlugin.js","sourceRoot":"","sources":["../src/SharedConfigPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Plugin as PluginType, Page } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
import { type SortConfig } from '@jpmorganchase/mosaic-schemas';
|
|
3
|
+
interface SidebarPluginConfigData {
|
|
4
|
+
dirs: string[];
|
|
5
|
+
refs: {
|
|
6
|
+
[key: string]: {
|
|
7
|
+
$$path: (number | string)[];
|
|
8
|
+
$$value: string;
|
|
9
|
+
}[];
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface SidebarPluginPage extends Page {
|
|
13
|
+
sidebar?: {
|
|
14
|
+
label?: string;
|
|
15
|
+
};
|
|
16
|
+
sharedConfig: {
|
|
17
|
+
sidebar: {
|
|
18
|
+
sort: SortConfig;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
interface SidebarPluginOptions {
|
|
23
|
+
/**
|
|
24
|
+
* filename of the sidebar json, linked to each related page via ref
|
|
25
|
+
*/
|
|
26
|
+
filename: string;
|
|
27
|
+
/**
|
|
28
|
+
* Glob pattern for matching directories which should be the root of the sidebar
|
|
29
|
+
* * creates a root level sidebar containing all pages underneath root
|
|
30
|
+
* *\/* creates a separate sidebar under each of the root directories
|
|
31
|
+
*/
|
|
32
|
+
rootDirGlob: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Sorts the pages in a folder by priority and then exports a JSON file with the
|
|
36
|
+
* sidebar tree from that directory downwards and adds sidebar data into frontmatter for each page.
|
|
37
|
+
*
|
|
38
|
+
* Additionally, add to frontmatter
|
|
39
|
+
* navigation -> prev -> { title, route }
|
|
40
|
+
* navigation -> next -> { title, route }
|
|
41
|
+
* to define the previous/next page in the page sequence, as defined by sidebar label and priority
|
|
42
|
+
*/
|
|
43
|
+
declare const SidebarPlugin: PluginType<SidebarPluginPage, SidebarPluginOptions, SidebarPluginConfigData>;
|
|
44
|
+
export default SidebarPlugin;
|
package/dist/SidebarPlugin.js
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const path_1 = __importDefault(require("path"));
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { sidebarSortConfigSchema } from '@jpmorganchase/mosaic-schemas';
|
|
3
|
+
import { cloneDeep } from 'lodash-es';
|
|
4
|
+
import { sortSidebarData } from './utils/sortSidebarData.js';
|
|
16
5
|
function createFileGlob(patterns, pageExtensions) {
|
|
17
6
|
if (Array.isArray(patterns)) {
|
|
18
7
|
return patterns.map(pattern => createFileGlob(pattern, pageExtensions));
|
|
@@ -22,92 +11,250 @@ function createFileGlob(patterns, pageExtensions) {
|
|
|
22
11
|
}
|
|
23
12
|
return `${patterns}{${pageExtensions.join(',')}}`;
|
|
24
13
|
}
|
|
25
|
-
function
|
|
26
|
-
return page.
|
|
14
|
+
function getPageLevel(page) {
|
|
15
|
+
return page.route.split('/').length - 2;
|
|
27
16
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
return -1;
|
|
33
|
-
}
|
|
34
|
-
if (pageB.route === route) {
|
|
35
|
-
return 1;
|
|
36
|
-
}
|
|
37
|
-
return ((pageB.sidebar && pageB.sidebar.priority ? pageB.sidebar.priority : -1) -
|
|
38
|
-
(pageA.sidebar && pageA.sidebar.priority ? pageA.sidebar.priority : -1));
|
|
17
|
+
function sortByPathLevel(pathA, pathB) {
|
|
18
|
+
const pathALevel = pathA.split('/').length;
|
|
19
|
+
const pathBLevel = pathB.split('/').length;
|
|
20
|
+
return pathBLevel - pathALevel;
|
|
39
21
|
}
|
|
40
|
-
|
|
41
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Given the sharedSortConfig
|
|
24
|
+
* 1. find the field specified by 'field' in the sort config
|
|
25
|
+
* 2. transform the field value into the type specified by 'dataType'
|
|
26
|
+
* @param page
|
|
27
|
+
* @param sharedSortConfig
|
|
28
|
+
* @returns transformed field value
|
|
29
|
+
*/
|
|
30
|
+
function getSortFieldData(page, sharedSortConfig) {
|
|
31
|
+
let fieldData;
|
|
32
|
+
if (sharedSortConfig !== undefined) {
|
|
33
|
+
const { field, dataType = 'string' } = sharedSortConfig;
|
|
34
|
+
field
|
|
35
|
+
.replace(/^(?:\.\.\/|\.\/)+/, '')
|
|
36
|
+
.split('/')
|
|
37
|
+
.forEach(part => {
|
|
38
|
+
const source = fieldData === undefined ? page : fieldData;
|
|
39
|
+
if (Object.prototype.hasOwnProperty.call(source, part)) {
|
|
40
|
+
fieldData = source[part];
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
switch (dataType) {
|
|
44
|
+
case 'date':
|
|
45
|
+
fieldData = new Date(fieldData).getTime(); // call getTime to convert to a number
|
|
46
|
+
break;
|
|
47
|
+
case 'string':
|
|
48
|
+
fieldData = String(fieldData);
|
|
49
|
+
break;
|
|
50
|
+
case 'number':
|
|
51
|
+
fieldData = Number(fieldData);
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
fieldData = String(fieldData);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return fieldData;
|
|
42
58
|
}
|
|
43
59
|
/**
|
|
44
|
-
* Sorts the pages in a folder by priority and then exports a JSON file
|
|
60
|
+
* Sorts the pages in a folder by priority and then exports a JSON file with the
|
|
45
61
|
* sidebar tree from that directory downwards and adds sidebar data into frontmatter for each page.
|
|
62
|
+
*
|
|
63
|
+
* Additionally, add to frontmatter
|
|
64
|
+
* navigation -> prev -> { title, route }
|
|
65
|
+
* navigation -> next -> { title, route }
|
|
66
|
+
* to define the previous/next page in the page sequence, as defined by sidebar label and priority
|
|
46
67
|
*/
|
|
47
68
|
const SidebarPlugin = {
|
|
48
|
-
$beforeSend(mutableFilesystem, { config, serialiser, ignorePages, pageExtensions },
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
ignore: ignorePages.map(ignore => `**/${ignore}`)
|
|
67
|
-
})).map((pagePath) => __awaiter(this, void 0, void 0, function* () {
|
|
68
|
-
const deserialisedPage = yield serialiser.deserialise(pagePath, yield mutableFilesystem.promises.readFile(pagePath));
|
|
69
|
-
return deserialisedPage;
|
|
70
|
-
})))).filter(filterPage => filterFn(filterPage));
|
|
71
|
-
if (childPages.length > 1) {
|
|
72
|
-
for (let j = 1; j < childPages.length; j++) {
|
|
73
|
-
config.setRef(sidebarFilePath, ['pages', `${i}`, 'childNodes', `${j - 1}`, '$ref'], `${childNodeSidebarPath}#/pages/${j}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
69
|
+
async $beforeSend(mutableFilesystem, { config, serialiser, ignorePages, pageExtensions }, { filename = 'sidebar.json', rootDirGlob = '*' }) {
|
|
70
|
+
/**
|
|
71
|
+
* Create a list of pages that should be used to build a sidebar.json
|
|
72
|
+
* @param dirName - root path of sidebar
|
|
73
|
+
*/
|
|
74
|
+
async function createPageList(rootDir) {
|
|
75
|
+
const isChildOfRootDir = pagePath => {
|
|
76
|
+
const pageDir = path.dirname(pagePath);
|
|
77
|
+
return pageDir.indexOf(rootDir) === 0;
|
|
78
|
+
};
|
|
79
|
+
const pagePaths = (await mutableFilesystem.promises.glob(createFileGlob(['**'], pageExtensions), {
|
|
80
|
+
cwd: String(rootDir),
|
|
81
|
+
ignore: ignorePages.map(ignore => `**/${ignore}`)
|
|
82
|
+
}));
|
|
83
|
+
const filteredPagePaths = pagePaths.filter(isChildOfRootDir);
|
|
84
|
+
const pageList = await Promise.all(filteredPagePaths.map(async (pagePath) => {
|
|
85
|
+
return mutableFilesystem.promises.readFile(pagePath).then(serializedContent => {
|
|
86
|
+
return serialiser.deserialise(pagePath, serializedContent);
|
|
77
87
|
});
|
|
88
|
+
}));
|
|
89
|
+
return pageList;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Group the pages into parent/child hierarchy
|
|
93
|
+
* @param pages - sidebar pages
|
|
94
|
+
*/
|
|
95
|
+
function createGroupMap(pages) {
|
|
96
|
+
const sortConfigPages = {};
|
|
97
|
+
return pages.reduce((result, page) => {
|
|
98
|
+
const name = page.sidebar?.label || page.title;
|
|
99
|
+
const sharedSortConfig = page?.sharedConfig?.sidebar?.sort;
|
|
100
|
+
if (sharedSortConfig) {
|
|
101
|
+
try {
|
|
102
|
+
sidebarSortConfigSchema.parse(sharedSortConfig);
|
|
103
|
+
sortConfigPages[`${path.posix.dirname(page.fullPath)}`] = sharedSortConfig;
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
/**
|
|
107
|
+
* Don't throw a PluginError here as this will stop the sidebar being generated.
|
|
108
|
+
* Plugins need a way to log errors/warnings without exceptions
|
|
109
|
+
*/
|
|
110
|
+
console.error(`[Mosaic] SidebarPlugin - Invalid sidebar sort config found in ${page.fullPath}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const priority = page.sidebar?.priority;
|
|
114
|
+
const id = page.route;
|
|
115
|
+
const isGroup = /\/index$/.test(page.route);
|
|
116
|
+
const groupPath = path.posix.dirname(page.fullPath);
|
|
117
|
+
const level = getPageLevel(page);
|
|
118
|
+
const newChildNode = {
|
|
119
|
+
id,
|
|
120
|
+
fullPath: page.fullPath,
|
|
121
|
+
name,
|
|
122
|
+
priority,
|
|
123
|
+
data: { level, link: page.route },
|
|
124
|
+
childNodes: []
|
|
125
|
+
};
|
|
126
|
+
if (!isGroup && sortConfigPages[`${path.posix.dirname(page.fullPath)}`] !== undefined) {
|
|
127
|
+
const fieldData = getSortFieldData(page, sortConfigPages[`${path.posix.dirname(page.fullPath)}`]);
|
|
128
|
+
newChildNode.sharedSortConfig = {
|
|
129
|
+
...sortConfigPages[`${path.posix.dirname(page.fullPath)}`],
|
|
130
|
+
fieldData
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (isGroup) {
|
|
134
|
+
result[groupPath] = {
|
|
135
|
+
...newChildNode,
|
|
136
|
+
...result[groupPath]
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
const childNodes = Object.prototype.hasOwnProperty.call(result, groupPath)
|
|
141
|
+
? result[groupPath].childNodes
|
|
142
|
+
: [];
|
|
143
|
+
result[groupPath] = {
|
|
144
|
+
...result[groupPath],
|
|
145
|
+
childNodes: [...childNodes, newChildNode]
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}, {});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Link the group map to their parents
|
|
153
|
+
* @param groupMap - unlinked groups of pages
|
|
154
|
+
* @param dirName - root path of sidebar
|
|
155
|
+
*/
|
|
156
|
+
function linkGroupMap(groupMap, dirName) {
|
|
157
|
+
const linkedGroupMap = cloneDeep(groupMap);
|
|
158
|
+
const sortedGroupMapKeys = Object.keys(linkedGroupMap).sort(sortByPathLevel);
|
|
159
|
+
sortedGroupMapKeys.forEach(groupPath => {
|
|
160
|
+
let parentGroupPath = path.posix.dirname(groupPath);
|
|
161
|
+
if (linkedGroupMap[parentGroupPath] === undefined) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
linkedGroupMap[parentGroupPath].childNodes = [
|
|
165
|
+
...linkedGroupMap[parentGroupPath].childNodes,
|
|
166
|
+
linkedGroupMap[groupPath]
|
|
167
|
+
];
|
|
168
|
+
});
|
|
169
|
+
return [linkedGroupMap[dirName]];
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Link each page to a sidebar.json file via ref
|
|
173
|
+
* @param pages - sidebar pages
|
|
174
|
+
* @param dirName - root path of sidebar
|
|
175
|
+
*/
|
|
176
|
+
function addSidebarDataToFrontmatter(pages, dirName) {
|
|
177
|
+
pages.forEach(page => {
|
|
178
|
+
config.setRef(String(page.fullPath), ['sidebarData', '$ref'], path.posix.join(dirName, filename, '#', 'pages'));
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
const createNavigationRefs = (currPage, prevPage, nextPage) => {
|
|
182
|
+
if (prevPage) {
|
|
183
|
+
config.setRef(currPage, ['navigation', 'prev', 'title', '$ref'], `${prevPage}#/title`);
|
|
184
|
+
config.setRef(currPage, ['navigation', 'prev', 'route', '$ref'], `${prevPage}#/route`);
|
|
78
185
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
.filter(level => level);
|
|
83
|
-
const sidebarRootDir = path_1.default.posix.join('/', ...dirNameLevels.slice(0, dirNameLevels.length < 3 ? dirNameLevels.length : 3), '/');
|
|
84
|
-
config.setRef(String(page.fullPath), ['sidebarData', '$ref'], path_1.default.posix.join(String(sidebarRootDir), options.filename, '#', 'pages'));
|
|
186
|
+
if (nextPage) {
|
|
187
|
+
config.setRef(currPage, ['navigation', 'next', 'title', '$ref'], `${nextPage}#/title`);
|
|
188
|
+
config.setRef(currPage, ['navigation', 'next', 'route', '$ref'], `${nextPage}#/route`);
|
|
85
189
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const pages = (yield Promise.all((yield mutableFilesystem.promises.glob(createFileGlob(['*', '*/index'], pageExtensions), {
|
|
93
|
-
onlyFiles: true,
|
|
94
|
-
cwd: String(dirName),
|
|
95
|
-
ignore: ignorePages.map(ignore => `**/${ignore}`)
|
|
96
|
-
})).map((pagePath) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
const deserialisedPage = yield serialiser.deserialise(pagePath, yield mutableFilesystem.promises.readFile(pagePath));
|
|
98
|
-
return deserialisedPage;
|
|
99
|
-
}))))
|
|
100
|
-
.filter(page => filterFn(page))
|
|
101
|
-
.sort((pageA, pageB) => sortFn(pageA, pageB, dirName));
|
|
102
|
-
for (let i = 0; i < pages.length; i++) {
|
|
103
|
-
setPageRefs(sidebarFilePath, pages[i], i);
|
|
104
|
-
setChildPageRefs(pages[i], dirName, i, sidebarFilePath);
|
|
105
|
-
addSidebarDataToFrontmatter(pages[i], dirName);
|
|
190
|
+
};
|
|
191
|
+
function addNavigationToFrontmatter(pages) {
|
|
192
|
+
let prevParentPage, nextParentPage;
|
|
193
|
+
const getLastPage = pages => {
|
|
194
|
+
if (pages[pages.length - 1].childNodes?.length) {
|
|
195
|
+
return getLastPage(pages[pages.length - 1].childNodes);
|
|
106
196
|
}
|
|
107
|
-
|
|
197
|
+
return pages[pages.length - 1];
|
|
198
|
+
};
|
|
199
|
+
const lastPage = getLastPage(pages);
|
|
200
|
+
const isFirstPage = page => page === pages[0];
|
|
201
|
+
const isLastPage = page => page === lastPage;
|
|
202
|
+
function recursiveAddNavigation(pages) {
|
|
203
|
+
pages.forEach((page, pageIndex) => {
|
|
204
|
+
const { fullPath: currPage } = page;
|
|
205
|
+
let prevPage, nextPage;
|
|
206
|
+
prevPage = prevParentPage;
|
|
207
|
+
prevParentPage = isFirstPage(page) ? undefined : pages[pageIndex].fullPath;
|
|
208
|
+
if (page.childNodes?.length) {
|
|
209
|
+
nextPage = page.childNodes[0].fullPath;
|
|
210
|
+
nextParentPage =
|
|
211
|
+
pageIndex < pages.length - 1 ? pages[pageIndex + 1].fullPath : nextParentPage;
|
|
212
|
+
}
|
|
213
|
+
else if (pageIndex < pages.length - 1) {
|
|
214
|
+
nextPage = pages[pageIndex + 1].fullPath;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
nextPage = isLastPage(page) ? undefined : nextParentPage;
|
|
218
|
+
}
|
|
219
|
+
if (currPage !== undefined) {
|
|
220
|
+
createNavigationRefs(currPage, prevPage, nextPage);
|
|
221
|
+
}
|
|
222
|
+
recursiveAddNavigation(page.childNodes);
|
|
223
|
+
});
|
|
108
224
|
}
|
|
225
|
+
recursiveAddNavigation(pages);
|
|
226
|
+
}
|
|
227
|
+
const rootUserJourneys = await mutableFilesystem.promises.glob(rootDirGlob, {
|
|
228
|
+
onlyDirectories: true,
|
|
229
|
+
extglob: true,
|
|
230
|
+
cwd: '/'
|
|
109
231
|
});
|
|
232
|
+
const removeExcludedPages = page => !(page.sidebar && page.sidebar.exclude);
|
|
233
|
+
function moveRootPageDown(pagesByPriority) {
|
|
234
|
+
const rootPage = pagesByPriority[0];
|
|
235
|
+
const pagesWithRootMovedDown = rootPage.childNodes;
|
|
236
|
+
pagesWithRootMovedDown.unshift(rootPage);
|
|
237
|
+
rootPage.childNodes = [];
|
|
238
|
+
return pagesWithRootMovedDown;
|
|
239
|
+
}
|
|
240
|
+
await Promise.all(rootUserJourneys.map(async (rootDir) => {
|
|
241
|
+
const sidebarFilePath = path.posix.join(String(rootDir), filename);
|
|
242
|
+
const pages = await createPageList(rootDir);
|
|
243
|
+
const includedPages = pages.filter(page => removeExcludedPages(page));
|
|
244
|
+
const groupMap = createGroupMap(includedPages);
|
|
245
|
+
const sidebarData = linkGroupMap(groupMap, rootDir);
|
|
246
|
+
if (sidebarData[0] === undefined) {
|
|
247
|
+
console.warn(`[Mosaic] SidebarPlugin - Unable to create a Sidebar grouping for ${rootDir}`);
|
|
248
|
+
console.log('[Mosaic] SidebarPlugin - likely you have a directory without an index file');
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const sortedSidebarData = sortSidebarData(sidebarData);
|
|
252
|
+
addNavigationToFrontmatter(sortedSidebarData);
|
|
253
|
+
const pagesWithRootMovedDown = moveRootPageDown(sortedSidebarData);
|
|
254
|
+
await mutableFilesystem.promises.writeFile(sidebarFilePath, JSON.stringify({ pages: pagesWithRootMovedDown }));
|
|
255
|
+
addSidebarDataToFrontmatter(pages, rootDir);
|
|
256
|
+
}));
|
|
110
257
|
}
|
|
111
258
|
};
|
|
112
|
-
|
|
259
|
+
export default SidebarPlugin;
|
|
113
260
|
//# sourceMappingURL=SidebarPlugin.js.map
|