@jpmorganchase/mosaic-plugins 0.1.0-beta.3 → 0.1.0-beta.30
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 +55 -0
- package/dist/$AliasPlugin.js.map +1 -0
- package/dist/$CodeModPlugin.d.ts +7 -0
- package/dist/$CodeModPlugin.js +24 -0
- package/dist/$CodeModPlugin.js.map +1 -0
- package/dist/$RefPlugin.d.ts +31 -0
- package/dist/$RefPlugin.js +119 -0
- package/dist/$RefPlugin.js.map +1 -0
- package/dist/$TagPlugin.d.ts +28 -0
- package/dist/$TagPlugin.js +65 -0
- package/dist/$TagPlugin.js.map +1 -0
- package/dist/BreadcrumbsPlugin.d.ts +18 -0
- package/dist/BreadcrumbsPlugin.js +38 -0
- package/dist/BreadcrumbsPlugin.js.map +1 -0
- package/dist/BrokenLinksPlugin.d.ts +10 -0
- package/dist/BrokenLinksPlugin.js +80 -0
- package/dist/BrokenLinksPlugin.js.map +1 -0
- package/dist/LazyPagePlugin.d.ts +14 -0
- package/dist/LazyPagePlugin.js +63 -0
- package/dist/LazyPagePlugin.js.map +1 -0
- package/dist/LocalFolderSavePlugin.d.ts +6 -0
- package/dist/LocalFolderSavePlugin.js +21 -0
- package/dist/LocalFolderSavePlugin.js.map +1 -0
- package/dist/PagesWithoutFileExtPlugin.d.ts +9 -0
- package/dist/PagesWithoutFileExtPlugin.js +29 -0
- package/dist/PagesWithoutFileExtPlugin.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 +23 -0
- package/dist/ReadingTimePlugin.js.map +1 -0
- package/dist/SearchIndexPlugin.d.ts +56 -0
- package/dist/SearchIndexPlugin.js +152 -0
- package/dist/SearchIndexPlugin.js.map +1 -0
- package/dist/SharedConfigPlugin.d.ts +13 -0
- package/dist/SharedConfigPlugin.js +34 -0
- package/dist/SharedConfigPlugin.js.map +1 -0
- package/dist/SidebarPlugin.d.ts +38 -0
- package/dist/SidebarPlugin.js +207 -0
- package/dist/SidebarPlugin.js.map +1 -0
- package/dist/SiteMapPlugin.d.ts +6 -0
- package/dist/SiteMapPlugin.js +27 -0
- package/dist/SiteMapPlugin.js.map +1 -0
- package/dist/TableOfContentsPlugin.d.ts +20 -0
- package/dist/TableOfContentsPlugin.js +43 -0
- package/dist/TableOfContentsPlugin.js.map +1 -0
- package/dist/utils/normaliseRefs.d.ts +1 -0
- package/dist/utils/normaliseRefs.js +66 -0
- package/dist/utils/normaliseRefs.js.map +1 -0
- package/package.json +41 -15
- package/.turbo/turbo-build.log +0 -14
- package/CHANGELOG.md +0 -34
- package/src/$AliasPlugin.ts +0 -62
- package/src/$CodeModPlugin.ts +0 -34
- package/src/$RefPlugin.ts +0 -200
- package/src/$TagPlugin.ts +0 -99
- package/src/BreadcrumbsPlugin.ts +0 -43
- package/src/LazyPagePlugin.ts +0 -101
- package/src/NextPrevPagePlugin.ts +0 -80
- package/src/PagesWithoutFileExtPlugin.ts +0 -38
- package/src/ReadingTimePlugin.mjs.ts +0 -32
- package/src/SharedConfigPlugin.ts +0 -49
- package/src/SidebarPlugin.ts +0 -154
- package/src/SiteMapPlugin.ts +0 -44
- package/src/TableOfContentsPlugin.mjs.ts +0 -52
- package/src/utils/normaliseRefs.ts +0 -85
- package/tsconfig.json +0 -21
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import mdx from '@jpmorganchase/mosaic-serialisers/mdx';
|
|
4
|
+
const LocalFolderSavePlugin = {
|
|
5
|
+
async saveContent(filePath, data, sourceOptions, { namespace }) {
|
|
6
|
+
const { markdown } = data;
|
|
7
|
+
const { rootDir, prefixDir } = sourceOptions;
|
|
8
|
+
if (namespace !== 'local') {
|
|
9
|
+
// indicate to the Plugin Runner that no save happened
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const pathOnDisk = path.posix.join(rootDir, filePath.replace(new RegExp(`${prefixDir}/`), ''));
|
|
13
|
+
const rawPage = await fs.promises.readFile(pathOnDisk);
|
|
14
|
+
const { content, ...metadata } = await mdx.deserialise(pathOnDisk, rawPage);
|
|
15
|
+
const updatedPage = { ...metadata, content: markdown };
|
|
16
|
+
await fs.promises.writeFile(pathOnDisk, await mdx.serialise(pathOnDisk, updatedPage));
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
export default LocalFolderSavePlugin;
|
|
21
|
+
//# sourceMappingURL=LocalFolderSavePlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalFolderSavePlugin.js","sourceRoot":"","sources":["../src/LocalFolderSavePlugin.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,OAAO,GAAG,MAAM,uCAAuC,CAAC;AAMxD,MAAM,qBAAqB,GAAe;IACxC,KAAK,CAAC,WAAW,CACf,QAAQ,EACR,IAA+B,EAC/B,aAAuC,EACvC,EAAE,SAAS,EAAE;QAEb,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAC1B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC;QAE7C,IAAI,SAAS,KAAK,OAAO,EAAE;YACzB,sDAAsD;YACtD,OAAO,KAAK,CAAC;SACd;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC5E,MAAM,WAAW,GAAG,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAEvD,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,SAAS,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
/**
|
|
3
|
+
* Plugin that creates aliases without the file extension for every page emitted by the source.
|
|
4
|
+
* This allows pages to be retrieved from the filesystem without specifying `.mdx` (or whatever file extension is specified in `options.stripExt`).
|
|
5
|
+
* The plugin also modifies the `route` to point to the shorter alias. Friendly fullPaths are the shortest possible paths that
|
|
6
|
+
* will point to the page (see `Page` docs)
|
|
7
|
+
*/
|
|
8
|
+
declare const PagesWithoutFileExtPlugin: PluginType;
|
|
9
|
+
export default PagesWithoutFileExtPlugin;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { escapeRegExp } from 'lodash-es';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
function createPageTest(ignorePages, pageExtensions) {
|
|
4
|
+
const extTest = new RegExp(`${pageExtensions.map(escapeRegExp).join('|')}$`);
|
|
5
|
+
const ignoreTest = new RegExp(`${ignorePages.map(escapeRegExp).join('|')}$`);
|
|
6
|
+
return file => !ignoreTest.test(file) && extTest.test(file) && !path.basename(file).startsWith('.');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Plugin that creates aliases without the file extension for every page emitted by the source.
|
|
10
|
+
* This allows pages to be retrieved from the filesystem without specifying `.mdx` (or whatever file extension is specified in `options.stripExt`).
|
|
11
|
+
* The plugin also modifies the `route` to point to the shorter alias. Friendly fullPaths are the shortest possible paths that
|
|
12
|
+
* will point to the page (see `Page` docs)
|
|
13
|
+
*/
|
|
14
|
+
const PagesWithoutFileExtPlugin = {
|
|
15
|
+
async $afterSource(pages, { config, ignorePages, pageExtensions }) {
|
|
16
|
+
const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
|
|
17
|
+
const pageTest = new RegExp(`${pageExtensions.map(escapeRegExp).join('|')}$`);
|
|
18
|
+
for (const page of pages) {
|
|
19
|
+
if (!isNonHiddenPage(page.fullPath)) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
page.route = page.route.replace(pageTest, '');
|
|
23
|
+
config.setAliases(page.fullPath, [page.route]);
|
|
24
|
+
}
|
|
25
|
+
return pages;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
export default PagesWithoutFileExtPlugin;
|
|
29
|
+
//# sourceMappingURL=PagesWithoutFileExtPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PagesWithoutFileExtPlugin.js","sourceRoot":"","sources":["../src/PagesWithoutFileExtPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,SAAS,cAAc,CAAC,WAAW,EAAE,cAAc;IACjD,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC,EAAE,CACZ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACzF,CAAC;AAED;;;;;GAKG;AACH,MAAM,yBAAyB,GAAe;IAC5C,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE;QAC/D,MAAM,eAAe,GAAG,cAAc,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE9E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;gBACnC,SAAS;aACV;YACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC9C,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;SAChD;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Page, Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
interface PublicAssetsPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* The directory to copy the assets to
|
|
5
|
+
* @default './public'
|
|
6
|
+
*/
|
|
7
|
+
outputDir?: string;
|
|
8
|
+
/**
|
|
9
|
+
* A collection of filenames to copy to the outputDir
|
|
10
|
+
*/
|
|
11
|
+
assets?: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Plugin that finds `assets` in the Mosaic filesytem and copies them to the specified outputDir.
|
|
15
|
+
* Typical use case is for assets like a sitemap
|
|
16
|
+
*/
|
|
17
|
+
declare const PublicAssetsPlugin: PluginType<Page, PublicAssetsPluginOptions>;
|
|
18
|
+
export default PublicAssetsPlugin;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import fsExtra from 'fs-extra';
|
|
4
|
+
/**
|
|
5
|
+
* Plugin that finds `assets` in the Mosaic filesytem and copies them to the specified outputDir.
|
|
6
|
+
* Typical use case is for assets like a sitemap
|
|
7
|
+
*/
|
|
8
|
+
const PublicAssetsPlugin = {
|
|
9
|
+
async afterUpdate(_, { sharedFilesystem }, { assets = [], outputDir = './public' }) {
|
|
10
|
+
if (assets.length > 0) {
|
|
11
|
+
await fsExtra.ensureDir(outputDir);
|
|
12
|
+
await Promise.all(assets.map(async (asset) => {
|
|
13
|
+
const allFiles = await sharedFilesystem.promises.glob(`**/${asset}`, {
|
|
14
|
+
cwd: '/',
|
|
15
|
+
onlyFiles: true
|
|
16
|
+
});
|
|
17
|
+
if (allFiles?.length > 0) {
|
|
18
|
+
await Promise.all(allFiles.map(async (file) => {
|
|
19
|
+
const data = await sharedFilesystem.promises.readFile(file);
|
|
20
|
+
await fs.promises.writeFile(path.posix.join(path.posix.resolve(outputDir), file), data);
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
export default PublicAssetsPlugin;
|
|
28
|
+
//# sourceMappingURL=PublicAssetsPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicAssetsPlugin.js","sourceRoot":"","sources":["../src/PublicAssetsPlugin.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,OAAO,MAAM,UAAU,CAAC;AAc/B;;;GAGG;AACH,MAAM,kBAAkB,GAAgD;IACtE,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,SAAS,GAAG,UAAU,EAAE;QAChF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,MAAM,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAEnC,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,GAAG,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;gBACvB,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE;oBACnE,GAAG,EAAE,GAAG;oBACR,SAAS,EAAE,IAAI;iBAChB,CAAC,CAAC;gBAEH,IAAI,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;oBACxB,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;wBACxB,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;wBAC5D,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,EACpD,IAAI,CACL,CAAC;oBACJ,CAAC,CAAC,CACH,CAAC;iBACH;YACH,CAAC,CAAC,CACH,CAAC;SACH;IACH,CAAC;CACF,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Page, Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
import getReadingTime from 'reading-time';
|
|
3
|
+
interface ReadingTimePluginPage extends Page {
|
|
4
|
+
readingTime?: ReturnType<typeof getReadingTime>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Calculates reading time for pages and adds to frontmatter
|
|
8
|
+
*/
|
|
9
|
+
declare const ReadingTimePlugin: PluginType<ReadingTimePluginPage>;
|
|
10
|
+
export default ReadingTimePlugin;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import getReadingTime from 'reading-time';
|
|
2
|
+
import markdown from 'remark-parse';
|
|
3
|
+
import { unified } from 'unified';
|
|
4
|
+
import { visit } from 'unist-util-visit';
|
|
5
|
+
/**
|
|
6
|
+
* Calculates reading time for pages and adds to frontmatter
|
|
7
|
+
*/
|
|
8
|
+
const ReadingTimePlugin = {
|
|
9
|
+
async $afterSource(pages) {
|
|
10
|
+
const processor = unified().use(markdown);
|
|
11
|
+
for (const page of pages) {
|
|
12
|
+
const tree = await processor.parse(page.content);
|
|
13
|
+
let textContent = '';
|
|
14
|
+
visit(tree, node => node.type === 'text' || node.type === 'code', (node) => {
|
|
15
|
+
textContent += node.value;
|
|
16
|
+
});
|
|
17
|
+
page.readingTime = getReadingTime(textContent);
|
|
18
|
+
}
|
|
19
|
+
return pages;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export default ReadingTimePlugin;
|
|
23
|
+
//# sourceMappingURL=ReadingTimePlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReadingTimePlugin.js","sourceRoot":"","sources":["../src/ReadingTimePlugin.ts"],"names":[],"mappings":"AACA,OAAO,cAAc,MAAM,cAAc,CAAC;AAC1C,OAAO,QAAQ,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAWzC;;GAEG;AACH,MAAM,iBAAiB,GAAsC;IAC3D,KAAK,CAAC,YAAY,CAAC,KAAK;QACtB,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,WAAW,GAAG,EAAE,CAAC;YAErB,KAAK,CACH,IAAI,EACJ,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EACpD,CAAC,IAAc,EAAE,EAAE;gBACjB,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC;YAC5B,CAAC,CACF,CAAC;YACF,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;SAChD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Page, Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
interface SearchRelevancy {
|
|
3
|
+
includeScore?: boolean;
|
|
4
|
+
includeMatches?: boolean;
|
|
5
|
+
maxPatternLength?: number;
|
|
6
|
+
ignoreLocation?: boolean;
|
|
7
|
+
threshold?: number;
|
|
8
|
+
keys?: string[] | {
|
|
9
|
+
name: string;
|
|
10
|
+
weight: number;
|
|
11
|
+
}[];
|
|
12
|
+
}
|
|
13
|
+
interface SearchIndexPluginOptions {
|
|
14
|
+
maxLineLength?: number;
|
|
15
|
+
maxLineCount?: number;
|
|
16
|
+
keys?: string[];
|
|
17
|
+
relevancy?: SearchRelevancy;
|
|
18
|
+
}
|
|
19
|
+
interface Optimization {
|
|
20
|
+
content: string;
|
|
21
|
+
title: string;
|
|
22
|
+
maxLineCount?: number;
|
|
23
|
+
maxLineLength?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* There are three scenarios for the "keys":
|
|
27
|
+
*
|
|
28
|
+
* 1. No keys are specified in the plugin options. In this case, we'll use the fallback keys.
|
|
29
|
+
* 2. The keys are specified as an array of strings. In this case, we'll add the required keys to the array.
|
|
30
|
+
* 3. The keys are specified as an array of objects. In this case, we can assume "weighting" is being applied
|
|
31
|
+
* so we'll only return the keys that have been specified in the options.
|
|
32
|
+
*
|
|
33
|
+
* @param optionKeys array of keys specified in the plugin options
|
|
34
|
+
* @returns array of keys to be used in the search index
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseKeys(optionKeys?: any[]): any[];
|
|
37
|
+
/**
|
|
38
|
+
* Converts raw content string into an array of sentences suitable for inclusion
|
|
39
|
+
* in the search index
|
|
40
|
+
*
|
|
41
|
+
* @param options.content the raw content string
|
|
42
|
+
* @param options.title the title of the page (used for adding context to parse errors)
|
|
43
|
+
* @param options.maxLineLength the maximum length of a sentence (set this to match the
|
|
44
|
+
* "location" option in your Fuse.js configuration). Sentences longer than this value will be
|
|
45
|
+
* truncated.
|
|
46
|
+
* @param options.maxLineCount the maximum number of lines to include in the search index for
|
|
47
|
+
* each page. Pages with more lines than this value will be truncated.
|
|
48
|
+
* @returns array of sentence strings
|
|
49
|
+
*/
|
|
50
|
+
export declare const optimizeContentForSearch: ({ content, title, maxLineLength, maxLineCount }: Optimization) => Promise<string[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a search-data.json file that contains all the information
|
|
53
|
+
* from each page that is required to generate a search index.
|
|
54
|
+
*/
|
|
55
|
+
declare const SearchIndexPlugin: PluginType<Page, SearchIndexPluginOptions>;
|
|
56
|
+
export default SearchIndexPlugin;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { unified } from 'unified';
|
|
2
|
+
import markdown from 'remark-parse';
|
|
3
|
+
import remarkMdx from 'remark-mdx';
|
|
4
|
+
import { visit } from 'unist-util-visit';
|
|
5
|
+
const defaultRelevancyOptions = {
|
|
6
|
+
includeScore: true,
|
|
7
|
+
includeMatches: true,
|
|
8
|
+
maxPatternLength: 240,
|
|
9
|
+
ignoreLocation: true,
|
|
10
|
+
threshold: 0.3
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* We need these keys to *always* be included in the search index.
|
|
14
|
+
* Without the title, there would be no way to display the search results.
|
|
15
|
+
* Without the route, there would be no way to navigate to the page.
|
|
16
|
+
*/
|
|
17
|
+
const requiredKeys = ['title', 'route'];
|
|
18
|
+
/**
|
|
19
|
+
* If there are no keys specified in the plugin options, we'll use these
|
|
20
|
+
*/
|
|
21
|
+
const fallbackKeys = [...requiredKeys, 'content'];
|
|
22
|
+
/**
|
|
23
|
+
* There are three scenarios for the "keys":
|
|
24
|
+
*
|
|
25
|
+
* 1. No keys are specified in the plugin options. In this case, we'll use the fallback keys.
|
|
26
|
+
* 2. The keys are specified as an array of strings. In this case, we'll add the required keys to the array.
|
|
27
|
+
* 3. The keys are specified as an array of objects. In this case, we can assume "weighting" is being applied
|
|
28
|
+
* so we'll only return the keys that have been specified in the options.
|
|
29
|
+
*
|
|
30
|
+
* @param optionKeys array of keys specified in the plugin options
|
|
31
|
+
* @returns array of keys to be used in the search index
|
|
32
|
+
*/
|
|
33
|
+
export function parseKeys(optionKeys = []) {
|
|
34
|
+
if (optionKeys.length < 1)
|
|
35
|
+
return fallbackKeys;
|
|
36
|
+
if (typeof optionKeys[0] === 'string')
|
|
37
|
+
return [...requiredKeys, ...optionKeys];
|
|
38
|
+
return optionKeys;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Converts raw content string into an array of sentences suitable for inclusion
|
|
42
|
+
* in the search index
|
|
43
|
+
*
|
|
44
|
+
* @param options.content the raw content string
|
|
45
|
+
* @param options.title the title of the page (used for adding context to parse errors)
|
|
46
|
+
* @param options.maxLineLength the maximum length of a sentence (set this to match the
|
|
47
|
+
* "location" option in your Fuse.js configuration). Sentences longer than this value will be
|
|
48
|
+
* truncated.
|
|
49
|
+
* @param options.maxLineCount the maximum number of lines to include in the search index for
|
|
50
|
+
* each page. Pages with more lines than this value will be truncated.
|
|
51
|
+
* @returns array of sentence strings
|
|
52
|
+
*/
|
|
53
|
+
export const optimizeContentForSearch = async ({ content, title, maxLineLength, maxLineCount }) => {
|
|
54
|
+
if (!content || content.length < 1)
|
|
55
|
+
return [content];
|
|
56
|
+
const processor = unified().use(markdown).use(remarkMdx);
|
|
57
|
+
let tree;
|
|
58
|
+
try {
|
|
59
|
+
tree = await processor.parse(content);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error(`Search Index Plugin failed to parse content for ${title}`, err.reason);
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
const sentences = [];
|
|
66
|
+
const segmenter = new Intl.Segmenter('en', { granularity: 'sentence' });
|
|
67
|
+
visit(tree, (node) => node.type === 'text' || node.type === 'code', (node) => {
|
|
68
|
+
const segments = [...segmenter.segment(node.value)].map(segment => segment.segment);
|
|
69
|
+
segments.forEach(segment => {
|
|
70
|
+
if (maxLineLength) {
|
|
71
|
+
sentences.push(segment.slice(0, maxLineLength));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
sentences.push(segment);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
if (maxLineCount) {
|
|
79
|
+
return sentences.slice(0, maxLineCount);
|
|
80
|
+
}
|
|
81
|
+
return sentences;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Creates a search-data.json file that contains all the information
|
|
85
|
+
* from each page that is required to generate a search index.
|
|
86
|
+
*/
|
|
87
|
+
const SearchIndexPlugin = {
|
|
88
|
+
/**
|
|
89
|
+
* For each source, parse the data we want to add to the search index and
|
|
90
|
+
* save it to the global config (to be saved to the filesystem later when
|
|
91
|
+
* all sources have been loaded).
|
|
92
|
+
*/
|
|
93
|
+
async $beforeSend(mutableFilesystem, { config, serialiser, ignorePages }, { maxLineLength, maxLineCount, keys: optionKeys }) {
|
|
94
|
+
const pages = await Promise.all((await mutableFilesystem.promises.glob('**', {
|
|
95
|
+
onlyFiles: true,
|
|
96
|
+
ignore: ignorePages.map(ignore => `**/${ignore}`),
|
|
97
|
+
cwd: '/'
|
|
98
|
+
})).map(async (pagePath) => {
|
|
99
|
+
const deserialisedPage = await serialiser.deserialise(pagePath, await mutableFilesystem.promises.readFile(pagePath));
|
|
100
|
+
return deserialisedPage;
|
|
101
|
+
}));
|
|
102
|
+
const searchData = await Promise.all(pages.map(async (page) => {
|
|
103
|
+
const content = await optimizeContentForSearch({
|
|
104
|
+
content: page.content || '',
|
|
105
|
+
title: page.title || '',
|
|
106
|
+
maxLineLength,
|
|
107
|
+
maxLineCount
|
|
108
|
+
});
|
|
109
|
+
const keys = parseKeys(optionKeys);
|
|
110
|
+
/**
|
|
111
|
+
* If the "content" key is specified, we want to include the result of
|
|
112
|
+
* the optimizeContentForSearch() function. Otherwise, we include the
|
|
113
|
+
* key value directly from the page data.
|
|
114
|
+
*/
|
|
115
|
+
return keys.reduce((acc, key) => ({ ...acc, [key]: key === 'content' ? content : page[key] }), {});
|
|
116
|
+
}));
|
|
117
|
+
/**
|
|
118
|
+
* Convert the searchData into an object where each page has a unique key (the
|
|
119
|
+
* route) so that the "merge" in `config.setData()` will correctly combine all
|
|
120
|
+
* the results from multiple sources.
|
|
121
|
+
*/
|
|
122
|
+
const searchDataKeyedByRoute = searchData.reduce((acc, curr) => ({
|
|
123
|
+
...acc,
|
|
124
|
+
[curr.route]: curr
|
|
125
|
+
}), {});
|
|
126
|
+
config.setData({
|
|
127
|
+
searchIndices: searchDataKeyedByRoute
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
/**
|
|
131
|
+
* Once we have all the sources' search data added to `globalConfig`, convert it
|
|
132
|
+
* to JSON and save it to the filesystem.
|
|
133
|
+
*/
|
|
134
|
+
async afterUpdate(_, { sharedFilesystem, globalConfig }, { keys: optionKeys, relevancy }) {
|
|
135
|
+
if (!globalConfig.data.searchIndices)
|
|
136
|
+
return;
|
|
137
|
+
const globalSearchIndices = globalConfig.data.searchIndices;
|
|
138
|
+
const searchData = Object.values(globalSearchIndices);
|
|
139
|
+
const condensedSearchData = searchData.map(page => ({ title: page.title, route: page.route }));
|
|
140
|
+
const keys = parseKeys(optionKeys);
|
|
141
|
+
const searchConfig = {
|
|
142
|
+
...defaultRelevancyOptions,
|
|
143
|
+
...relevancy,
|
|
144
|
+
keys
|
|
145
|
+
};
|
|
146
|
+
await sharedFilesystem.promises.writeFile('/search-config.json', JSON.stringify(searchConfig));
|
|
147
|
+
await sharedFilesystem.promises.writeFile('/search-data.json', JSON.stringify(searchData));
|
|
148
|
+
await sharedFilesystem.promises.writeFile('/search-data-condensed.json', JSON.stringify(condensedSearchData));
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
export default SearchIndexPlugin;
|
|
152
|
+
//# sourceMappingURL=SearchIndexPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchIndexPlugin.js","sourceRoot":"","sources":["../src/SearchIndexPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Page, Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
interface SharedConfigPluginPage extends Page {
|
|
3
|
+
sharedConfig?: string;
|
|
4
|
+
}
|
|
5
|
+
interface SharedConfigPluginOptions {
|
|
6
|
+
filename: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Plugin that crawls the page hierarchy to find the closest `sharedConfig` from any parent index's page metadata.
|
|
10
|
+
* It then exports a JSON file (name: `options.filename`) into each directory with the merged config for that level
|
|
11
|
+
*/
|
|
12
|
+
declare const SharedConfigPlugin: PluginType<SharedConfigPluginPage, SharedConfigPluginOptions>;
|
|
13
|
+
export default SharedConfigPlugin;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { flatten } from 'lodash-es';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
function createFileGlob(url, pageExtensions) {
|
|
4
|
+
if (pageExtensions.length === 1) {
|
|
5
|
+
return `${url}${pageExtensions[0]}`;
|
|
6
|
+
}
|
|
7
|
+
return `${url}{${pageExtensions.join(',')}}`;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Plugin that crawls the page hierarchy to find the closest `sharedConfig` from any parent index's page metadata.
|
|
11
|
+
* It then exports a JSON file (name: `options.filename`) into each directory with the merged config for that level
|
|
12
|
+
*/
|
|
13
|
+
const SharedConfigPlugin = {
|
|
14
|
+
async $beforeSend(mutableFilesystem, { config, serialiser, ignorePages, pageExtensions }, options) {
|
|
15
|
+
const pagePaths = await mutableFilesystem.promises.glob(createFileGlob('**/index', pageExtensions), {
|
|
16
|
+
ignore: [options.filename, ...flatten(ignorePages.map(ignore => [ignore, `**/${ignore}`]))],
|
|
17
|
+
cwd: '/'
|
|
18
|
+
});
|
|
19
|
+
for (const pagePath of pagePaths) {
|
|
20
|
+
const sharedConfigFile = path.join(path.dirname(String(pagePath)), options.filename);
|
|
21
|
+
const page = await serialiser.deserialise(String(pagePath), await mutableFilesystem.promises.readFile(String(pagePath)));
|
|
22
|
+
if (page.sharedConfig) {
|
|
23
|
+
config.setRef(sharedConfigFile, ['config', '$ref'], `${String(pagePath)}#/sharedConfig`);
|
|
24
|
+
await mutableFilesystem.promises.writeFile(sharedConfigFile, '{}');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const baseDir = path.posix.resolve(path.dirname(String(pagePath)), '../');
|
|
28
|
+
config.setAliases(path.join(baseDir, options.filename), [sharedConfigFile]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export default SharedConfigPlugin;
|
|
34
|
+
//# sourceMappingURL=SharedConfigPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SharedConfigPlugin.js","sourceRoot":"","sources":["../src/SharedConfigPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,SAAS,cAAc,CAAC,GAAG,EAAE,cAAc;IACzC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/B,OAAO,GAAG,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;KACrC;IACD,OAAO,GAAG,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAC/C,CAAC;AAUD;;;GAGG;AACH,MAAM,kBAAkB,GAAkE;IACxF,KAAK,CAAC,WAAW,CACf,iBAAiB,EACjB,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,EACnD,OAAO;QAEP,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CACrD,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,EAC1C;YACE,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3F,GAAG,EAAE,GAAG;SACT,CACF,CAAC;QAEF,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;YAChC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YAErF,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,WAAW,CACvC,MAAM,CAAC,QAAQ,CAAC,EAChB,MAAM,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAC5D,CAAC;YACF,IAAI,IAAI,CAAC,YAAY,EAAE;gBACrB,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;gBACzF,MAAM,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;aACpE;iBAAM;gBACL,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gBAE1E,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;aAC7E;SACF;IACH,CAAC;CACF,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Plugin as PluginType, Page } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
interface SidebarPluginConfigData {
|
|
3
|
+
dirs: string[];
|
|
4
|
+
refs: {
|
|
5
|
+
[key: string]: {
|
|
6
|
+
$$path: (number | string)[];
|
|
7
|
+
$$value: string;
|
|
8
|
+
}[];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
interface SidebarPluginPage extends Page {
|
|
12
|
+
sidebar?: {
|
|
13
|
+
label?: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
interface SidebarPluginOptions {
|
|
17
|
+
/**
|
|
18
|
+
* filename of the sidebar json, linked to each related page via ref
|
|
19
|
+
*/
|
|
20
|
+
filename: string;
|
|
21
|
+
/**
|
|
22
|
+
* Glob pattern for matching directories which should be the root of the sidebar
|
|
23
|
+
* * creates a root level sidebar containing all pages underneath root
|
|
24
|
+
* *\/* creates a separate sidebar under each of the root directories
|
|
25
|
+
*/
|
|
26
|
+
rootDirGlob: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Sorts the pages in a folder by priority and then exports a JSON file with the
|
|
30
|
+
* sidebar tree from that directory downwards and adds sidebar data into frontmatter for each page.
|
|
31
|
+
*
|
|
32
|
+
* Additionally, add to frontmatter
|
|
33
|
+
* navigation -> prev -> { title, route }
|
|
34
|
+
* navigation -> next -> { title, route }
|
|
35
|
+
* to define the previous/next page in the page sequence, as defined by sidebar label and priority
|
|
36
|
+
*/
|
|
37
|
+
declare const SidebarPlugin: PluginType<SidebarPluginPage, SidebarPluginOptions, SidebarPluginConfigData>;
|
|
38
|
+
export default SidebarPlugin;
|