@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.
Files changed (78) hide show
  1. package/dist/$AliasPlugin.d.ts +10 -0
  2. package/dist/$AliasPlugin.js +34 -46
  3. package/dist/$AliasPlugin.js.map +1 -1
  4. package/dist/$CodeModPlugin.d.ts +7 -0
  5. package/dist/$CodeModPlugin.js +12 -28
  6. package/dist/$CodeModPlugin.js.map +1 -1
  7. package/dist/$RefPlugin.d.ts +31 -0
  8. package/dist/$RefPlugin.js +109 -108
  9. package/dist/$RefPlugin.js.map +1 -1
  10. package/dist/$TagPlugin.d.ts +28 -0
  11. package/dist/$TagPlugin.js +24 -44
  12. package/dist/$TagPlugin.js.map +1 -1
  13. package/dist/BreadcrumbsPlugin.d.ts +19 -0
  14. package/dist/BreadcrumbsPlugin.js +78 -34
  15. package/dist/BreadcrumbsPlugin.js.map +1 -1
  16. package/dist/BrokenLinksPlugin.d.ts +10 -0
  17. package/dist/BrokenLinksPlugin.js +80 -0
  18. package/dist/BrokenLinksPlugin.js.map +1 -0
  19. package/dist/FragmentPlugin.d.ts +3 -0
  20. package/dist/FragmentPlugin.js +61 -0
  21. package/dist/FragmentPlugin.js.map +1 -0
  22. package/dist/LazyPagePlugin.d.ts +14 -0
  23. package/dist/LazyPagePlugin.js +46 -79
  24. package/dist/LazyPagePlugin.js.map +1 -1
  25. package/dist/PagesWithoutFileExtPlugin.d.ts +9 -0
  26. package/dist/PagesWithoutFileExtPlugin.js +14 -29
  27. package/dist/PagesWithoutFileExtPlugin.js.map +1 -1
  28. package/dist/PropsTablePlugin.d.ts +6 -0
  29. package/dist/PropsTablePlugin.js +88 -0
  30. package/dist/PropsTablePlugin.js.map +1 -0
  31. package/dist/PublicAssetsPlugin.d.ts +18 -0
  32. package/dist/PublicAssetsPlugin.js +28 -0
  33. package/dist/PublicAssetsPlugin.js.map +1 -0
  34. package/dist/ReadingTimePlugin.d.ts +10 -0
  35. package/dist/ReadingTimePlugin.js +39 -0
  36. package/dist/ReadingTimePlugin.js.map +1 -0
  37. package/dist/SearchIndexPlugin.d.ts +56 -0
  38. package/dist/SearchIndexPlugin.js +154 -0
  39. package/dist/SearchIndexPlugin.js.map +1 -0
  40. package/dist/SharedConfigPlugin.d.ts +14 -0
  41. package/dist/SharedConfigPlugin.js +124 -32
  42. package/dist/SharedConfigPlugin.js.map +1 -1
  43. package/dist/SidebarPlugin.d.ts +44 -0
  44. package/dist/SidebarPlugin.js +235 -88
  45. package/dist/SidebarPlugin.js.map +1 -1
  46. package/dist/SiteMapPlugin.d.ts +9 -0
  47. package/dist/SiteMapPlugin.js +20 -34
  48. package/dist/SiteMapPlugin.js.map +1 -1
  49. package/dist/TableOfContentsPlugin.d.ts +20 -0
  50. package/dist/TableOfContentsPlugin.js +44 -0
  51. package/dist/TableOfContentsPlugin.js.map +1 -0
  52. package/dist/utils/PluginError.d.ts +7 -0
  53. package/dist/utils/PluginError.js +13 -0
  54. package/dist/utils/PluginError.js.map +1 -0
  55. package/dist/utils/createPageTest.d.ts +1 -0
  56. package/dist/utils/createPageTest.js +8 -0
  57. package/dist/utils/createPageTest.js.map +1 -0
  58. package/dist/utils/mergePageContent.d.ts +16 -0
  59. package/dist/utils/mergePageContent.js +23 -0
  60. package/dist/utils/mergePageContent.js.map +1 -0
  61. package/dist/utils/normaliseRefs.d.ts +1 -0
  62. package/dist/utils/normaliseRefs.js +52 -69
  63. package/dist/utils/normaliseRefs.js.map +1 -1
  64. package/dist/utils/sortSidebarData.d.ts +19 -0
  65. package/dist/utils/sortSidebarData.js +35 -0
  66. package/dist/utils/sortSidebarData.js.map +1 -0
  67. package/package.json +42 -19
  68. package/CHANGELOG.md +0 -79
  69. package/dist/LocalFolderSavePlugin.js +0 -48
  70. package/dist/LocalFolderSavePlugin.js.map +0 -1
  71. package/dist/NextPrevPagePlugin.js +0 -63
  72. package/dist/NextPrevPagePlugin.js.map +0 -1
  73. package/dist/ReadingTimePlugin.mjs +0 -119
  74. package/dist/ReadingTimePlugin.mjs.map +0 -1
  75. package/dist/SearchIndexPlugin.mjs +0 -268
  76. package/dist/SearchIndexPlugin.mjs.map +0 -1
  77. package/dist/TableOfContentsPlugin.mjs +0 -131
  78. package/dist/TableOfContentsPlugin.mjs.map +0 -1
