@jpmorganchase/mosaic-plugins 0.1.0-beta.9 → 0.1.0-beta.90
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 +81 -37
- 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/DocumentAssetsPlugin.d.ts +28 -0
- package/dist/DocumentAssetsPlugin.js +144 -0
- package/dist/DocumentAssetsPlugin.js.map +1 -0
- package/dist/FragmentPlugin.d.ts +3 -0
- package/dist/FragmentPlugin.js +64 -0
- package/dist/FragmentPlugin.js.map +1 -0
- package/dist/LazyPagePlugin.d.ts +14 -0
- package/dist/LazyPagePlugin.js +45 -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 +27 -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 +45 -0
- package/dist/SidebarPlugin.js +276 -87
- 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 +26 -0
- package/dist/TableOfContentsPlugin.js +67 -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 +29 -0
- package/dist/utils/sortSidebarData.js +47 -0
- package/dist/utils/sortSidebarData.js.map +1 -0
- package/package.json +45 -27
- package/CHANGELOG.md +0 -109
- 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
package/dist/$TagPlugin.js
CHANGED
|
@@ -1,26 +1,8 @@
|
|
|
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 path_1 = __importDefault(require("path"));
|
|
16
|
-
const escapeRegExp_1 = __importDefault(require("lodash/escapeRegExp"));
|
|
17
|
-
const reduce_1 = __importDefault(require("lodash/reduce"));
|
|
18
|
-
function createPageTest(ignorePages, pageExtensions) {
|
|
19
|
-
const extTest = new RegExp(`${pageExtensions.map(escapeRegExp_1.default).join('|')}$`);
|
|
20
|
-
const ignoreTest = new RegExp(`${ignorePages.map(escapeRegExp_1.default).join('|')}$`);
|
|
21
|
-
return file => !ignoreTest.test(file) && extTest.test(file) && !path_1.default.basename(file).startsWith('.');
|
|
22
|
-
}
|
|
23
|
-
const findKeys = (obj, targetProp, pathParts = []) => (0, reduce_1.default)(obj, (found, value, key) => {
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { reduce } from 'lodash-es';
|
|
3
|
+
import PluginError from './utils/PluginError.js';
|
|
4
|
+
import { createPageTest } from './utils/createPageTest.js';
|
|
5
|
+
const findKeys = (obj, targetProp, pathParts = []) => reduce(obj, (found, value, key) => {
|
|
24
6
|
if (key === targetProp) {
|
|
25
7
|
return found.concat({ $$path: pathParts.concat(String(key)), $$value: value });
|
|
26
8
|
}
|
|
@@ -40,31 +22,26 @@ const findKeys = (obj, targetProp, pathParts = []) => (0, reduce_1.default)(obj,
|
|
|
40
22
|
const $TagPlugin = {
|
|
41
23
|
// Check if the updated source has any /.tag aliases that we care about - if it does, we should re-run `afterUpdate` to
|
|
42
24
|
// make sure we pull in the latest pages
|
|
43
|
-
shouldClearCache(updatedSourceFilesystem, { config }) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// Does the updated source have tags we are interested in?
|
|
51
|
-
return (yield updatedSourceFilesystem.promises.readdir('/.tags')).some(tag => config.data.subscribedTags.includes(tag));
|
|
52
|
-
});
|
|
25
|
+
async shouldClearCache(updatedSourceFilesystem, { config }) {
|
|
26
|
+
if (!config.data?.subscribedTags ||
|
|
27
|
+
!(await updatedSourceFilesystem.promises.exists('/.tags'))) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
// Does the updated source have tags we are interested in?
|
|
31
|
+
return (await updatedSourceFilesystem.promises.readdir('/.tags')).some(tag => config.data.subscribedTags.includes(tag));
|
|
53
32
|
},
|
|
54
33
|
// Every source with tags will create symlinks with the tagged pages, inside /.tags
|
|
55
|
-
$afterSource(pages, { config, ignorePages, pageExtensions }) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
for (const page of pages) {
|
|
34
|
+
async $afterSource(pages, { config, ignorePages, pageExtensions }) {
|
|
35
|
+
const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
|
|
36
|
+
for (const page of pages) {
|
|
37
|
+
try {
|
|
60
38
|
if (!isNonHiddenPage(page.fullPath)) {
|
|
61
39
|
continue;
|
|
62
40
|
}
|
|
63
41
|
const meta = page;
|
|
64
42
|
// Symlink every `tag` item to '/.tags' folder
|
|
65
|
-
if (
|
|
43
|
+
if (meta.tags?.length) {
|
|
66
44
|
config.setTags(page.fullPath, meta.tags);
|
|
67
|
-
delete meta.tags;
|
|
68
45
|
}
|
|
69
46
|
// Find any references to $tag
|
|
70
47
|
const foundTags = findKeys(page, '$tag');
|
|
@@ -73,14 +50,17 @@ const $TagPlugin = {
|
|
|
73
50
|
foundTags.forEach(ref => {
|
|
74
51
|
const [tag, fragment = ''] = ref.$$value.split('#');
|
|
75
52
|
tags.add(tag);
|
|
76
|
-
config.setGlobalRef(page.fullPath, ref.$$path, `${
|
|
53
|
+
config.setGlobalRef(page.fullPath, ref.$$path, `${path.posix.join('/.tags', tag, '**', '*')}#${fragment}`);
|
|
77
54
|
});
|
|
78
55
|
config.setData({ subscribedTags: Array.from(tags) });
|
|
79
56
|
}
|
|
80
57
|
}
|
|
81
|
-
|
|
82
|
-
|
|
58
|
+
catch (e) {
|
|
59
|
+
throw new PluginError(e.message, page.fullPath);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return pages;
|
|
83
63
|
}
|
|
84
64
|
};
|
|
85
|
-
|
|
65
|
+
export default $TagPlugin;
|
|
86
66
|
//# sourceMappingURL=$TagPlugin.js.map
|
package/dist/$TagPlugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"$TagPlugin.js","sourceRoot":"","sources":["../src/$TagPlugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"$TagPlugin.js","sourceRoot":"","sources":["../src/$TagPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
import { SidebarPluginPage } from './SidebarPlugin.js';
|
|
3
|
+
export type Breadcrumb = {
|
|
4
|
+
label: string;
|
|
5
|
+
path: string;
|
|
6
|
+
id: string;
|
|
7
|
+
};
|
|
8
|
+
export interface BreadcrumbsPluginPage extends SidebarPluginPage {
|
|
9
|
+
breadcrumbs?: Array<Breadcrumb>;
|
|
10
|
+
layout?: string;
|
|
11
|
+
}
|
|
12
|
+
interface BreadcrumbsPluginOptions {
|
|
13
|
+
indexPageName: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Calculates breadcrumbs for pages then embeds a `breadcrumbs` property to the metadata
|
|
17
|
+
*/
|
|
18
|
+
declare const BreadcrumbsPlugin: PluginType<BreadcrumbsPluginPage, BreadcrumbsPluginOptions>;
|
|
19
|
+
export default BreadcrumbsPlugin;
|
|
@@ -1,51 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
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 'node:path';
|
|
2
|
+
import PluginError from './utils/PluginError.js';
|
|
3
|
+
import { createPageTest } from './utils/createPageTest.js';
|
|
16
4
|
/**
|
|
17
5
|
* Calculates breadcrumbs for pages then embeds a `breadcrumbs` property to the metadata
|
|
18
6
|
*/
|
|
19
7
|
const BreadcrumbsPlugin = {
|
|
20
|
-
$afterSource(pages,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
8
|
+
async $afterSource(pages, { ignorePages, pageExtensions }, options) {
|
|
9
|
+
const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
|
|
10
|
+
for (const page of pages) {
|
|
11
|
+
if (!isNonHiddenPage(page.fullPath)) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const pathParts = page.fullPath.replace(/^[/]/, '').split('/');
|
|
16
|
+
const topAndTailedPath = pathParts.slice(1, -1);
|
|
17
|
+
const breadcrumbs = topAndTailedPath.reduce((result, _pathPart, partIndex) => {
|
|
18
|
+
const breadcrumbRoot = `/${pathParts[0]}`;
|
|
19
|
+
const breadcrumbPath = path.posix.join(breadcrumbRoot, ...topAndTailedPath.slice(0, topAndTailedPath.length - partIndex), options.indexPageName);
|
|
20
|
+
const breadcrumbPage = pages.find(
|
|
27
21
|
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
item => item.fullPath === breadcrumbPath);
|
|
23
|
+
if (breadcrumbPage) {
|
|
24
|
+
result.unshift({
|
|
25
|
+
label: breadcrumbPage.sidebar?.groupLabel ||
|
|
26
|
+
breadcrumbPage.sidebar?.label ||
|
|
27
|
+
breadcrumbPage.title,
|
|
28
|
+
path: breadcrumbPage.route,
|
|
29
|
+
id: breadcrumbPage.fullPath
|
|
33
30
|
});
|
|
34
31
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
item => item.fullPath === path_1.default.posix.join(parentDir, options.indexPageName));
|
|
38
|
-
if (currentPage) {
|
|
39
|
-
parentDir = path_1.default.posix.dirname(path_1.default.posix.join(String(currentPage.fullPath), '..'));
|
|
40
|
-
}
|
|
41
|
-
}
|
|
32
|
+
return result;
|
|
33
|
+
}, []);
|
|
42
34
|
if (!page.breadcrumbs) {
|
|
43
35
|
page.breadcrumbs = breadcrumbs;
|
|
44
36
|
}
|
|
45
37
|
}
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
catch (e) {
|
|
39
|
+
throw new PluginError(e.message, page.fullPath);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return pages;
|
|
43
|
+
},
|
|
44
|
+
async afterNamespaceSourceUpdate(mutableFilesystem, { serialiser, globalFilesystem, ignorePages }, options) {
|
|
45
|
+
const pages = (await mutableFilesystem.promises.glob('**', {
|
|
46
|
+
onlyFiles: true,
|
|
47
|
+
ignore: ignorePages.map(ignore => `**/${ignore}`),
|
|
48
|
+
cwd: '/'
|
|
49
|
+
}));
|
|
50
|
+
if (pages.length > 0) {
|
|
51
|
+
let updatedBreadcrumbs = [];
|
|
52
|
+
const { breadcrumbs } = await serialiser.deserialise(pages[0], await mutableFilesystem.promises.readFile(pages[0]));
|
|
53
|
+
// the root breadcrumb is the first breadcrumb for all pages in a source. It is essentially the "first" page in a source
|
|
54
|
+
const rootBreadcrumb = breadcrumbs?.[0] || undefined;
|
|
55
|
+
if (rootBreadcrumb) {
|
|
56
|
+
let parentDir = path.posix.join(path.posix.dirname(rootBreadcrumb.id), '../');
|
|
57
|
+
while (parentDir !== '/') {
|
|
58
|
+
const parentDirIndex = path.posix.join(parentDir, options.indexPageName);
|
|
59
|
+
// check for this file in the global fs so we have a holistic view of all site pages
|
|
60
|
+
if (await globalFilesystem.promises.exists(parentDirIndex)) {
|
|
61
|
+
const { breadcrumbs: parentDirBreadcrumbs } = await serialiser.deserialise(rootBreadcrumb.id, await globalFilesystem.promises.readFile(parentDirIndex));
|
|
62
|
+
updatedBreadcrumbs = parentDirBreadcrumbs;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
parentDir = path.posix.join(path.posix.dirname(parentDirIndex), '../');
|
|
66
|
+
}
|
|
67
|
+
if (updatedBreadcrumbs.length > 0) {
|
|
68
|
+
for (const pagePath of pages) {
|
|
69
|
+
const page = await serialiser.deserialise(pagePath, await mutableFilesystem.promises.readFile(pagePath));
|
|
70
|
+
// append the parent breadcrumbs **before** the current breadcrumbs
|
|
71
|
+
page.breadcrumbs = [...updatedBreadcrumbs, ...page.breadcrumbs];
|
|
72
|
+
await mutableFilesystem.promises.writeFile(pagePath, await serialiser.serialise(pagePath, page));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
async shouldUpdateNamespaceSources(updatedSourceFilesystem, { ignorePages, namespace }) {
|
|
79
|
+
/**
|
|
80
|
+
* Only trigger an update when the updated source happens to be the "root" namespace source
|
|
81
|
+
* This is determined this by checking if the filesystem has files inside the "namespace" directory
|
|
82
|
+
*
|
|
83
|
+
* "child" sources will have the namespace directory but they wont have files until further down the directory hierarchy
|
|
84
|
+
*/
|
|
85
|
+
const namespaceDirFiles = (await updatedSourceFilesystem.promises.glob(`${namespace}/*`, {
|
|
86
|
+
onlyFiles: true,
|
|
87
|
+
ignore: ignorePages.map(ignore => `**/${ignore}`),
|
|
88
|
+
cwd: '/'
|
|
89
|
+
}));
|
|
90
|
+
// the root namespace has updated
|
|
91
|
+
return namespaceDirFiles.length > 0;
|
|
48
92
|
}
|
|
49
93
|
};
|
|
50
|
-
|
|
94
|
+
export default BreadcrumbsPlugin;
|
|
51
95
|
//# sourceMappingURL=BreadcrumbsPlugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BreadcrumbsPlugin.js","sourceRoot":"","sources":["../src/BreadcrumbsPlugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BreadcrumbsPlugin.js","sourceRoot":"","sources":["../src/BreadcrumbsPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Page, Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
interface BrokenLinksPluginPage extends Page {
|
|
3
|
+
}
|
|
4
|
+
interface BrokenLinksPluginOptions {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
skipUrlPatterns?: Array<string | RegExp>;
|
|
7
|
+
proxyEndpoint?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const BrokenLinksPlugin: PluginType<BrokenLinksPluginPage, BrokenLinksPluginOptions>;
|
|
10
|
+
export default BrokenLinksPlugin;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { remark } from 'remark';
|
|
3
|
+
import remarkMdx from 'remark-mdx';
|
|
4
|
+
import checkLinks from 'check-links';
|
|
5
|
+
import { visit } from 'unist-util-visit';
|
|
6
|
+
import proxyAgentPkg from 'https-proxy-agent';
|
|
7
|
+
const { HttpsProxyAgent } = proxyAgentPkg;
|
|
8
|
+
async function checkPageLinks(ast, options, fullPath, headings) {
|
|
9
|
+
const urlToNodes = {};
|
|
10
|
+
const aggregate = node => {
|
|
11
|
+
const { url: urlFromNode } = node;
|
|
12
|
+
if (!urlFromNode)
|
|
13
|
+
return;
|
|
14
|
+
const isExternalUrl = /^(https?:\/\/)/.test(urlFromNode);
|
|
15
|
+
const url = isExternalUrl
|
|
16
|
+
? // full urls including internal and external
|
|
17
|
+
new URL(urlFromNode)
|
|
18
|
+
: // handles relative links
|
|
19
|
+
new URL(`${path.posix.resolve(path.posix.dirname(fullPath), urlFromNode)}`, options.baseUrl);
|
|
20
|
+
if (!isExternalUrl && url.hash !== '') {
|
|
21
|
+
const isValidHeadingLink = headings.findIndex(heading => heading.replace(/\W+/g, '-').toLowerCase() === url.hash.substring(1).toLowerCase()) !== -1;
|
|
22
|
+
if (isValidHeadingLink) {
|
|
23
|
+
// link points to a heading on the page
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (options.skipUrlPatterns &&
|
|
28
|
+
options.skipUrlPatterns.some(skipPattern => new RegExp(skipPattern).test(url.toString()))) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!urlToNodes[url.toString()]) {
|
|
32
|
+
urlToNodes[url.toString()] = [];
|
|
33
|
+
}
|
|
34
|
+
urlToNodes[url.toString()].push(node);
|
|
35
|
+
};
|
|
36
|
+
visit(ast, ['link', 'image', 'definition'], aggregate);
|
|
37
|
+
const links = Object.keys(urlToNodes);
|
|
38
|
+
const checkLinksOptions = options.proxyEndpoint
|
|
39
|
+
? {
|
|
40
|
+
agent: {
|
|
41
|
+
https: new HttpsProxyAgent(options.proxyEndpoint)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
: {};
|
|
45
|
+
const results = await checkLinks(links, checkLinksOptions);
|
|
46
|
+
links.forEach(link => {
|
|
47
|
+
const result = results[link];
|
|
48
|
+
if (result.status !== 'dead' && result.status !== 'invalid') {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const nodes = urlToNodes[link];
|
|
52
|
+
if (!nodes)
|
|
53
|
+
return;
|
|
54
|
+
console.group(`[Mosaic] Broken links found in ${fullPath}`);
|
|
55
|
+
for (const node of nodes) {
|
|
56
|
+
console.log(`Link to ${link} is dead`, node);
|
|
57
|
+
}
|
|
58
|
+
console.groupEnd();
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async function findPageHeadings(ast) {
|
|
62
|
+
const headings = [];
|
|
63
|
+
visit(ast, ['heading'], node => {
|
|
64
|
+
headings.push(node.children[0]?.value);
|
|
65
|
+
});
|
|
66
|
+
return headings;
|
|
67
|
+
}
|
|
68
|
+
const processor = remark().use(remarkMdx);
|
|
69
|
+
const BrokenLinksPlugin = {
|
|
70
|
+
async $afterSource(pages, _, options) {
|
|
71
|
+
pages.forEach(async (page) => {
|
|
72
|
+
const ast = await processor.parse(page.content);
|
|
73
|
+
const headings = await findPageHeadings(ast);
|
|
74
|
+
await checkPageLinks(ast, options, page.fullPath, headings);
|
|
75
|
+
});
|
|
76
|
+
return pages;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
export default BrokenLinksPlugin;
|
|
80
|
+
//# sourceMappingURL=BrokenLinksPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrokenLinksPlugin.js","sourceRoot":"","sources":["../src/BrokenLinksPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Page, Plugin as PluginType } from '@jpmorganchase/mosaic-types';
|
|
2
|
+
interface DocumentAssetsPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* An array of subdirectory globs that could contain assets
|
|
5
|
+
* @default: ['**\/images']
|
|
6
|
+
*/
|
|
7
|
+
assetSubDirs?: string[];
|
|
8
|
+
/**
|
|
9
|
+
* The source path, where your docs reside, when the site runs
|
|
10
|
+
*/
|
|
11
|
+
srcDir?: string;
|
|
12
|
+
/**
|
|
13
|
+
* The directory to copy matched assets to, typically the site's public directory
|
|
14
|
+
* @default './public'
|
|
15
|
+
*/
|
|
16
|
+
outputDir?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The prefix we add to all images in documents, so that it routes to the public directory
|
|
19
|
+
* @default '/images'
|
|
20
|
+
*/
|
|
21
|
+
imagesPrefix?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Plugin that finds assets within the Mosaic filesystem and copies them to the configured `outputDir`.
|
|
25
|
+
* Documents that create relative references to those images, will be re-written to pull the images from the `outputDir`.
|
|
26
|
+
*/
|
|
27
|
+
declare const DocumentAssetsPlugin: PluginType<Page, DocumentAssetsPluginOptions>;
|
|
28
|
+
export default DocumentAssetsPlugin;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import glob from 'fast-glob';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { escapeRegExp } from 'lodash-es';
|
|
5
|
+
import { unified } from 'unified';
|
|
6
|
+
import { visit } from 'unist-util-visit';
|
|
7
|
+
import remarkParse from 'remark-parse';
|
|
8
|
+
import remarkMdx from 'remark-mdx';
|
|
9
|
+
import remarkStringify from 'remark-stringify';
|
|
10
|
+
import PluginError from './utils/PluginError.js';
|
|
11
|
+
function isUrl(assetPath) {
|
|
12
|
+
try {
|
|
13
|
+
new URL(assetPath);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch (_err) { }
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const createPageTest = (ignorePages, pageExtensions) => {
|
|
20
|
+
const extTest = new RegExp(`${pageExtensions.map(ext => escapeRegExp(ext)).join('|')}$`);
|
|
21
|
+
const ignoreTest = new RegExp(`${ignorePages.map(ignore => escapeRegExp(ignore)).join('|')}$`);
|
|
22
|
+
return (file) => !ignoreTest.test(file) && extTest.test(file) && !path.basename(file).startsWith('.');
|
|
23
|
+
};
|
|
24
|
+
function remarkRewriteImagePaths(newPrefix) {
|
|
25
|
+
return (tree) => {
|
|
26
|
+
visit(tree, 'image', (node) => {
|
|
27
|
+
if (node.url) {
|
|
28
|
+
if (isUrl(node.url) || /^\//.test(node.url)) {
|
|
29
|
+
// Absolute URL or path, do nothing
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const isRelativePath = !isUrl(node.url) && !path.posix.isAbsolute(node.url);
|
|
34
|
+
const assetPath = isRelativePath ? node.url : `./${node.url}`;
|
|
35
|
+
const resolvedPath = path.posix.resolve(path.posix.dirname(newPrefix), assetPath);
|
|
36
|
+
node.url = resolvedPath;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Plugin that finds assets within the Mosaic filesystem and copies them to the configured `outputDir`.
|
|
44
|
+
* Documents that create relative references to those images, will be re-written to pull the images from the `outputDir`.
|
|
45
|
+
*/
|
|
46
|
+
const DocumentAssetsPlugin = {
|
|
47
|
+
async afterUpdate(_mutableFileSystem, _helpers, { assetSubDirs = [path.join('**', 'images')], srcDir = path.join(process.cwd(), 'docs'), outputDir = `${path.sep}public` }) {
|
|
48
|
+
const resolvedCwd = path.resolve(process.cwd());
|
|
49
|
+
const resolvedSrcDir = path.resolve(srcDir);
|
|
50
|
+
const resolvedOutputDir = path.resolve(outputDir);
|
|
51
|
+
if (!resolvedOutputDir.startsWith(resolvedCwd)) {
|
|
52
|
+
throw new PluginError('outputDir must be within the current working directory', resolvedOutputDir);
|
|
53
|
+
}
|
|
54
|
+
for (const assetSubDir of assetSubDirs) {
|
|
55
|
+
const resolvedAssetSubDir = path.resolve(resolvedSrcDir, assetSubDir);
|
|
56
|
+
if (!resolvedAssetSubDir.startsWith(resolvedSrcDir)) {
|
|
57
|
+
throw new PluginError('asset subdirectory must be within srcDir', resolvedAssetSubDir);
|
|
58
|
+
}
|
|
59
|
+
let globbedImageDirs;
|
|
60
|
+
try {
|
|
61
|
+
globbedImageDirs = await glob(assetSubDir, {
|
|
62
|
+
cwd: resolvedSrcDir,
|
|
63
|
+
onlyDirectories: true,
|
|
64
|
+
fs
|
|
65
|
+
});
|
|
66
|
+
if (globbedImageDirs.length === 0) {
|
|
67
|
+
console.warn(`Warning: No entries found for ${assetSubDir}. It may not exist.`);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
console.error(`Error globbing ${assetSubDir} in ${srcDir}:`, err);
|
|
73
|
+
throw new PluginError(err.message, assetSubDir);
|
|
74
|
+
}
|
|
75
|
+
await fs.promises.mkdir(outputDir, { recursive: true });
|
|
76
|
+
for (const globbedImageDir of globbedImageDirs) {
|
|
77
|
+
let imageFiles;
|
|
78
|
+
let globbedPath;
|
|
79
|
+
let rootSrcDir = srcDir;
|
|
80
|
+
let rootOutputDir = outputDir;
|
|
81
|
+
try {
|
|
82
|
+
if (!path.isAbsolute(rootSrcDir)) {
|
|
83
|
+
rootSrcDir = path.resolve(path.join(process.cwd(), srcDir));
|
|
84
|
+
}
|
|
85
|
+
globbedPath = path.join(rootSrcDir, globbedImageDir);
|
|
86
|
+
imageFiles = await fs.promises.readdir(globbedPath);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
console.error(`Error reading directory ${globbedPath}:`, err);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (!path.isAbsolute(rootOutputDir)) {
|
|
93
|
+
rootOutputDir = path.resolve(path.join(process.cwd(), outputDir));
|
|
94
|
+
}
|
|
95
|
+
for (const imageFile of imageFiles) {
|
|
96
|
+
try {
|
|
97
|
+
const imageSrcPath = path.join(globbedImageDir, imageFile);
|
|
98
|
+
const fullImageSrcPath = path.join(rootSrcDir, imageSrcPath);
|
|
99
|
+
const fullImageDestPath = path.join(rootOutputDir, imageSrcPath);
|
|
100
|
+
await fs.promises.mkdir(path.dirname(fullImageDestPath), { recursive: true });
|
|
101
|
+
const symlinkAlreadyExists = await fs.promises
|
|
102
|
+
.access(fullImageDestPath)
|
|
103
|
+
.then(() => true)
|
|
104
|
+
.catch(() => false);
|
|
105
|
+
if (!symlinkAlreadyExists) {
|
|
106
|
+
await fs.promises.symlink(fullImageSrcPath, fullImageDestPath);
|
|
107
|
+
console.log(`Symlink created: ${fullImageSrcPath} -> ${fullImageDestPath}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.error(`Error processing ${imageFile}:`, error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
async $afterSource(pages, { ignorePages, pageExtensions }, { imagesPrefix = `/images` }) {
|
|
118
|
+
if (!pageExtensions.includes('.mdx')) {
|
|
119
|
+
return pages;
|
|
120
|
+
}
|
|
121
|
+
for (const page of pages) {
|
|
122
|
+
const isNonHiddenPage = createPageTest(ignorePages, ['.mdx']);
|
|
123
|
+
if (!isNonHiddenPage(page.fullPath)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const processor = unified()
|
|
127
|
+
.use(remarkParse)
|
|
128
|
+
.use(remarkMdx)
|
|
129
|
+
.use(remarkRewriteImagePaths, path.posix.join(imagesPrefix, page.route))
|
|
130
|
+
.use(remarkStringify);
|
|
131
|
+
await processor
|
|
132
|
+
.process(page.content)
|
|
133
|
+
.then((file) => {
|
|
134
|
+
page.content = String(file);
|
|
135
|
+
})
|
|
136
|
+
.catch((err) => {
|
|
137
|
+
console.error('Error processing Markdown:', err);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return pages;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
export default DocumentAssetsPlugin;
|
|
144
|
+
//# sourceMappingURL=DocumentAssetsPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentAssetsPlugin.js","sourceRoot":"","sources":["../src/DocumentAssetsPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { remark } from 'remark';
|
|
3
|
+
import remarkMdx from 'remark-mdx';
|
|
4
|
+
import remarkDirective from 'remark-directive';
|
|
5
|
+
import { visit } from 'unist-util-visit';
|
|
6
|
+
import PluginError from './utils/PluginError.js';
|
|
7
|
+
import { createPageTest } from './utils/createPageTest.js';
|
|
8
|
+
function isDirective(node) {
|
|
9
|
+
return (node.type === 'containerDirective' ||
|
|
10
|
+
node.type === 'leafDirective' ||
|
|
11
|
+
node.type === 'textDirective');
|
|
12
|
+
}
|
|
13
|
+
function processFragments(tree, pages, isNonHiddenPage, fullPath) {
|
|
14
|
+
visit(tree, (node, index, parent) => {
|
|
15
|
+
if (isDirective(node)) {
|
|
16
|
+
if (node.name !== 'fragment')
|
|
17
|
+
return;
|
|
18
|
+
const attributes = node.attributes ?? {};
|
|
19
|
+
const { src } = attributes;
|
|
20
|
+
if (!src) {
|
|
21
|
+
console.error("Fragment directive requires a 'src' attribute. Skipping.");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const fragmentFullPath = path.posix.join(path.dirname(fullPath), src);
|
|
25
|
+
const isHidden = !isNonHiddenPage(fragmentFullPath);
|
|
26
|
+
const fragmentPage = pages.find(page => page.fullPath === fragmentFullPath);
|
|
27
|
+
if (isHidden || !fragmentPage) {
|
|
28
|
+
console.warn(`Invalid file reference: '${node.attributes.src}'. Skipping.`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Create a new node with the content from fragmentPage.content
|
|
32
|
+
const newNode = {
|
|
33
|
+
type: 'html',
|
|
34
|
+
value: fragmentPage.content
|
|
35
|
+
};
|
|
36
|
+
// Replace the original node with the newNode in the tree
|
|
37
|
+
parent.children.splice(index, 1, newNode);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const processor = remark().use(remarkMdx).use(remarkDirective);
|
|
43
|
+
const FragmentPlugin = {
|
|
44
|
+
async $afterSource(pages, { ignorePages, pageExtensions }) {
|
|
45
|
+
const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
|
|
46
|
+
for (const page of pages) {
|
|
47
|
+
try {
|
|
48
|
+
const { fullPath } = page;
|
|
49
|
+
if (!isNonHiddenPage(fullPath)) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const tree = processor.parse(page.content);
|
|
53
|
+
processFragments(tree, pages, isNonHiddenPage, page.fullPath);
|
|
54
|
+
page.content = processor.stringify(tree);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
throw new PluginError(e.message, page.fullPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return pages;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
export default FragmentPlugin;
|
|
64
|
+
//# sourceMappingURL=FragmentPlugin.js.map
|