@mintlify/scraping 3.0.16 → 3.0.18
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/__test__/prepareStringToBeValidFilename.test.ts +67 -0
- package/bin/cli.js +19 -5
- package/bin/cli.js.map +1 -1
- package/bin/openapi/index.d.ts +4 -2
- package/bin/openapi/index.js +14 -3
- package/bin/openapi/index.js.map +1 -1
- package/bin/scraping/combineNavWithEmptyGroupTitles.d.ts +2 -1
- package/bin/scraping/combineNavWithEmptyGroupTitles.js.map +1 -1
- package/bin/scraping/scrapeFileGettingFileNameFromUrl.d.ts +2 -1
- package/bin/scraping/scrapeFileGettingFileNameFromUrl.js +4 -1
- package/bin/scraping/scrapeFileGettingFileNameFromUrl.js.map +1 -1
- package/bin/scraping/scrapeGettingFileNameFromUrl.d.ts +3 -2
- package/bin/scraping/scrapeGettingFileNameFromUrl.js.map +1 -1
- package/bin/scraping/scrapePage.d.ts +7 -0
- package/bin/scraping/scrapePage.js.map +1 -1
- package/bin/scraping/scrapePageCommands.d.ts +1 -0
- package/bin/scraping/scrapePageCommands.js.map +1 -1
- package/bin/scraping/scrapeSection.d.ts +2 -0
- package/bin/scraping/scrapeSection.js.map +1 -1
- package/bin/scraping/scrapeSectionCommands.d.ts +1 -0
- package/bin/scraping/scrapeSectionCommands.js.map +1 -1
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomSection.d.ts +2 -1
- package/bin/scraping/site-scrapers/Intercom/scrapeIntercomSection.js.map +1 -1
- package/bin/scraping/site-scrapers/scrapeDocusaurusSection.d.ts +2 -1
- package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js.map +1 -1
- package/bin/scraping/site-scrapers/scrapeGitBookSection.d.ts +2 -1
- package/bin/scraping/site-scrapers/scrapeGitBookSection.js.map +1 -1
- package/bin/scraping/site-scrapers/scrapeReadMeSection.d.ts +2 -1
- package/bin/scraping/site-scrapers/scrapeReadMeSection.js.map +1 -1
- package/bin/tsconfig.tsbuildinfo +1 -1
- package/bin/util.d.ts +2 -1
- package/bin/util.js.map +1 -1
- package/package.json +11 -3
- package/src/cli.ts +22 -10
- package/src/openapi/index.ts +31 -14
- package/src/scraping/combineNavWithEmptyGroupTitles.ts +5 -5
- package/src/scraping/scrapeFileGettingFileNameFromUrl.ts +6 -2
- package/src/scraping/scrapeGettingFileNameFromUrl.ts +5 -3
- package/src/scraping/scrapePage.ts +15 -0
- package/src/scraping/scrapePageCommands.ts +1 -1
- package/src/scraping/scrapeSection.ts +10 -0
- package/src/scraping/scrapeSectionCommands.ts +1 -1
- package/src/scraping/site-scrapers/Intercom/scrapeIntercomSection.ts +4 -3
- package/src/scraping/site-scrapers/scrapeDocusaurusSection.ts +4 -3
- package/src/scraping/site-scrapers/scrapeGitBookSection.ts +4 -3
- package/src/scraping/site-scrapers/scrapeReadMeSection.ts +4 -3
- package/src/util.ts +2 -1
- package/src/types.d.ts +0 -65
package/bin/util.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import { Ora as OraType } from 'ora';
|
|
2
3
|
export declare const MintConfig: (name: string, color: string, ctaName: string, ctaUrl: string, filename: string) => {
|
|
3
4
|
name: string;
|
|
@@ -19,7 +20,7 @@ export declare const MintConfig: (name: string, color: string, ctaName: string,
|
|
|
19
20
|
};
|
|
20
21
|
export declare const Page: (title: string, description?: string, markdown?: string) => string;
|
|
21
22
|
export declare function getOrigin(url: string): string;
|
|
22
|
-
export declare function objToReadableString(objs:
|
|
23
|
+
export declare function objToReadableString(objs: NavigationEntry[]): string;
|
|
23
24
|
export declare const toFilename: (title: string) => string;
|
|
24
25
|
export declare const addMdx: (fileName: string) => string;
|
|
25
26
|
export declare const createPage: (title: string, description?: string, markdown?: string, overwrite?: boolean, rootDir?: string, fileName?: string) => void;
|
package/bin/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/scraping",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.18",
|
|
4
4
|
"description": "Scrape documentation frameworks to Mintlify docs",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -29,10 +29,16 @@
|
|
|
29
29
|
"prepare": "npm run build",
|
|
30
30
|
"build": "tsc",
|
|
31
31
|
"watch": "tsc --watch",
|
|
32
|
+
"test": "jest",
|
|
32
33
|
"lint": "eslint . --cache",
|
|
33
34
|
"format": "prettier \"./src/**/*.ts\" --write",
|
|
34
35
|
"format:check": "prettier \"./src/**/*.ts\" --check"
|
|
35
36
|
},
|
|
37
|
+
"jest": {
|
|
38
|
+
"preset": "ts-jest",
|
|
39
|
+
"testEnvironment": "node",
|
|
40
|
+
"verbose": true
|
|
41
|
+
},
|
|
36
42
|
"dependencies": {
|
|
37
43
|
"@apidevtools/swagger-parser": "^10.1.0",
|
|
38
44
|
"axios": "^1.2.2",
|
|
@@ -50,6 +56,7 @@
|
|
|
50
56
|
"@mintlify/eslint-config-typescript": "1.0.7",
|
|
51
57
|
"@mintlify/prettier-config": "1.0.1",
|
|
52
58
|
"@mintlify/ts-config": "1.0.7",
|
|
59
|
+
"@mintlify/validation": "0.1.60",
|
|
53
60
|
"@trivago/prettier-plugin-sort-imports": "3.x",
|
|
54
61
|
"@tsconfig/recommended": "1.x",
|
|
55
62
|
"@types/cheerio": "^0.22.31",
|
|
@@ -61,10 +68,11 @@
|
|
|
61
68
|
"eslint": "8.x",
|
|
62
69
|
"eslint-config-prettier": "8.x",
|
|
63
70
|
"eslint-plugin-unused-imports": "2.x",
|
|
64
|
-
"jest": "^29.
|
|
71
|
+
"jest": "^29.6.1",
|
|
65
72
|
"openapi-types": "^12.1.3",
|
|
66
73
|
"prettier": "2.x",
|
|
74
|
+
"ts-jest": "^29.1.1",
|
|
67
75
|
"typescript": "^4.8.2"
|
|
68
76
|
},
|
|
69
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "1a17dd9dcd1b9a928ad1cd592a20c426c011bcd1"
|
|
70
78
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
4
|
+
import { existsSync } from 'fs';
|
|
4
5
|
import yargs from 'yargs';
|
|
5
6
|
import { hideBin } from 'yargs/helpers';
|
|
6
7
|
|
|
@@ -104,18 +105,29 @@ yargs(hideBin(process.argv))
|
|
|
104
105
|
});
|
|
105
106
|
},
|
|
106
107
|
async (argv) => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
try {
|
|
109
|
+
if (argv.openapiFilename === undefined) {
|
|
110
|
+
throw new Error(
|
|
111
|
+
'Provide the path to your OpenAPI file (e.g. mintlify-scrape openapi-files ./openapi.json)'
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (!existsSync(argv.openapiFilename)) {
|
|
115
|
+
throw new Error(`The file "${argv.openapiFilename}" does not exist`);
|
|
116
|
+
}
|
|
117
|
+
const { nav } = await generateOpenApiPages(
|
|
118
|
+
argv.openapiFilename,
|
|
119
|
+
argv.writeFiles,
|
|
120
|
+
argv.outDir
|
|
110
121
|
);
|
|
122
|
+
console.log('navigation object suggestion:');
|
|
123
|
+
console.log(JSON.stringify(nav, undefined, 2));
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (error instanceof Error) {
|
|
126
|
+
console.error(error.message);
|
|
127
|
+
} else {
|
|
128
|
+
console.error(error);
|
|
129
|
+
}
|
|
111
130
|
}
|
|
112
|
-
const { nav } = await generateOpenApiPages(
|
|
113
|
-
argv.openapiFilename,
|
|
114
|
-
argv.writeFiles,
|
|
115
|
-
argv.outDir
|
|
116
|
-
);
|
|
117
|
-
console.log('navigation object suggestion:');
|
|
118
|
-
console.log(JSON.stringify(nav, undefined, 2));
|
|
119
131
|
}
|
|
120
132
|
)
|
|
121
133
|
// Print the help menu when the user enters an invalid command.
|
package/src/openapi/index.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import SwaggerParser from '@apidevtools/swagger-parser';
|
|
2
|
+
import {
|
|
3
|
+
DecoratedNavigation,
|
|
4
|
+
DecoratedNavigationGroup,
|
|
5
|
+
Navigation,
|
|
6
|
+
NavigationEntry,
|
|
7
|
+
NavigationGroup,
|
|
8
|
+
} from '@mintlify/models';
|
|
2
9
|
import { outputFile } from 'fs-extra';
|
|
3
10
|
import { join } from 'node:path';
|
|
4
11
|
import { OpenAPI, OpenAPIV3 } from 'openapi-types';
|
|
@@ -8,8 +15,8 @@ export const generateOpenApiPages = async (
|
|
|
8
15
|
writeFiles?: boolean,
|
|
9
16
|
outDir?: string
|
|
10
17
|
): Promise<{
|
|
11
|
-
nav:
|
|
12
|
-
decoratedNav:
|
|
18
|
+
nav: Navigation;
|
|
19
|
+
decoratedNav: DecoratedNavigation;
|
|
13
20
|
spec: OpenAPI.Document;
|
|
14
21
|
}> => {
|
|
15
22
|
let spec: OpenAPI.Document | undefined = undefined;
|
|
@@ -23,8 +30,8 @@ export const generateOpenApiPages = async (
|
|
|
23
30
|
throw new Error('No paths defined.');
|
|
24
31
|
}
|
|
25
32
|
|
|
26
|
-
const nav:
|
|
27
|
-
const decoratedNav:
|
|
33
|
+
const nav: Navigation = [];
|
|
34
|
+
const decoratedNav: DecoratedNavigation = [];
|
|
28
35
|
|
|
29
36
|
Object.entries(spec.paths).forEach(([path, pathItemObject]) => {
|
|
30
37
|
if (pathItemObject === undefined) {
|
|
@@ -35,12 +42,13 @@ export const generateOpenApiPages = async (
|
|
|
35
42
|
const operation = pathItemObject[method];
|
|
36
43
|
const groupName = operation?.tags?.[0];
|
|
37
44
|
const title =
|
|
38
|
-
operation?.summary
|
|
39
|
-
`${method}-${path
|
|
40
|
-
const
|
|
45
|
+
prepareStringToBeValidFilename(operation?.summary) ??
|
|
46
|
+
`${method}-${prepareStringToBeValidFilename(path)}`;
|
|
47
|
+
const folder = prepareStringToBeValidFilename(groupName) ?? '';
|
|
48
|
+
const base = join(outDir ?? '', folder, title);
|
|
41
49
|
|
|
42
|
-
const navGroup = findNavGroup<
|
|
43
|
-
const decoratedNavGroup = findNavGroup<
|
|
50
|
+
const navGroup = findNavGroup<NavigationGroup>(nav, groupName);
|
|
51
|
+
const decoratedNavGroup = findNavGroup<DecoratedNavigationGroup>(decoratedNav, groupName);
|
|
44
52
|
|
|
45
53
|
const filenameWithoutExtension = generateUniqueFilenameWithoutExtension(navGroup, base);
|
|
46
54
|
navGroup.push(filenameWithoutExtension);
|
|
@@ -62,7 +70,7 @@ export const generateOpenApiPages = async (
|
|
|
62
70
|
};
|
|
63
71
|
|
|
64
72
|
// returns the group with the given group name, or the top-level group if no group name is provided
|
|
65
|
-
const findNavGroup = <T extends
|
|
73
|
+
const findNavGroup = <T extends NavigationGroup | DecoratedNavigationGroup>(
|
|
66
74
|
nav: T['pages'][number][],
|
|
67
75
|
groupName?: string
|
|
68
76
|
): T['pages'][number][] => {
|
|
@@ -87,10 +95,7 @@ const findNavGroup = <T extends MintNavigation | DecoratedMintNavigation>(
|
|
|
87
95
|
};
|
|
88
96
|
|
|
89
97
|
// returns a filename that is unique within the given array of pages
|
|
90
|
-
const generateUniqueFilenameWithoutExtension = (
|
|
91
|
-
pages: MintNavigationEntry[],
|
|
92
|
-
base: string
|
|
93
|
-
): string => {
|
|
98
|
+
const generateUniqueFilenameWithoutExtension = (pages: NavigationEntry[], base: string): string => {
|
|
94
99
|
let filename = base;
|
|
95
100
|
if (pages.includes(filename)) {
|
|
96
101
|
let extension = 1;
|
|
@@ -114,3 +119,15 @@ openapi: ${method} ${path}
|
|
|
114
119
|
|
|
115
120
|
outputFile(filename, data);
|
|
116
121
|
};
|
|
122
|
+
|
|
123
|
+
export const prepareStringToBeValidFilename = (str?: string) =>
|
|
124
|
+
str
|
|
125
|
+
? str
|
|
126
|
+
.replaceAll(' ', '-')
|
|
127
|
+
.replace(/\{.*?\}/g, '-') // remove path parameters
|
|
128
|
+
.replace(/^-/, '')
|
|
129
|
+
.replace(/-$/, '')
|
|
130
|
+
.replace(/[{}(),.'\n\/]/g, '') // remove special characters
|
|
131
|
+
.replaceAll(/--/g, '-') // replace double hyphens
|
|
132
|
+
.toLowerCase()
|
|
133
|
+
: undefined;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
navArray: MintNavigation[]
|
|
3
|
-
): MintNavigation[] {
|
|
4
|
-
const newNavArray: MintNavigation[] = [];
|
|
1
|
+
import { Navigation, NavigationGroup } from '@mintlify/models';
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
export default function combineNavWithEmptyGroupTitles(navArray: Navigation): Navigation {
|
|
4
|
+
const newNavArray: Navigation = [];
|
|
5
|
+
|
|
6
|
+
navArray.forEach((nav: NavigationGroup) => {
|
|
7
7
|
// The first run through the loop will always have -1 as the index.
|
|
8
8
|
// JavaScript returns undefined when we look for an index outside the size of the array.
|
|
9
9
|
const prev = newNavArray[newNavArray.length - 1];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import axios from 'axios';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
|
|
@@ -24,7 +25,7 @@ export async function scrapeFileGettingFileNameFromUrl(
|
|
|
24
25
|
puppeteer = false,
|
|
25
26
|
version: string | undefined,
|
|
26
27
|
baseToRemove?: string
|
|
27
|
-
): Promise<
|
|
28
|
+
): Promise<NavigationEntry> {
|
|
28
29
|
// Skip scraping external links
|
|
29
30
|
if (pathname.startsWith('https://') || pathname.startsWith('http://')) {
|
|
30
31
|
return pathname;
|
|
@@ -64,7 +65,10 @@ export async function scrapeFileGettingFileNameFromUrl(
|
|
|
64
65
|
|
|
65
66
|
// Check if page didn't have content
|
|
66
67
|
if (!title && !markdown) {
|
|
67
|
-
return {
|
|
68
|
+
return {
|
|
69
|
+
group: '',
|
|
70
|
+
pages: [],
|
|
71
|
+
};
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
const newFileLocation = folders ? path.join(cliDir, folders) : cliDir;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { NavigationEntry } from '@mintlify/models';
|
|
2
|
+
|
|
1
3
|
import { scrapeFileGettingFileNameFromUrl } from './scrapeFileGettingFileNameFromUrl.js';
|
|
2
4
|
|
|
3
5
|
export async function scrapeGettingFileNameFromUrl(
|
|
4
|
-
navEntry:
|
|
6
|
+
navEntry: NavigationEntry,
|
|
5
7
|
cliDir: string,
|
|
6
8
|
origin: string,
|
|
7
9
|
overwrite: boolean,
|
|
@@ -20,9 +22,9 @@ export async function scrapeGettingFileNameFromUrl(
|
|
|
20
22
|
puppeteer = false,
|
|
21
23
|
version: string | undefined,
|
|
22
24
|
baseToRemove?: string
|
|
23
|
-
): Promise<
|
|
25
|
+
): Promise<NavigationEntry> {
|
|
24
26
|
if (typeof navEntry !== 'string') {
|
|
25
|
-
const newPages:
|
|
27
|
+
const newPages: NavigationEntry[] = [];
|
|
26
28
|
for (const nestedNavEntry of navEntry.pages) {
|
|
27
29
|
newPages.push(
|
|
28
30
|
await scrapeGettingFileNameFromUrl(
|
|
@@ -2,6 +2,21 @@ import path from 'path';
|
|
|
2
2
|
|
|
3
3
|
import { createPage, getOrigin } from '../util.js';
|
|
4
4
|
|
|
5
|
+
type ScrapePageResult = {
|
|
6
|
+
title: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
markdown?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ScrapePageFn = (
|
|
12
|
+
html: string,
|
|
13
|
+
origin: string,
|
|
14
|
+
cliDir: string,
|
|
15
|
+
imageBaseDir: string,
|
|
16
|
+
overwrite: boolean,
|
|
17
|
+
version: string | undefined
|
|
18
|
+
) => Promise<ScrapePageResult>;
|
|
19
|
+
|
|
5
20
|
export async function scrapePage(
|
|
6
21
|
scrapeFunc: ScrapePageFn,
|
|
7
22
|
href: string,
|
|
@@ -4,7 +4,7 @@ import { ArgumentsCamelCase } from 'yargs';
|
|
|
4
4
|
import { getHtmlWithPuppeteer } from '../browser.js';
|
|
5
5
|
import { getHrefFromArgs } from '../util.js';
|
|
6
6
|
import { detectFramework, Frameworks } from './detectFramework.js';
|
|
7
|
-
import { scrapePage } from './scrapePage.js';
|
|
7
|
+
import { scrapePage, ScrapePageFn } from './scrapePage.js';
|
|
8
8
|
import { scrapeIntercomPage } from './site-scrapers/Intercom/scrapeIntercomPage.js';
|
|
9
9
|
import { scrapeDocusaurusPage } from './site-scrapers/scrapeDocusaurusPage.js';
|
|
10
10
|
import { scrapeGitBookPage } from './site-scrapers/scrapeGitBookPage.js';
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
import { NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import path from 'path';
|
|
2
3
|
|
|
3
4
|
import { objToReadableString } from '../util.js';
|
|
4
5
|
|
|
6
|
+
export type ScrapeSectionFn = (
|
|
7
|
+
html: string,
|
|
8
|
+
origin: string,
|
|
9
|
+
cliDir: string,
|
|
10
|
+
imageBaseDir: string,
|
|
11
|
+
overwrite: boolean,
|
|
12
|
+
version: string | undefined
|
|
13
|
+
) => Promise<NavigationEntry[]>;
|
|
14
|
+
|
|
5
15
|
export async function scrapeSection(
|
|
6
16
|
scrapeFunc: ScrapeSectionFn,
|
|
7
17
|
html: string,
|
|
@@ -4,7 +4,7 @@ import { ArgumentsCamelCase } from 'yargs';
|
|
|
4
4
|
import { startBrowser } from '../browser.js';
|
|
5
5
|
import { getHrefFromArgs, getOrigin } from '../util.js';
|
|
6
6
|
import { detectFramework, Frameworks } from './detectFramework.js';
|
|
7
|
-
import { scrapeSection } from './scrapeSection.js';
|
|
7
|
+
import { ScrapeSectionFn, scrapeSection } from './scrapeSection.js';
|
|
8
8
|
import { scrapeIntercomSection } from './site-scrapers/Intercom/scrapeIntercomSection.js';
|
|
9
9
|
import openNestedDocusaurusMenus from './site-scrapers/openNestedDocusaurusMenus.js';
|
|
10
10
|
import openNestedGitbookMenus from './site-scrapers/openNestedGitbookMenus.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Navigation, NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import axios from 'axios';
|
|
2
3
|
import cheerio from 'cheerio';
|
|
3
4
|
|
|
@@ -12,7 +13,7 @@ export async function scrapeIntercomSection(
|
|
|
12
13
|
imageBaseDir: string,
|
|
13
14
|
overwrite: boolean,
|
|
14
15
|
version: string | undefined
|
|
15
|
-
): Promise<
|
|
16
|
+
): Promise<NavigationEntry[]> {
|
|
16
17
|
let $ = cheerio.load(html);
|
|
17
18
|
|
|
18
19
|
const logoSrc = $('.header__logo img').first().attr('src');
|
|
@@ -35,10 +36,10 @@ export async function scrapeIntercomSection(
|
|
|
35
36
|
};
|
|
36
37
|
});
|
|
37
38
|
|
|
38
|
-
const collections:
|
|
39
|
+
const collections: Navigation = await Promise.all(collectionsMap);
|
|
39
40
|
|
|
40
41
|
return await Promise.all(
|
|
41
|
-
collections.map(async (entry:
|
|
42
|
+
collections.map(async (entry: NavigationEntry) => {
|
|
42
43
|
return await scrapeGettingFileNameFromUrl(
|
|
43
44
|
entry,
|
|
44
45
|
cliDir,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Navigation, NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import cheerio from 'cheerio';
|
|
2
3
|
|
|
3
4
|
import combineNavWithEmptyGroupTitles from '../combineNavWithEmptyGroupTitles.js';
|
|
@@ -13,7 +14,7 @@ export async function scrapeDocusaurusSection(
|
|
|
13
14
|
imageBaseDir: string,
|
|
14
15
|
overwrite: boolean,
|
|
15
16
|
version?: string
|
|
16
|
-
): Promise<
|
|
17
|
+
): Promise<Navigation> {
|
|
17
18
|
const $ = cheerio.load(html);
|
|
18
19
|
|
|
19
20
|
// Download the logo
|
|
@@ -24,7 +25,7 @@ export async function scrapeDocusaurusSection(
|
|
|
24
25
|
const navigationSections = $('.theme-doc-sidebar-menu').first().children();
|
|
25
26
|
|
|
26
27
|
// Get all links per group
|
|
27
|
-
const groupsConfig:
|
|
28
|
+
const groupsConfig: Navigation = getDocusaurusLinksPerGroup(navigationSections, $, version);
|
|
28
29
|
|
|
29
30
|
// Merge groups with empty titles together
|
|
30
31
|
const reducedGroupsConfig = combineNavWithEmptyGroupTitles(groupsConfig);
|
|
@@ -34,7 +35,7 @@ export async function scrapeDocusaurusSection(
|
|
|
34
35
|
reducedGroupsConfig.map(async (groupConfig) => {
|
|
35
36
|
groupConfig.pages = (
|
|
36
37
|
await Promise.all(
|
|
37
|
-
groupConfig.pages.map(async (navEntry:
|
|
38
|
+
groupConfig.pages.map(async (navEntry: NavigationEntry) =>
|
|
38
39
|
// Docusaurus requires a directory on all sections wheras we use root.
|
|
39
40
|
// /docs is their default directory so we remove it
|
|
40
41
|
scrapeGettingFileNameFromUrl(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Navigation, NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import cheerio from 'cheerio';
|
|
2
3
|
|
|
3
4
|
import combineNavWithEmptyGroupTitles from '../combineNavWithEmptyGroupTitles.js';
|
|
@@ -14,7 +15,7 @@ export async function scrapeGitBookSection(
|
|
|
14
15
|
imageBaseDir: string,
|
|
15
16
|
overwrite: boolean,
|
|
16
17
|
version: string | undefined
|
|
17
|
-
): Promise<
|
|
18
|
+
): Promise<NavigationEntry[]> {
|
|
18
19
|
const $ = cheerio.load(html);
|
|
19
20
|
|
|
20
21
|
// Download the logo
|
|
@@ -34,7 +35,7 @@ export async function scrapeGitBookSection(
|
|
|
34
35
|
.children();
|
|
35
36
|
|
|
36
37
|
// Get all links per group
|
|
37
|
-
const groupsConfig:
|
|
38
|
+
const groupsConfig: Navigation = navigationSections
|
|
38
39
|
.toArray()
|
|
39
40
|
.map((s: cheerio.Element) => {
|
|
40
41
|
const section = $(s);
|
|
@@ -59,7 +60,7 @@ export async function scrapeGitBookSection(
|
|
|
59
60
|
|
|
60
61
|
// Scrape each link in the navigation.
|
|
61
62
|
return Promise.all(
|
|
62
|
-
reducedGroupsConfig.map(async (navEntry:
|
|
63
|
+
reducedGroupsConfig.map(async (navEntry: NavigationEntry) => {
|
|
63
64
|
return await scrapeGettingFileNameFromUrl(
|
|
64
65
|
navEntry,
|
|
65
66
|
cliDir,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Navigation, NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import cheerio from 'cheerio';
|
|
2
3
|
|
|
3
4
|
import downloadLogoImage from '../downloadLogoImage.js';
|
|
@@ -12,7 +13,7 @@ export async function scrapeReadMeSection(
|
|
|
12
13
|
imageBaseDir: string,
|
|
13
14
|
overwrite: boolean,
|
|
14
15
|
version: string | undefined
|
|
15
|
-
): Promise<
|
|
16
|
+
): Promise<NavigationEntry[]> {
|
|
16
17
|
const $ = cheerio.load(html);
|
|
17
18
|
|
|
18
19
|
// Download the logo
|
|
@@ -24,7 +25,7 @@ export async function scrapeReadMeSection(
|
|
|
24
25
|
// responsiveness but they all have the same links.
|
|
25
26
|
const navigationSections = $('.rm-Sidebar').first().find('.rm-Sidebar-section');
|
|
26
27
|
|
|
27
|
-
const groupsConfig:
|
|
28
|
+
const groupsConfig: Navigation = navigationSections.toArray().map((s: cheerio.Element) => {
|
|
28
29
|
const section = $(s);
|
|
29
30
|
const sectionTitle = section.find('h3').first().text();
|
|
30
31
|
|
|
@@ -47,7 +48,7 @@ export async function scrapeReadMeSection(
|
|
|
47
48
|
|
|
48
49
|
// Scrape each link in the navigation.
|
|
49
50
|
return Promise.all(
|
|
50
|
-
groupsConfig.map(async (navEntry:
|
|
51
|
+
groupsConfig.map(async (navEntry: NavigationEntry) => {
|
|
51
52
|
return await scrapeGettingFileNameFromUrl(
|
|
52
53
|
// ReadMe requires a directory on all sections whereas we use root.
|
|
53
54
|
// /docs is their default directory so we remove it
|
package/src/util.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NavigationEntry } from '@mintlify/models';
|
|
1
2
|
import { mkdirSync, writeFileSync } from 'fs';
|
|
2
3
|
import Ora, { Ora as OraType } from 'ora';
|
|
3
4
|
import path from 'path';
|
|
@@ -58,7 +59,7 @@ export function getOrigin(url: string) {
|
|
|
58
59
|
return new URL(url).origin;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
export function objToReadableString(objs:
|
|
62
|
+
export function objToReadableString(objs: NavigationEntry[]) {
|
|
62
63
|
// Two spaces as indentation
|
|
63
64
|
return objs.map((obj) => JSON.stringify(obj, null, 2)).join(',\n');
|
|
64
65
|
}
|
package/src/types.d.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
type MintPage = {
|
|
2
|
-
title: string;
|
|
3
|
-
description?: string;
|
|
4
|
-
markdown?: string;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
type MintNavigation = {
|
|
8
|
-
group?: string;
|
|
9
|
-
version?: string;
|
|
10
|
-
pages: MintNavigationEntry[];
|
|
11
|
-
};
|
|
12
|
-
type MintNavigationEntry = string | MintNavigation;
|
|
13
|
-
|
|
14
|
-
type DecoratedMintNavigation = {
|
|
15
|
-
group: string;
|
|
16
|
-
version?: string;
|
|
17
|
-
pages: DecoratedMintNavigationEntry[];
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
type DecoratedMintNavigationEntry = DecoratedMintNavigation | PageMetadata;
|
|
21
|
-
|
|
22
|
-
type PageMetadata = Partial<Record<PageMetadataKeys, string>>;
|
|
23
|
-
|
|
24
|
-
const pageMetadataKeys = [
|
|
25
|
-
'title',
|
|
26
|
-
'description',
|
|
27
|
-
'sidebarTitle',
|
|
28
|
-
'href',
|
|
29
|
-
'api',
|
|
30
|
-
'openapi',
|
|
31
|
-
'contentType',
|
|
32
|
-
'auth',
|
|
33
|
-
'version',
|
|
34
|
-
'mode',
|
|
35
|
-
'hideFooterPagination',
|
|
36
|
-
'authors',
|
|
37
|
-
'lastUpdatedDate',
|
|
38
|
-
'createdDate',
|
|
39
|
-
'size',
|
|
40
|
-
] as const;
|
|
41
|
-
|
|
42
|
-
type PageMetadataKeys = (typeof pageMetadataKeys)[number];
|
|
43
|
-
|
|
44
|
-
type ScrapePageFn = (
|
|
45
|
-
html: string,
|
|
46
|
-
origin: string,
|
|
47
|
-
cliDir: string,
|
|
48
|
-
imageBaseDir: string,
|
|
49
|
-
overwrite: boolean,
|
|
50
|
-
version: string | undefined
|
|
51
|
-
) => Promise<MintPage>;
|
|
52
|
-
|
|
53
|
-
type ScrapeSectionFn = (
|
|
54
|
-
html: string,
|
|
55
|
-
origin: string,
|
|
56
|
-
cliDir: string,
|
|
57
|
-
imageBaseDir: string,
|
|
58
|
-
overwrite: boolean,
|
|
59
|
-
version: string | undefined
|
|
60
|
-
) => Promise<MintNavigationEntry[]>;
|
|
61
|
-
|
|
62
|
-
type OpenApiFile = {
|
|
63
|
-
filename: string;
|
|
64
|
-
spec: any;
|
|
65
|
-
};
|