@@ -1,26 +1,8 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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"));
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
- var _a;
45
- return __awaiter(this, void 0, void 0, function* () {
46
- if (!((_a = config.data) === null || _a === void 0 ? void 0 : _a.subscribedTags) ||
47
- !(yield updatedSourceFilesystem.promises.exists('/.tags'))) {
48
- return false;
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
- var _a;
57
- return __awaiter(this, void 0, void 0, function* () {
58
- const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
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 ((_a = meta.tags) === null || _a === void 0 ? void 0 : _a.length) {
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, `${path_1.default.join('/.tags', tag, '**')}#${fragment}`);
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
- return pages;
82
- });
58
+ catch (e) {
59
+ throw new PluginError(e.message, page.fullPath);
60
+ }
61
+ }
62
+ return pages;
83
63
  }
84
64
  };
85
- exports.default = $TagPlugin;
65
+ export default $TagPlugin;
86
66
  //# sourceMappingURL=$TagPlugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"$TagPlugin.js","sourceRoot":"","sources":["../src/$TagPlugin.ts"],"names":[],"mappings":"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"}
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 declare 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
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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, _, options) {
21
- return __awaiter(this, void 0, void 0, function* () {
22
- for (const page of pages) {
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 {
23
15
  const breadcrumbs = [];
24
16
  let currentPage = page;
25
- let parentDir = path_1.default.posix.normalize(path_1.default.posix.dirname(currentPage.fullPath));
26
- while (currentPage !== undefined) {
27
- // eslint-disable-next-line @typescript-eslint/no-loop-func
28
- if (breadcrumbs.findIndex(breadcrumb => breadcrumb.id === currentPage.fullPath) === -1) {
29
- breadcrumbs.unshift({
30
- label: currentPage.title,
31
- path: currentPage.route,
32
- id: currentPage.fullPath
33
- });
34
- }
17
+ let parentDir = path.posix.normalize(path.posix.dirname(currentPage.fullPath));
18
+ const maxBreadcrumbCount = page.fullPath.split('/').length;
19
+ while (currentPage !== undefined && breadcrumbs.length < maxBreadcrumbCount) {
20
+ breadcrumbs.unshift({
21
+ label: currentPage.sidebar?.label || currentPage.title,
22
+ path: currentPage.route,
23
+ id: currentPage.fullPath
24
+ });
35
25
  currentPage = pages.find(
36
26
  // eslint-disable-next-line @typescript-eslint/no-loop-func
37
- item => item.fullPath === path_1.default.posix.join(parentDir, options.indexPageName));
27
+ item => item.fullPath === path.posix.join(parentDir, options.indexPageName));
38
28
  if (currentPage) {
39
- parentDir = path_1.default.posix.dirname(path_1.default.posix.join(String(currentPage.fullPath), '..'));
29
+ parentDir = path.posix.dirname(path.posix.join(String(currentPage.fullPath), '..'));
40
30
  }
41
31
  }
42
32
  if (!page.breadcrumbs) {
43
- page.breadcrumbs = breadcrumbs;
33
+ // filter out any duplicate breadcrumbs
34
+ const map = new Map(breadcrumbs.map(crumb => [crumb.id, crumb]));
35
+ page.breadcrumbs = [...map.values()];
36
+ }
37
+ }
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
+ }
44
74
  }
45
75
  }
46
- return pages;
47
- });
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
- exports.default = BreadcrumbsPlugin;
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":";;;;;;;;;;;;;;AAAA,gDAAwB;AAaxB;;GAEG;AACH,MAAM,iBAAiB,GAAgE;IAC/E,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO;;YAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACxB,MAAM,WAAW,GAAsB,EAAE,CAAC;gBAC1C,IAAI,WAAW,GAAG,IAAI,CAAC;gBACvB,IAAI,SAAS,GAAG,cAAI,CAAC,KAAK,CAAC,SAAS,CAAC,cAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAE/E,OAAO,WAAW,KAAK,SAAS,EAAE;oBAChC,2DAA2D;oBAC3D,IAAI,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;wBACtF,WAAW,CAAC,OAAO,CAAC;4BAClB,KAAK,EAAE,WAAW,CAAC,KAAK;4BACxB,IAAI,EAAE,WAAW,CAAC,KAAK;4BACvB,EAAE,EAAE,WAAW,CAAC,QAAQ;yBACzB,CAAC,CAAC;qBACJ;oBAED,WAAW,GAAG,KAAK,CAAC,IAAI;oBACtB,2DAA2D;oBAC3D,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,cAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,CAC5E,CAAC;oBACF,IAAI,WAAW,EAAE;wBACf,SAAS,GAAG,cAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;qBACrF;iBACF;gBAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;iBAChC;aACF;YAED,OAAO,KAAK,CAAC;QACf,CAAC;KAAA;CACF,CAAC;AAEF,kBAAe,iBAAiB,CAAC"}
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,3 @@
1
+ import type { Plugin as PluginType } from '@jpmorganchase/mosaic-types';
2
+ declare const FragmentPlugin: PluginType;
3
+ export default FragmentPlugin;
@@ -0,0 +1,61 @@
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 processFragments(tree, pages, isNonHiddenPage, fullPath) {
9
+ visit(tree, (node, index, parent) => {
10
+ if (node.type === 'containerDirective' ||
11
+ node.type === 'leafDirective' ||
12
+ node.type === 'textDirective') {
13
+ if (node.name !== 'fragment')
14
+ return;
15
+ const attributes = node.attributes ?? {};
16
+ const { src } = attributes;
17
+ if (!src) {
18
+ console.error("Fragment directive requires a 'src' attribute. Skipping.");
19
+ return;
20
+ }
21
+ const fragmentFullPath = path.posix.join(path.dirname(fullPath), src);
22
+ const isHidden = !isNonHiddenPage(fragmentFullPath);
23
+ const fragmentPage = pages.find(page => page.fullPath === fragmentFullPath);
24
+ if (isHidden || !fragmentPage) {
25
+ console.warn(`Invalid file reference: '${node.attributes.src}'. Skipping.`);
26
+ }
27
+ else {
28
+ // Create a new node with the content from fragmentPage.content
29
+ const newNode = {
30
+ type: 'html',
31
+ value: fragmentPage.content
32
+ };
33
+ // Replace the original node with the newNode in the tree
34
+ parent.children.splice(index, 1, newNode);
35
+ }
36
+ }
37
+ });
38
+ }
39
+ const processor = remark().use(remarkMdx).use(remarkDirective);
40
+ const FragmentPlugin = {
41
+ async $afterSource(pages, { ignorePages, pageExtensions }) {
42
+ const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
43
+ for (const page of pages) {
44
+ try {
45
+ const { fullPath } = page;
46
+ if (!isNonHiddenPage(fullPath)) {
47
+ continue;
48
+ }
49
+ const tree = processor.parse(page.content);
50
+ processFragments(tree, pages, isNonHiddenPage, page.fullPath);
51
+ page.content = processor.stringify(tree);
52
+ }
53
+ catch (e) {
54
+ throw new PluginError(e.message, page.fullPath);
55
+ }
56
+ }
57
+ return pages;
58
+ }
59
+ };
60
+ export default FragmentPlugin;
61
+ //# sourceMappingURL=FragmentPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FragmentPlugin.js","sourceRoot":"","sources":["../src/FragmentPlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Page, Plugin as PluginType } from '@jpmorganchase/mosaic-types';
2
+ interface LazyPagePluginPage extends Page {
3
+ aliases: {
4
+ [key: string]: Set<string>;
5
+ };
6
+ hddPaths: {
7
+ [key: string]: string;
8
+ };
9
+ }
10
+ interface LazyPagePluginOptions {
11
+ cacheDir?: string;
12
+ }
13
+ declare const LazyPagePlugin: PluginType<LazyPagePluginPage, LazyPagePluginOptions>;
14
+ export default LazyPagePlugin;
@@ -1,38 +1,8 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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 __rest = (this && this.__rest) || function (s, e) {
12
- var t = {};
13
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
- t[p] = s[p];
15
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
- t[p[i]] = s[p[i]];
19
- }
20
- return t;
21
- };
22
- var __importDefault = (this && this.__importDefault) || function (mod) {
23
- return (mod && mod.__esModule) ? mod : { "default": mod };
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- const fs_1 = __importDefault(require("fs"));
27
- const fs_extra_1 = __importDefault(require("fs-extra"));
28
- const merge_1 = __importDefault(require("lodash/merge"));
29
- const escapeRegExp_1 = __importDefault(require("lodash/escapeRegExp"));
30
- const path_1 = __importDefault(require("path"));
31
- function createPageTest(ignorePages, pageExtensions) {
32
- const extTest = new RegExp(`${pageExtensions.map(escapeRegExp_1.default).join('|')}$`);
33
- const ignoreTest = new RegExp(`${ignorePages.map(escapeRegExp_1.default).join('|')}$`);
34
- return file => !ignoreTest.test(file) && extTest.test(file) && !path_1.default.basename(file).startsWith('.');
35
- }
1
+ import fs from 'fs';
2
+ import fsExtra from 'fs-extra';
3
+ import path from 'path';
4
+ import { mergePageContent } from './utils/mergePageContent.js';
5
+ import { createPageTest } from './utils/createPageTest.js';
36
6
  function createFileGlob(url, pageExtensions) {
37
7
  if (pageExtensions.length === 1) {
38
8
  return `${url}${pageExtensions[0]}`;
@@ -40,54 +10,51 @@ function createFileGlob(url, pageExtensions) {
40
10
  return `${url}{${pageExtensions.join(',')}}`;
41
11
  }
42
12
  const LazyPagePlugin = {
43
- afterUpdate(mutableFilesystem, { ignorePages, config, pageExtensions, serialiser }) {
44
- return __awaiter(this, void 0, void 0, function* () {
45
- const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
46
- // This adds a hook that triggers everytime a non-cached page is read from the filesystem.
47
- mutableFilesystem.__internal_do_not_use_addReadFileHook((pagePath, fileData) => __awaiter(this, void 0, void 0, function* () {
48
- // If this is a 'page' - read the original file from disk and try to inject anything that's missing.
49
- if (isNonHiddenPage(pagePath)) {
50
- const currentPage = yield serialiser.deserialise(pagePath, fileData);
51
- if (config.data.hddPaths[pagePath]) {
52
- const page = yield serialiser.deserialise(pagePath, yield fs_1.default.promises.readFile(config.data.hddPaths[pagePath]));
53
- const completePage = yield serialiser.serialise(pagePath, (0, merge_1.default)(page, currentPage, { content: page.content }));
54
- return completePage;
55
- }
13
+ async afterUpdate(mutableFilesystem, { ignorePages, config, pageExtensions, serialiser }) {
14
+ const isNonHiddenPage = createPageTest(ignorePages, pageExtensions);
15
+ // This adds a hook that triggers every time a non-cached page is read from the filesystem.
16
+ mutableFilesystem.__internal_do_not_use_addReadFileHook(async (pagePath, fileData) => {
17
+ // If this is a 'page' - read the original file from disk and try to inject anything that's missing.
18
+ if (isNonHiddenPage(pagePath)) {
19
+ const currentPage = await serialiser.deserialise(pagePath, fileData);
20
+ if (config.data.hddPaths?.[pagePath]) {
21
+ const page = await serialiser.deserialise(pagePath, await fs.promises.readFile(config.data.hddPaths[pagePath]));
22
+ const mergedPage = mergePageContent(page, currentPage);
23
+ const completePage = await serialiser.serialise(pagePath, mergePageContent(mergedPage, { content: page.content }));
24
+ return completePage;
56
25
  }
57
- return fileData;
58
- }));
26
+ }
27
+ return fileData;
59
28
  });
60
29
  },
61
- $beforeSend(mutableFilesystem, { config, serialiser, ignorePages, pageExtensions }, options) {
62
- return __awaiter(this, void 0, void 0, function* () {
63
- const hddPaths = {};
64
- let originalDiskSize = 0;
65
- let newDiskSize = 0;
66
- const allPages = yield mutableFilesystem.promises.glob(createFileGlob('**', pageExtensions), {
67
- ignore: ignorePages.map(ignore => `**/${ignore}`),
68
- cwd: '/',
69
- onlyFiles: true
70
- });
71
- const baseDir = path_1.default.join(process.cwd(), options.cacheDir || '.mosaic-lazy-page-plugin-cache');
72
- yield fs_extra_1.default.ensureDir(baseDir);
73
- for (const filePath of allPages) {
74
- const rawPage = yield mutableFilesystem.promises.readFile(String(filePath));
75
- const page = yield serialiser.deserialise(String(filePath), rawPage);
76
- originalDiskSize += rawPage.length;
77
- yield fs_1.default.promises.mkdir(path_1.default.dirname(path_1.default.join(baseDir, String(filePath))), {
78
- recursive: true
79
- });
80
- yield fs_1.default.promises.writeFile(path_1.default.join(baseDir, String(filePath)), yield serialiser.serialise(String(filePath), page));
81
- const { content } = page, pageRest = __rest(page, ["content"]);
82
- hddPaths[String(filePath)] = path_1.default.join(baseDir, String(filePath));
83
- const redactedPage = yield serialiser.serialise(String(filePath), pageRest);
84
- newDiskSize += redactedPage.length;
85
- }
86
- config.setData({ hddPaths });
87
- const reduction = originalDiskSize - newDiskSize;
88
- console.info(`[Mosaic] LazyPagePlugin moved ${((reduction / originalDiskSize) * 100).toFixed(2)}% of virtual filesystem content to the hard disk. This reduced the virtual filesystem size from ${(originalDiskSize / 1000000).toFixed(2)}mb to ${(newDiskSize / 1000000).toFixed(2)}mb (yay!)`);
30
+ async $beforeSend(mutableFilesystem, { config, serialiser, ignorePages, pageExtensions }, options) {
31
+ const hddPaths = {};
32
+ let originalDiskSize = 0;
33
+ let newDiskSize = 0;
34
+ const allPages = await mutableFilesystem.promises.glob(createFileGlob('**', pageExtensions), {
35
+ ignore: ignorePages.map(ignore => `**/${ignore}`),
36
+ cwd: '/',
37
+ onlyFiles: true
89
38
  });
39
+ const baseDir = path.join(process.cwd(), options.cacheDir || '.mosaic-lazy-page-plugin-cache');
40
+ await fsExtra.ensureDir(baseDir);
41
+ for (const filePath of allPages) {
42
+ const rawPage = await mutableFilesystem.promises.readFile(String(filePath));
43
+ const page = await serialiser.deserialise(String(filePath), rawPage);
44
+ originalDiskSize += rawPage.length;
45
+ await fs.promises.mkdir(path.dirname(path.join(baseDir, String(filePath))), {
46
+ recursive: true
47
+ });
48
+ await fs.promises.writeFile(path.join(baseDir, String(filePath)), await serialiser.serialise(String(filePath), page));
49
+ const { content, ...pageRest } = page;
50
+ hddPaths[String(filePath)] = path.join(baseDir, String(filePath));
51
+ const redactedPage = await serialiser.serialise(String(filePath), pageRest);
52
+ newDiskSize += redactedPage.length;
53
+ }
54
+ config.setData({ hddPaths });
55
+ const reduction = originalDiskSize - newDiskSize;
56
+ console.info(`[Mosaic] LazyPagePlugin moved ${((reduction / originalDiskSize) * 100).toFixed(2)}% of virtual filesystem content to the hard disk. This reduced the virtual filesystem size from ${(originalDiskSize / 1000000).toFixed(2)}mb to ${(newDiskSize / 1000000).toFixed(2)}mb (yay!)`);
90
57
  }
91
58
  };
92
- exports.default = LazyPagePlugin;
59
+ export default LazyPagePlugin;
93
60
  //# sourceMappingURL=LazyPagePlugin.js.map