@mintlify/scraping 3.0.186 → 3.0.188
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/bin/assert.d.ts +5 -0
- package/bin/assert.js +13 -0
- package/bin/assert.js.map +1 -0
- package/bin/cli.js +43 -72
- package/bin/cli.js.map +1 -1
- package/bin/components/Accordion.d.ts +5 -0
- package/bin/components/Accordion.js +54 -0
- package/bin/components/Accordion.js.map +1 -0
- package/bin/components/AccordionGroup.d.ts +5 -0
- package/bin/components/AccordionGroup.js +52 -0
- package/bin/components/AccordionGroup.js.map +1 -0
- package/bin/components/Callout.d.ts +5 -0
- package/bin/components/Callout.js +114 -0
- package/bin/components/Callout.js.map +1 -0
- package/bin/components/Card.d.ts +5 -0
- package/bin/components/Card.js +135 -0
- package/bin/components/Card.js.map +1 -0
- package/bin/components/CardGroup.d.ts +5 -0
- package/bin/components/CardGroup.js +52 -0
- package/bin/components/CardGroup.js.map +1 -0
- package/bin/components/CodeGroup.d.ts +5 -0
- package/bin/components/CodeGroup.js +166 -0
- package/bin/components/CodeGroup.js.map +1 -0
- package/bin/components/Frame.d.ts +5 -0
- package/bin/components/Frame.js +51 -0
- package/bin/components/Frame.js.map +1 -0
- package/bin/components/Tabs.d.ts +5 -0
- package/bin/components/Tabs.js +122 -0
- package/bin/components/Tabs.js.map +1 -0
- package/bin/components/link.d.ts +2 -0
- package/bin/components/link.js +16 -0
- package/bin/components/link.js.map +1 -0
- package/bin/constants.d.ts +6 -7
- package/bin/constants.js +31 -12
- package/bin/constants.js.map +1 -1
- package/bin/customComponents/create.d.ts +10 -0
- package/bin/customComponents/create.js +69 -0
- package/bin/customComponents/create.js.map +1 -0
- package/bin/customComponents/plugin.d.ts +2 -0
- package/bin/customComponents/plugin.js +26 -0
- package/bin/customComponents/plugin.js.map +1 -0
- package/bin/customComponents/selective.d.ts +6 -0
- package/bin/customComponents/selective.js +29 -0
- package/bin/customComponents/selective.js.map +1 -0
- package/bin/nav/iterate.d.ts +2 -0
- package/bin/nav/iterate.js +15 -0
- package/bin/nav/iterate.js.map +1 -0
- package/bin/nav/listItems.d.ts +8 -0
- package/bin/nav/listItems.js +62 -0
- package/bin/nav/listItems.js.map +1 -0
- package/bin/nav/retrieve.d.ts +3 -0
- package/bin/nav/retrieve.js +75 -0
- package/bin/nav/retrieve.js.map +1 -0
- package/bin/nav/root.d.ts +2 -0
- package/bin/nav/root.js +40 -0
- package/bin/nav/root.js.map +1 -0
- package/bin/openapi/generateOpenApiPages.js +18 -5
- package/bin/openapi/generateOpenApiPages.js.map +1 -1
- package/bin/root/retrieve.d.ts +2 -0
- package/bin/root/retrieve.js +46 -0
- package/bin/root/retrieve.js.map +1 -0
- package/bin/scrapingPipeline/group.d.ts +5 -0
- package/bin/scrapingPipeline/group.js +46 -0
- package/bin/scrapingPipeline/group.js.map +1 -0
- package/bin/scrapingPipeline/icon.d.ts +2 -0
- package/bin/scrapingPipeline/icon.js +22 -0
- package/bin/scrapingPipeline/icon.js.map +1 -0
- package/bin/scrapingPipeline/images.d.ts +3 -0
- package/bin/scrapingPipeline/images.js +50 -0
- package/bin/scrapingPipeline/images.js.map +1 -0
- package/bin/scrapingPipeline/logo.d.ts +5 -0
- package/bin/scrapingPipeline/logo.js +92 -0
- package/bin/scrapingPipeline/logo.js.map +1 -0
- package/bin/scrapingPipeline/page.d.ts +6 -0
- package/bin/scrapingPipeline/page.js +102 -0
- package/bin/scrapingPipeline/page.js.map +1 -0
- package/bin/scrapingPipeline/root.d.ts +2 -0
- package/bin/scrapingPipeline/root.js +8 -0
- package/bin/scrapingPipeline/root.js.map +1 -0
- package/bin/scrapingPipeline/site.d.ts +7 -0
- package/bin/scrapingPipeline/site.js +129 -0
- package/bin/scrapingPipeline/site.js.map +1 -0
- package/bin/scrapingPipeline/tabs.d.ts +3 -0
- package/bin/scrapingPipeline/tabs.js +67 -0
- package/bin/scrapingPipeline/tabs.js.map +1 -0
- package/bin/tabs/retrieveReadme.d.ts +3 -0
- package/bin/tabs/retrieveReadme.js +78 -0
- package/bin/tabs/retrieveReadme.js.map +1 -0
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/bin/types/components.d.ts +2 -0
- package/bin/types/components.js +2 -0
- package/bin/types/components.js.map +1 -0
- package/bin/types/framework.d.ts +8 -0
- package/bin/types/framework.js +3 -0
- package/bin/types/framework.js.map +1 -0
- package/bin/types/hast.d.ts +6 -0
- package/bin/types/hast.js +2 -0
- package/bin/types/hast.js.map +1 -0
- package/bin/types/result.d.ts +7 -0
- package/bin/types/result.js +2 -0
- package/bin/types/result.js.map +1 -0
- package/bin/types/scrapeFunc.d.ts +3 -0
- package/bin/types/scrapeFunc.js +2 -0
- package/bin/types/scrapeFunc.js.map +1 -0
- package/bin/utils/append.d.ts +1 -0
- package/bin/utils/append.js +12 -0
- package/bin/utils/append.js.map +1 -0
- package/bin/utils/children.d.ts +5 -0
- package/bin/utils/children.js +35 -0
- package/bin/utils/children.js.map +1 -0
- package/bin/utils/className.d.ts +3 -0
- package/bin/utils/className.js +13 -0
- package/bin/utils/className.js.map +1 -0
- package/bin/utils/detectFramework.d.ts +4 -0
- package/bin/utils/detectFramework.js +60 -0
- package/bin/utils/detectFramework.js.map +1 -0
- package/bin/utils/emptyParagraphs.d.ts +3 -0
- package/bin/utils/emptyParagraphs.js +19 -0
- package/bin/utils/emptyParagraphs.js.map +1 -0
- package/bin/utils/errors.d.ts +3 -0
- package/bin/utils/errors.js +16 -0
- package/bin/utils/errors.js.map +1 -0
- package/bin/utils/escape.d.ts +2 -0
- package/bin/utils/escape.js +25 -0
- package/bin/utils/escape.js.map +1 -0
- package/bin/utils/extension.d.ts +3 -0
- package/bin/utils/extension.js +18 -0
- package/bin/utils/extension.js.map +1 -0
- package/bin/utils/file.d.ts +4 -0
- package/bin/utils/file.js +43 -0
- package/bin/utils/file.js.map +1 -0
- package/bin/utils/firstChild.d.ts +2 -0
- package/bin/utils/firstChild.js +12 -0
- package/bin/utils/firstChild.js.map +1 -0
- package/bin/utils/images.d.ts +5 -0
- package/bin/utils/images.js +86 -0
- package/bin/utils/images.js.map +1 -0
- package/bin/utils/img.d.ts +2 -0
- package/bin/utils/img.js +15 -0
- package/bin/utils/img.js.map +1 -0
- package/bin/utils/log.d.ts +18 -0
- package/bin/utils/log.js +68 -0
- package/bin/utils/log.js.map +1 -0
- package/bin/utils/nestedRoots.d.ts +7 -0
- package/bin/utils/nestedRoots.js +19 -0
- package/bin/utils/nestedRoots.js.map +1 -0
- package/bin/utils/network.d.ts +5 -0
- package/bin/utils/network.js +82 -0
- package/bin/utils/network.js.map +1 -0
- package/bin/utils/path.d.ts +1 -0
- package/bin/utils/path.js +22 -0
- package/bin/utils/path.js.map +1 -0
- package/bin/utils/position.d.ts +3 -0
- package/bin/utils/position.js +12 -0
- package/bin/utils/position.js.map +1 -0
- package/bin/utils/reservedNames.d.ts +4 -0
- package/bin/utils/reservedNames.js +27 -0
- package/bin/utils/reservedNames.js.map +1 -0
- package/bin/utils/strings.d.ts +2 -0
- package/bin/utils/strings.js +7 -0
- package/bin/utils/strings.js.map +1 -0
- package/bin/utils/text.d.ts +2 -0
- package/bin/utils/text.js +11 -0
- package/bin/utils/text.js.map +1 -0
- package/bin/utils/title.d.ts +10 -0
- package/bin/utils/title.js +58 -0
- package/bin/utils/title.js.map +1 -0
- package/bin/utils/url.d.ts +3 -0
- package/bin/utils/url.js +10 -0
- package/bin/utils/url.js.map +1 -0
- package/package.json +18 -9
- package/src/assert.ts +15 -0
- package/src/cli.ts +53 -90
- package/src/components/Accordion.ts +84 -0
- package/src/components/AccordionGroup.ts +69 -0
- package/src/components/Callout.ts +159 -0
- package/src/components/Card.ts +168 -0
- package/src/components/CardGroup.ts +69 -0
- package/src/components/CodeGroup.ts +209 -0
- package/src/components/Frame.ts +86 -0
- package/src/components/Tabs.ts +154 -0
- package/src/components/link.ts +17 -0
- package/src/constants.ts +37 -19
- package/src/customComponents/create.ts +106 -0
- package/src/customComponents/plugin.ts +31 -0
- package/src/customComponents/selective.ts +37 -0
- package/src/nav/iterate.ts +18 -0
- package/src/nav/listItems.ts +82 -0
- package/src/nav/retrieve.ts +88 -0
- package/src/nav/root.ts +47 -0
- package/src/openapi/generateOpenApiPages.ts +19 -4
- package/src/root/retrieve.ts +52 -0
- package/src/scrapingPipeline/group.ts +62 -0
- package/src/scrapingPipeline/icon.ts +26 -0
- package/src/scrapingPipeline/images.ts +67 -0
- package/src/scrapingPipeline/logo.ts +127 -0
- package/src/scrapingPipeline/page.ts +130 -0
- package/src/scrapingPipeline/root.ts +10 -0
- package/src/scrapingPipeline/site.ts +161 -0
- package/src/scrapingPipeline/tabs.ts +87 -0
- package/src/tabs/retrieveReadme.ts +99 -0
- package/src/types/components.ts +3 -0
- package/src/types/framework.ts +10 -0
- package/src/types/hast.ts +12 -0
- package/src/types/result.ts +1 -0
- package/src/types/scrapeFunc.ts +9 -0
- package/src/utils/append.ts +9 -0
- package/src/utils/children.ts +51 -0
- package/src/utils/className.ts +14 -0
- package/src/utils/detectFramework.ts +72 -0
- package/src/utils/emptyParagraphs.ts +21 -0
- package/src/utils/errors.ts +24 -0
- package/src/utils/escape.ts +30 -0
- package/src/utils/extension.ts +19 -0
- package/src/utils/file.ts +58 -0
- package/src/utils/firstChild.ts +13 -0
- package/src/utils/images.ts +101 -0
- package/src/utils/img.ts +17 -0
- package/src/utils/log.ts +82 -0
- package/src/utils/nestedRoots.ts +20 -0
- package/src/utils/network.ts +95 -0
- package/src/utils/path.ts +27 -0
- package/src/utils/position.ts +14 -0
- package/src/utils/reservedNames.ts +31 -0
- package/src/utils/strings.ts +7 -0
- package/src/utils/text.ts +11 -0
- package/src/utils/title.ts +68 -0
- package/src/utils/url.ts +8 -0
- package/bin/browser.d.ts +0 -2
- package/bin/browser.js +0 -24
- package/bin/browser.js.map +0 -1
- package/bin/checks.d.ts +0 -8
- package/bin/checks.js +0 -24
- package/bin/checks.js.map +0 -1
- package/bin/downloadImage.d.ts +0 -5
- package/bin/downloadImage.js +0 -88
- package/bin/downloadImage.js.map +0 -1
- package/bin/scraping/combineNavWithEmptyGroupTitles.d.ts +0 -2
- package/bin/scraping/combineNavWithEmptyGroupTitles.js +0 -20
- package/bin/scraping/combineNavWithEmptyGroupTitles.js.map +0 -1
- package/bin/scraping/detectFramework.d.ts +0 -9
- package/bin/scraping/detectFramework.js +0 -36
- package/bin/scraping/detectFramework.js.map +0 -1
- package/bin/scraping/downloadAllImages.d.ts +0 -4
- package/bin/scraping/downloadAllImages.js +0 -36
- package/bin/scraping/downloadAllImages.js.map +0 -1
- package/bin/scraping/downloadLogoImage.d.ts +0 -1
- package/bin/scraping/downloadLogoImage.js +0 -12
- package/bin/scraping/downloadLogoImage.js.map +0 -1
- package/bin/scraping/replaceImagePaths.d.ts +0 -1
- package/bin/scraping/replaceImagePaths.js +0 -14
- package/bin/scraping/replaceImagePaths.js.map +0 -1
- package/bin/scraping/scrapeFileGettingFileNameFromUrl.d.ts +0 -6
- package/bin/scraping/scrapeFileGettingFileNameFromUrl.js +0 -46
- package/bin/scraping/scrapeFileGettingFileNameFromUrl.js.map +0 -1
- package/bin/scraping/scrapeGettingFileNameFromUrl.d.ts +0 -6
- package/bin/scraping/scrapeGettingFileNameFromUrl.js +0 -13
- package/bin/scraping/scrapeGettingFileNameFromUrl.js.map +0 -1
- package/bin/scraping/scrapePage.d.ts +0 -8
- package/bin/scraping/scrapePage.js +0 -10
- package/bin/scraping/scrapePage.js.map +0 -1
- package/bin/scraping/scrapePageCommands.d.ts +0 -7
- package/bin/scraping/scrapePageCommands.js +0 -50
- package/bin/scraping/scrapePageCommands.js.map +0 -1
- package/bin/scraping/scrapeSection.d.ts +0 -3
- package/bin/scraping/scrapeSection.js +0 -12
- package/bin/scraping/scrapeSection.js.map +0 -1
- package/bin/scraping/scrapeSectionCommands.d.ts +0 -6
- package/bin/scraping/scrapeSectionCommands.js +0 -63
- package/bin/scraping/scrapeSectionCommands.js.map +0 -1
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomPage.d.ts +0 -5
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomPage.js +0 -29
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomPage.js.map +0 -1
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomSection.d.ts +0 -2
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomSection.js +0 -31
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomSection.js.map +0 -1
- package/bin/scraping/site-scrapers/alternateGroupTitle.d.ts +0 -3
- package/bin/scraping/site-scrapers/alternateGroupTitle.js +0 -9
- package/bin/scraping/site-scrapers/alternateGroupTitle.js.map +0 -1
- package/bin/scraping/site-scrapers/links-per-group/getDocusaurusLinksPerGroup.d.ts +0 -5
- package/bin/scraping/site-scrapers/links-per-group/getDocusaurusLinksPerGroup.js +0 -33
- package/bin/scraping/site-scrapers/links-per-group/getDocusaurusLinksPerGroup.js.map +0 -1
- package/bin/scraping/site-scrapers/links-per-group/getLinksRecursively.d.ts +0 -3
- package/bin/scraping/site-scrapers/links-per-group/getLinksRecursively.js +0 -35
- package/bin/scraping/site-scrapers/links-per-group/getLinksRecursively.js.map +0 -1
- package/bin/scraping/site-scrapers/links-per-group/getLinksRecursivelyGitBook.d.ts +0 -3
- package/bin/scraping/site-scrapers/links-per-group/getLinksRecursivelyGitBook.js +0 -33
- package/bin/scraping/site-scrapers/links-per-group/getLinksRecursivelyGitBook.js.map +0 -1
- package/bin/scraping/site-scrapers/openNestedDocusaurusMenus.d.ts +0 -2
- package/bin/scraping/site-scrapers/openNestedDocusaurusMenus.js +0 -30
- package/bin/scraping/site-scrapers/openNestedDocusaurusMenus.js.map +0 -1
- package/bin/scraping/site-scrapers/openNestedGitbookMenus.d.ts +0 -2
- package/bin/scraping/site-scrapers/openNestedGitbookMenus.js +0 -21
- package/bin/scraping/site-scrapers/openNestedGitbookMenus.js.map +0 -1
- package/bin/scraping/site-scrapers/scrapeDocusaurusPage.d.ts +0 -5
- package/bin/scraping/site-scrapers/scrapeDocusaurusPage.js +0 -53
- package/bin/scraping/site-scrapers/scrapeDocusaurusPage.js.map +0 -1
- package/bin/scraping/site-scrapers/scrapeDocusaurusSection.d.ts +0 -2
- package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js +0 -32
- package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js.map +0 -1
- package/bin/scraping/site-scrapers/scrapeGitBookPage.d.ts +0 -5
- package/bin/scraping/site-scrapers/scrapeGitBookPage.js +0 -56
- package/bin/scraping/site-scrapers/scrapeGitBookPage.js.map +0 -1
- package/bin/scraping/site-scrapers/scrapeGitBookSection.d.ts +0 -2
- package/bin/scraping/site-scrapers/scrapeGitBookSection.js +0 -42
- package/bin/scraping/site-scrapers/scrapeGitBookSection.js.map +0 -1
- package/bin/scraping/site-scrapers/scrapeReadMePage.d.ts +0 -5
- package/bin/scraping/site-scrapers/scrapeReadMePage.js +0 -38
- package/bin/scraping/site-scrapers/scrapeReadMePage.js.map +0 -1
- package/bin/scraping/site-scrapers/scrapeReadMeSection.d.ts +0 -2
- package/bin/scraping/site-scrapers/scrapeReadMeSection.js +0 -39
- package/bin/scraping/site-scrapers/scrapeReadMeSection.js.map +0 -1
- package/bin/util.d.ts +0 -29
- package/bin/util.js +0 -97
- package/bin/util.js.map +0 -1
- package/src/browser.ts +0 -24
- package/src/checks.ts +0 -32
- package/src/downloadImage.ts +0 -102
- package/src/scraping/combineNavWithEmptyGroupTitles.ts +0 -21
- package/src/scraping/detectFramework.ts +0 -55
- package/src/scraping/downloadAllImages.ts +0 -61
- package/src/scraping/downloadLogoImage.ts +0 -24
- package/src/scraping/replaceImagePaths.ts +0 -17
- package/src/scraping/scrapeFileGettingFileNameFromUrl.ts +0 -84
- package/src/scraping/scrapeGettingFileNameFromUrl.ts +0 -56
- package/src/scraping/scrapePage.ts +0 -40
- package/src/scraping/scrapePageCommands.ts +0 -68
- package/src/scraping/scrapeSection.ts +0 -30
- package/src/scraping/scrapeSectionCommands.ts +0 -98
- package/src/scraping/site-scrapers/Intercom/scrapeIntercomPage.ts +0 -52
- package/src/scraping/site-scrapers/Intercom/scrapeIntercomSection.ts +0 -54
- package/src/scraping/site-scrapers/alternateGroupTitle.ts +0 -11
- package/src/scraping/site-scrapers/links-per-group/getDocusaurusLinksPerGroup.ts +0 -45
- package/src/scraping/site-scrapers/links-per-group/getLinksRecursively.ts +0 -47
- package/src/scraping/site-scrapers/links-per-group/getLinksRecursivelyGitBook.ts +0 -44
- package/src/scraping/site-scrapers/openNestedDocusaurusMenus.ts +0 -42
- package/src/scraping/site-scrapers/openNestedGitbookMenus.ts +0 -27
- package/src/scraping/site-scrapers/scrapeDocusaurusPage.ts +0 -85
- package/src/scraping/site-scrapers/scrapeDocusaurusSection.ts +0 -63
- package/src/scraping/site-scrapers/scrapeGitBookPage.ts +0 -82
- package/src/scraping/site-scrapers/scrapeGitBookSection.ts +0 -69
- package/src/scraping/site-scrapers/scrapeReadMePage.ts +0 -56
- package/src/scraping/site-scrapers/scrapeReadMeSection.ts +0 -66
- package/src/util.ts +0 -122
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { MdxJsxFlowElement } from 'mdast-util-mdx-jsx';
|
|
2
|
+
import { visit } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
export function unifiedRemoveEmptyParagraphs() {
|
|
5
|
+
return function (node: MdxJsxFlowElement) {
|
|
6
|
+
return removeEmptyParagraphs(node);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function removeEmptyParagraphs(node: MdxJsxFlowElement) {
|
|
11
|
+
return visit(node, 'paragraph', function (subNode, index, parent) {
|
|
12
|
+
let emptyChildrenCount = 0;
|
|
13
|
+
for (const child of subNode.children) {
|
|
14
|
+
if ('children' in child && child.children.length === 0) emptyChildrenCount++;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (emptyChildrenCount === subNode.children.length && parent && typeof index === 'number') {
|
|
18
|
+
parent.children.splice(index, 1);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Result } from '../types/result.js';
|
|
2
|
+
import { log } from './log.js';
|
|
3
|
+
|
|
4
|
+
export function getErrorMessage(error: unknown): string {
|
|
5
|
+
return error instanceof Error ? `: ${error.message}` : '';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function logErrorResults(
|
|
9
|
+
actionThatFailed: string,
|
|
10
|
+
results: Array<Result<[string, string]>>
|
|
11
|
+
) {
|
|
12
|
+
const sumOfErrors = results.reduce(
|
|
13
|
+
(prev, curr) => (Number.isNaN(Number(curr.success)) ? prev : prev + Number(!curr.success)),
|
|
14
|
+
0
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
if (sumOfErrors > 0) {
|
|
18
|
+
log(`We encountered ${sumOfErrors} errors when ${actionThatFailed}`, 'warn');
|
|
19
|
+
results.forEach((result) => {
|
|
20
|
+
if (result.success) return;
|
|
21
|
+
log(result.message, 'failure');
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Root } from 'hast';
|
|
2
|
+
import { CONTINUE, SKIP, visit } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
export function escapeCharactersOutsideCodeBlocks() {
|
|
5
|
+
const charsToEscape = ['<', '{', '`'];
|
|
6
|
+
const escapeRegex = new RegExp(`[${charsToEscape.join('')}]`, 'g');
|
|
7
|
+
|
|
8
|
+
return function (tree: Root) {
|
|
9
|
+
visit(tree, function (node) {
|
|
10
|
+
if (node.type === 'element') {
|
|
11
|
+
if (node.tagName === 'pre' || node.tagName === 'code') {
|
|
12
|
+
return SKIP;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (node.type === 'text') {
|
|
17
|
+
const escapedText = node.value.replace(escapeRegex, (match) => {
|
|
18
|
+
return `\\${match}`;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (escapedText !== node.value) {
|
|
22
|
+
node.value = escapedText;
|
|
23
|
+
return CONTINUE;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return CONTINUE;
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function addMdx(filename: string): string {
|
|
2
|
+
if (filename.endsWith('.mdx')) {
|
|
3
|
+
return filename;
|
|
4
|
+
}
|
|
5
|
+
return filename + '.mdx';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function getFileExtension(filename: string): string | undefined {
|
|
9
|
+
const extBeginsIndex = filename.lastIndexOf('.') + 1;
|
|
10
|
+
const ext = filename.substring(extBeginsIndex);
|
|
11
|
+
|
|
12
|
+
if (filename === ext) return undefined;
|
|
13
|
+
return ext.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function fileBelongsInPagesFolder(filename: string): boolean {
|
|
17
|
+
const extension = getFileExtension(filename);
|
|
18
|
+
return !!extension && (extension === 'mdx' || extension === 'md' || extension === 'tsx');
|
|
19
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { getErrorMessage } from './errors.js';
|
|
5
|
+
import { log } from './log.js';
|
|
6
|
+
import { createFilename } from './path.js';
|
|
7
|
+
|
|
8
|
+
export function write(filename: string, data: string | NodeJS.TypedArray) {
|
|
9
|
+
writeFileSync(filename, data);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function toFilename(title: string) {
|
|
13
|
+
// Gets rid of special characters at the start and end
|
|
14
|
+
// of the name by converting to spaces then using trim.
|
|
15
|
+
//
|
|
16
|
+
// I did not write this, I can feel the regex jokes
|
|
17
|
+
// coming already. - Ricardo
|
|
18
|
+
return title
|
|
19
|
+
.replace(/[^a-z0-9]/gi, ' ')
|
|
20
|
+
.trim()
|
|
21
|
+
.replace(/ /g, '-')
|
|
22
|
+
.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function writePage(
|
|
26
|
+
filename: string | URL = '',
|
|
27
|
+
title: string = '',
|
|
28
|
+
description: string = '',
|
|
29
|
+
markdown: string = '',
|
|
30
|
+
url?: string
|
|
31
|
+
): void {
|
|
32
|
+
const rootPath = process.cwd();
|
|
33
|
+
const writePath = createFilename(rootPath, filename, title);
|
|
34
|
+
if (!writePath) return;
|
|
35
|
+
|
|
36
|
+
const cleanedWritePath = writePath.replace(rootPath, '.');
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
mkdirSync(dirname(writePath), { recursive: true });
|
|
40
|
+
write(writePath, formatPageWithFrontmatter(title, description, markdown, url));
|
|
41
|
+
log(`${cleanedWritePath} written to disk`, 'success');
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const errorMessage = getErrorMessage(error);
|
|
44
|
+
log(`${cleanedWritePath} couldn't download to disk${errorMessage}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function formatPageWithFrontmatter(
|
|
49
|
+
title: string = '',
|
|
50
|
+
description: string = '',
|
|
51
|
+
markdown: string = '',
|
|
52
|
+
url: string = ''
|
|
53
|
+
) {
|
|
54
|
+
const optionalTitle = title ? `\ntitle: "${title}"` : '';
|
|
55
|
+
const optionalDescription = description ? `\ndescription: "${description}"` : '';
|
|
56
|
+
const optionalUrl = url ? `\nurl: "${url}"` : '';
|
|
57
|
+
return `---${optionalTitle}${optionalDescription}${optionalUrl}\n---\n\n${markdown}`;
|
|
58
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Element } from 'hast';
|
|
2
|
+
import { EXIT, visit } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
export function findFirstChild(node: Element, tagName: string): Element | undefined {
|
|
5
|
+
let element: Element | undefined = undefined;
|
|
6
|
+
visit(node, 'element', function (subNode) {
|
|
7
|
+
if (subNode.tagName === tagName) {
|
|
8
|
+
element = subNode;
|
|
9
|
+
return EXIT;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return element;
|
|
13
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { SUPPORTED_MEDIA_EXTENSIONS } from '../constants.js';
|
|
5
|
+
import type { Result } from '../types/result.js';
|
|
6
|
+
import { getErrorMessage } from './errors.js';
|
|
7
|
+
import { getFileExtension } from './extension.js';
|
|
8
|
+
import { write } from './file.js';
|
|
9
|
+
import { log } from './log.js';
|
|
10
|
+
import { fetchImage } from './network.js';
|
|
11
|
+
|
|
12
|
+
export async function downloadImage(
|
|
13
|
+
src: string,
|
|
14
|
+
rootPath: string
|
|
15
|
+
): Promise<Result<[string, string]>> {
|
|
16
|
+
try {
|
|
17
|
+
let filename = await writeImageToFile(src, rootPath);
|
|
18
|
+
filename = filename.replace(process.cwd(), '');
|
|
19
|
+
|
|
20
|
+
const shortenedFilename = filename.length > 36 ? `...${filename.slice(-36)}` : filename;
|
|
21
|
+
log(`${shortenedFilename} downloaded and written to disk`, 'success');
|
|
22
|
+
|
|
23
|
+
return { success: true, data: [src, filename] };
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (error instanceof Error) {
|
|
26
|
+
return { success: false, message: error.message };
|
|
27
|
+
} else {
|
|
28
|
+
return {
|
|
29
|
+
success: false,
|
|
30
|
+
message: `${src} - an unknown error occurred downloading this image`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function writeImageToFile(src: string, rootPath: string): Promise<string> {
|
|
37
|
+
const filename = removeMetadataFromImageSrc(src);
|
|
38
|
+
const imagePath = join(rootPath, filename);
|
|
39
|
+
const shortenedFilename = filename.length > 36 ? `...${filename.slice(-36)}` : filename;
|
|
40
|
+
|
|
41
|
+
if (!isValidImageSrc(filename)) {
|
|
42
|
+
throw new Error(`${shortenedFilename} - file extension not supported`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (existsSync(imagePath)) {
|
|
46
|
+
return imagePath;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
mkdirSync(dirname(imagePath), { recursive: true });
|
|
51
|
+
} catch (error) {
|
|
52
|
+
throw new Error(`${imagePath} - failed to create directory`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const imageData = await fetchImage(src);
|
|
57
|
+
write(imagePath, imageData);
|
|
58
|
+
return imagePath;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
const errorMessage = getErrorMessage(error);
|
|
61
|
+
throw new Error(`${shortenedFilename} - failed to download file from source${errorMessage}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function isValidImageSrc(src: string) {
|
|
66
|
+
if (!src) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (src.startsWith('data:')) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const ext = getFileExtension(src);
|
|
75
|
+
if (ext && !SUPPORTED_MEDIA_EXTENSIONS.includes(ext)) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function getFilenameBeforeMetadata(src: string, ext: string): string {
|
|
83
|
+
const lengthUntilMetadata = src.indexOf(`.${ext}`) + `.${ext}`.length;
|
|
84
|
+
return src.slice(0, lengthUntilMetadata);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function removeMetadataFromImageSrc(src: string) {
|
|
88
|
+
let filename = '';
|
|
89
|
+
if (src.includes('gitbook/image')) {
|
|
90
|
+
for (const ext of SUPPORTED_MEDIA_EXTENSIONS) {
|
|
91
|
+
if (src.includes(`.${ext}`)) {
|
|
92
|
+
filename = getFilenameBeforeMetadata(src, ext);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!filename) {
|
|
97
|
+
return src.split('#')[0]!.split('?')[0]!;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return filename.split('%2F').slice(4).join('%2F');
|
|
101
|
+
}
|
package/src/utils/img.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Element } from 'hast';
|
|
2
|
+
import { visit, CONTINUE, EXIT } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
export function findImg(node: Element): string | undefined {
|
|
5
|
+
let imgSrc: string | undefined = undefined;
|
|
6
|
+
visit(node, 'element', function (subNode, index, parent) {
|
|
7
|
+
if (subNode.tagName !== 'img') return CONTINUE;
|
|
8
|
+
|
|
9
|
+
if (parent && typeof index === 'number') {
|
|
10
|
+
parent.children.splice(index, 1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
imgSrc = (subNode.properties.src as string) || undefined;
|
|
14
|
+
return EXIT;
|
|
15
|
+
});
|
|
16
|
+
return imgSrc;
|
|
17
|
+
}
|
package/src/utils/log.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export const colors = {
|
|
2
|
+
red: '\x1b[31m',
|
|
3
|
+
green: '\x1b[32m',
|
|
4
|
+
yellow: '\x1b[33m',
|
|
5
|
+
blue: '\x1b[34m',
|
|
6
|
+
magenta: '\x1b[35m',
|
|
7
|
+
cyan: '\x1b[36m',
|
|
8
|
+
default: '\x1b[0m',
|
|
9
|
+
} as const;
|
|
10
|
+
const statuses = ['success', 'failure', 'error', 'warn', 'warning', 'info'] as const;
|
|
11
|
+
|
|
12
|
+
export type Status = (typeof statuses)[number];
|
|
13
|
+
export type Color = keyof typeof colors;
|
|
14
|
+
|
|
15
|
+
export const checkIcon = '✔ ' as const;
|
|
16
|
+
export const xIcon = '✘ ' as const;
|
|
17
|
+
export const infoIcon = 'ⓘ ' as const;
|
|
18
|
+
export const warningIcon = '⚠ ' as const;
|
|
19
|
+
|
|
20
|
+
export function log(message: string | unknown, statusOrColor?: Status): void {
|
|
21
|
+
let color: (typeof colors)[Color] = colors.blue;
|
|
22
|
+
let statusMsg: string = 'INFO ';
|
|
23
|
+
let icon: string = infoIcon;
|
|
24
|
+
|
|
25
|
+
const msg = typeof message === 'string' ? message.toLowerCase() : '';
|
|
26
|
+
if (!statusOrColor) {
|
|
27
|
+
statusOrColor =
|
|
28
|
+
msg.includes('fail') ||
|
|
29
|
+
msg.includes('error') ||
|
|
30
|
+
msg.includes('could not') ||
|
|
31
|
+
msg.includes("couldn't") ||
|
|
32
|
+
msg.includes('did not') ||
|
|
33
|
+
msg.includes('invalid') ||
|
|
34
|
+
msg.includes("didn't")
|
|
35
|
+
? 'error'
|
|
36
|
+
: msg.includes('success') ||
|
|
37
|
+
msg.includes('downloaded') ||
|
|
38
|
+
msg.includes('written') ||
|
|
39
|
+
msg.includes('added')
|
|
40
|
+
? 'success'
|
|
41
|
+
: msg.includes('warn')
|
|
42
|
+
? 'warn'
|
|
43
|
+
: undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
switch (statusOrColor) {
|
|
47
|
+
case undefined:
|
|
48
|
+
case 'info':
|
|
49
|
+
break;
|
|
50
|
+
|
|
51
|
+
case 'success':
|
|
52
|
+
color = colors.green;
|
|
53
|
+
statusMsg = 'SUCCESS';
|
|
54
|
+
icon = checkIcon;
|
|
55
|
+
break;
|
|
56
|
+
|
|
57
|
+
case 'warn':
|
|
58
|
+
case 'warning':
|
|
59
|
+
color = colors.yellow;
|
|
60
|
+
statusMsg = 'WARNING';
|
|
61
|
+
icon = warningIcon;
|
|
62
|
+
break;
|
|
63
|
+
|
|
64
|
+
case 'failure':
|
|
65
|
+
case 'error':
|
|
66
|
+
color = colors.red;
|
|
67
|
+
statusMsg = 'ERROR ';
|
|
68
|
+
icon = xIcon;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log(
|
|
73
|
+
`${color}${icon} ${statusMsg}${colors.default} - ${
|
|
74
|
+
typeof message === 'string' ||
|
|
75
|
+
typeof message === 'bigint' ||
|
|
76
|
+
typeof message === 'number' ||
|
|
77
|
+
typeof message === 'boolean'
|
|
78
|
+
? message
|
|
79
|
+
: JSON.stringify(message, undefined, 2)
|
|
80
|
+
}`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Root as MdastRoot } from 'mdast';
|
|
2
|
+
import { CONTINUE, visit } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
/** There should only be one root; this replaces any inner roots
|
|
5
|
+
* that we might get because of us converting the content manually
|
|
6
|
+
* to `contentAsRoot` from `content`
|
|
7
|
+
*/
|
|
8
|
+
export function unifiedRemoveNestedRoots() {
|
|
9
|
+
return function (node: MdastRoot) {
|
|
10
|
+
return removeNestedRoots(node);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function removeNestedRoots(root: MdastRoot) {
|
|
15
|
+
visit(root, 'root', function (node, _, parent) {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
17
|
+
if (!parent) return CONTINUE;
|
|
18
|
+
(parent as MdastRoot).children = node.children;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Browser, launch } from 'puppeteer';
|
|
2
|
+
|
|
3
|
+
import { getErrorMessage } from './errors.js';
|
|
4
|
+
import { log } from './log.js';
|
|
5
|
+
|
|
6
|
+
async function exponentialBackoff<T>(
|
|
7
|
+
operation: () => Promise<T>,
|
|
8
|
+
retries: number = 3,
|
|
9
|
+
delay: number = 1000,
|
|
10
|
+
factor: number = 2
|
|
11
|
+
): Promise<T> {
|
|
12
|
+
try {
|
|
13
|
+
return await operation();
|
|
14
|
+
} catch (error) {
|
|
15
|
+
if (retries > 0) {
|
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
17
|
+
return exponentialBackoff(operation, retries - 1, delay * factor, factor);
|
|
18
|
+
} else {
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function startPuppeteer() {
|
|
25
|
+
try {
|
|
26
|
+
return await launch({
|
|
27
|
+
headless: true,
|
|
28
|
+
ignoreHTTPSErrors: true,
|
|
29
|
+
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (error instanceof Error) {
|
|
32
|
+
log(`Could not create a browser instance: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function getHtmlWithPuppeteer(
|
|
38
|
+
browser: Browser,
|
|
39
|
+
url: string | URL
|
|
40
|
+
): Promise<string | undefined> {
|
|
41
|
+
const page = await browser.newPage();
|
|
42
|
+
await page.goto(url.toString(), {
|
|
43
|
+
waitUntil: 'networkidle2',
|
|
44
|
+
});
|
|
45
|
+
const html = await exponentialBackoff(() => page.content());
|
|
46
|
+
return html;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function fetchPageResponse(url: string | URL): Promise<string> {
|
|
50
|
+
try {
|
|
51
|
+
const res = await fetch(url);
|
|
52
|
+
if (!res.ok) {
|
|
53
|
+
throw new Error(`${res.status} ${res.statusText}`);
|
|
54
|
+
}
|
|
55
|
+
return await res.text();
|
|
56
|
+
} catch (error) {
|
|
57
|
+
const errorMessage = getErrorMessage(error);
|
|
58
|
+
throw new Error(`${url}\n\t- failed to fetch page from source${errorMessage}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function fetchPageHtml(
|
|
63
|
+
url: string | URL,
|
|
64
|
+
browser: Browser | undefined = undefined
|
|
65
|
+
): Promise<string> {
|
|
66
|
+
if (browser) {
|
|
67
|
+
try {
|
|
68
|
+
const res = await getHtmlWithPuppeteer(browser, url);
|
|
69
|
+
if (res) return res;
|
|
70
|
+
throw new Error('an unknown error occured');
|
|
71
|
+
} catch (error) {
|
|
72
|
+
const errorMessage = getErrorMessage(error);
|
|
73
|
+
throw new Error(`${url}\n\t- Puppeteer failed to retrieve page from source${errorMessage}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return await exponentialBackoff(() => fetchPageResponse(url));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function fetchImage(url: string): Promise<NodeJS.TypedArray> {
|
|
81
|
+
try {
|
|
82
|
+
const res = await exponentialBackoff(() => fetch(url));
|
|
83
|
+
if (!res.ok) {
|
|
84
|
+
throw new Error(`${res.status} ${res.statusText}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const imageBuffer = await res.arrayBuffer();
|
|
88
|
+
const imageData = new Uint8Array(imageBuffer);
|
|
89
|
+
|
|
90
|
+
return imageData;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
const errorMessage = getErrorMessage(error);
|
|
93
|
+
throw new Error(`${url}\n\t- failed to retrieve image from source${errorMessage}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
|
|
3
|
+
import { addMdx } from './extension.js';
|
|
4
|
+
import { toFilename } from './file.js';
|
|
5
|
+
import { log } from './log.js';
|
|
6
|
+
|
|
7
|
+
export function createFilename(
|
|
8
|
+
rootPath: string = process.cwd(),
|
|
9
|
+
filename: string | URL,
|
|
10
|
+
title?: string
|
|
11
|
+
): string | undefined {
|
|
12
|
+
if (typeof filename === 'string' && filename.startsWith('http')) {
|
|
13
|
+
const url = new URL(filename);
|
|
14
|
+
filename = url.pathname;
|
|
15
|
+
} else if (typeof filename === 'object') {
|
|
16
|
+
filename = (filename as URL).pathname;
|
|
17
|
+
} else {
|
|
18
|
+
filename = filename as string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (filename === '') {
|
|
22
|
+
log(`Invalid file name provided: ${filename}`, 'error');
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return join(rootPath, addMdx(filename || toFilename(title ?? '')));
|
|
27
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Element } from 'hast';
|
|
2
|
+
import { visit } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
export function unifiedRemovePositions() {
|
|
5
|
+
return function (node: Element) {
|
|
6
|
+
return removePositions(node);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function removePositions(node: Element) {
|
|
11
|
+
return visit(node, function (subNode) {
|
|
12
|
+
delete subNode.position;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const blacklistedNames = new Map<string, string>([['api', 'api-reference']]);
|
|
2
|
+
|
|
3
|
+
export const INDEX_NAMES = [
|
|
4
|
+
'home',
|
|
5
|
+
'introduction',
|
|
6
|
+
'getting-started',
|
|
7
|
+
'get-started',
|
|
8
|
+
'welcome',
|
|
9
|
+
'start',
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export const GROUP_NAMES = [
|
|
13
|
+
'Home',
|
|
14
|
+
'Introduction',
|
|
15
|
+
'Getting Started',
|
|
16
|
+
'Get Started',
|
|
17
|
+
'Welcome',
|
|
18
|
+
'Start',
|
|
19
|
+
'Docs',
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export function iterateThroughReservedNames(
|
|
23
|
+
namesToUse: Array<string>,
|
|
24
|
+
namesInUse: Array<string>
|
|
25
|
+
): string {
|
|
26
|
+
for (const name of namesToUse) {
|
|
27
|
+
if (namesInUse.includes(name)) continue;
|
|
28
|
+
return name;
|
|
29
|
+
}
|
|
30
|
+
return '';
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Element } from 'hast';
|
|
2
|
+
import { visit } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
export function getText(element: Element | undefined): string {
|
|
5
|
+
if (!element) return '';
|
|
6
|
+
let text = '';
|
|
7
|
+
visit(element, 'text', function (node) {
|
|
8
|
+
text += node.value;
|
|
9
|
+
});
|
|
10
|
+
return text;
|
|
11
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Element, ElementContent, Root as HastRoot } from 'hast';
|
|
2
|
+
import type { Root as MdastRoot, BlockContent } from 'mdast';
|
|
3
|
+
import { visit, CONTINUE, EXIT } from 'unist-util-visit';
|
|
4
|
+
|
|
5
|
+
export function findTitle(
|
|
6
|
+
node: Element | ElementContent | BlockContent | MdastRoot | HastRoot | undefined,
|
|
7
|
+
opts: { delete: boolean; nodeType?: string; tagName?: string } = {
|
|
8
|
+
delete: true,
|
|
9
|
+
nodeType: undefined,
|
|
10
|
+
tagName: undefined,
|
|
11
|
+
}
|
|
12
|
+
): string {
|
|
13
|
+
let title = '';
|
|
14
|
+
if (!node) return title;
|
|
15
|
+
|
|
16
|
+
visit(node, opts.nodeType ? opts.nodeType : node, function (subNode) {
|
|
17
|
+
if (opts.tagName && subNode.type === 'element' && subNode.tagName !== opts.tagName) {
|
|
18
|
+
return CONTINUE;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
visit(subNode, 'text', function (textNode, index, parent) {
|
|
22
|
+
title += textNode.value;
|
|
23
|
+
if (opts.delete && parent && typeof index === 'number') {
|
|
24
|
+
parent.children.splice(index, 1);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
return title.trim();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getTitleFromHeading(root: MdastRoot): string {
|
|
32
|
+
let headingElement: BlockContent | undefined = undefined;
|
|
33
|
+
visit(root, 'heading', function (subNode, index, parent) {
|
|
34
|
+
headingElement = subNode;
|
|
35
|
+
if (parent && typeof index === 'number') {
|
|
36
|
+
parent.children.splice(index, 1);
|
|
37
|
+
}
|
|
38
|
+
return EXIT;
|
|
39
|
+
});
|
|
40
|
+
return findTitle(headingElement);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function getDescriptionFromRoot(root: MdastRoot): string {
|
|
44
|
+
let descriptionElement: BlockContent | undefined = undefined;
|
|
45
|
+
visit(root, 'paragraph', function (subNode, index, parent) {
|
|
46
|
+
if (typeof index !== 'number' || index !== 0 || !parent || parent.type !== 'root') return EXIT;
|
|
47
|
+
|
|
48
|
+
descriptionElement = subNode;
|
|
49
|
+
if (typeof index === 'number') {
|
|
50
|
+
parent.children.splice(index, 1);
|
|
51
|
+
}
|
|
52
|
+
return EXIT;
|
|
53
|
+
});
|
|
54
|
+
return findTitle(descriptionElement);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function getTitleFromLink(url: string): string {
|
|
58
|
+
if (url.startsWith('http')) {
|
|
59
|
+
url = new URL(url).pathname;
|
|
60
|
+
}
|
|
61
|
+
const lastPathname = url.split('/').at(-1) ?? '';
|
|
62
|
+
const dashSplitPathname = lastPathname.split('-').flatMap((i) => i.split('_'));
|
|
63
|
+
dashSplitPathname.forEach((str, index) => {
|
|
64
|
+
dashSplitPathname[index] = str[0] ? `${str[0].toUpperCase()}${str.substring(1)}` : str;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return dashSplitPathname.join(' ');
|
|
68
|
+
}
|
package/src/utils/url.ts
ADDED
package/bin/browser.d.ts
DELETED