@mintlify/scraping 4.0.1120 → 4.0.1121
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/scraping",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1121",
|
|
4
4
|
"description": "Scrape documentation frameworks to Mintlify docs",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"optional": true
|
|
88
88
|
}
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "985b3f5ae0bdfcb5260e478c6607592a674a6e2b"
|
|
91
91
|
}
|
|
@@ -7,7 +7,18 @@ import { removeHastComments } from '../../utils/hastComments.js';
|
|
|
7
7
|
import { hastToMdx, type RewriteLink } from '../convert.js';
|
|
8
8
|
import type { SdkNavGroup, SdkPage, SdkReference } from '../types.js';
|
|
9
9
|
|
|
10
|
-
type
|
|
10
|
+
type JavadocKind = 'interface' | 'class' | 'enum' | 'record' | 'exception' | 'error' | 'annotation';
|
|
11
|
+
type JavadocType = { pkg: string; name: string; file: string; slug: string; kind: JavadocKind };
|
|
12
|
+
|
|
13
|
+
const KINDS: { kind: JavadocKind; group: string; tag: string }[] = [
|
|
14
|
+
{ kind: 'interface', group: 'Interfaces', tag: 'INTERFACE' },
|
|
15
|
+
{ kind: 'class', group: 'Classes', tag: 'CLASS' },
|
|
16
|
+
{ kind: 'enum', group: 'Enums', tag: 'ENUM' },
|
|
17
|
+
{ kind: 'record', group: 'Records', tag: 'RECORD' },
|
|
18
|
+
{ kind: 'exception', group: 'Exceptions', tag: 'EXCEPTION' },
|
|
19
|
+
{ kind: 'error', group: 'Errors', tag: 'ERROR' },
|
|
20
|
+
{ kind: 'annotation', group: 'Annotations', tag: 'ANNOTATION' },
|
|
21
|
+
];
|
|
11
22
|
|
|
12
23
|
const TYPE_NAME_PATTERN = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)*$/;
|
|
13
24
|
const DROPPED_CLASSES = new Set([
|
|
@@ -24,12 +35,20 @@ export async function convertJavadoc(sourcePath: string): Promise<SdkReference>
|
|
|
24
35
|
throw new Error(`No javadoc types found in ${sourcePath}`);
|
|
25
36
|
}
|
|
26
37
|
const slugByFile = new Map(types.map((type) => [type.file, type.slug]));
|
|
38
|
+
const kindsByPackage = new Map<string, Map<string, JavadocKind>>();
|
|
27
39
|
|
|
28
40
|
const pages: SdkPage[] = [];
|
|
29
41
|
const byPackage = new Map<string, JavadocType[]>();
|
|
30
42
|
for (const type of types) {
|
|
31
43
|
const html = await fse.readFile(path.join(sourcePath, type.file), 'utf8');
|
|
32
|
-
|
|
44
|
+
let packageKinds = kindsByPackage.get(type.pkg);
|
|
45
|
+
if (!packageKinds) {
|
|
46
|
+
packageKinds = await readPackageKinds(sourcePath, type.pkg);
|
|
47
|
+
kindsByPackage.set(type.pkg, packageKinds);
|
|
48
|
+
}
|
|
49
|
+
const page = renderPage(type, html, slugByFile, packageKinds.get(type.name));
|
|
50
|
+
type.kind = page.kind;
|
|
51
|
+
pages.push(page);
|
|
33
52
|
const siblings = byPackage.get(type.pkg) ?? [];
|
|
34
53
|
siblings.push(type);
|
|
35
54
|
byPackage.set(type.pkg, siblings);
|
|
@@ -37,16 +56,85 @@ export async function convertJavadoc(sourcePath: string): Promise<SdkReference>
|
|
|
37
56
|
|
|
38
57
|
const groups: SdkNavGroup[] = [...byPackage.entries()]
|
|
39
58
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
40
|
-
.map(([pkg, members]) => ({
|
|
41
|
-
group: pkg,
|
|
42
|
-
pages: members
|
|
43
|
-
.sort((left, right) => left.name.localeCompare(right.name))
|
|
44
|
-
.map((member) => member.slug),
|
|
45
|
-
}));
|
|
59
|
+
.map(([pkg, members]) => ({ group: pkg, pages: packageEntries(members) }));
|
|
46
60
|
|
|
47
61
|
return { pages, groups };
|
|
48
62
|
}
|
|
49
63
|
|
|
64
|
+
function packageEntries(members: JavadocType[]): (string | SdkNavGroup)[] {
|
|
65
|
+
const sorted = [...members].sort((left, right) => left.name.localeCompare(right.name));
|
|
66
|
+
const buckets = KINDS.map((entry) => ({
|
|
67
|
+
group: entry.group,
|
|
68
|
+
pages: sorted.filter((member) => member.kind === entry.kind).map((member) => member.slug),
|
|
69
|
+
})).filter((bucket) => bucket.pages.length > 0);
|
|
70
|
+
if (buckets.length <= 1) return sorted.map((member) => member.slug);
|
|
71
|
+
return buckets;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function readPackageKinds(root: string, pkg: string): Promise<Map<string, JavadocKind>> {
|
|
75
|
+
const summaryPath = path.join(root, ...pkg.split('.'), 'package-summary.html');
|
|
76
|
+
if (!(await fse.pathExists(summaryPath))) return new Map();
|
|
77
|
+
const hast = htmlToHast(await fse.readFile(summaryPath, 'utf8'));
|
|
78
|
+
const kinds = new Map<string, JavadocKind>();
|
|
79
|
+
const record = (container: Element, kind: JavadocKind) => {
|
|
80
|
+
const cells = hasClass(container, 'col-first') || hasClass(container, 'colFirst');
|
|
81
|
+
visitElements(container, (el) => {
|
|
82
|
+
if (!cells && !hasClass(el, 'col-first') && !hasClass(el, 'colFirst')) return;
|
|
83
|
+
visitElements(el, (anchor) => recordAnchor(anchor, kind));
|
|
84
|
+
});
|
|
85
|
+
if (cells) visitElements(container, (anchor) => recordAnchor(anchor, kind));
|
|
86
|
+
};
|
|
87
|
+
const recordAnchor = (el: Element, kind: JavadocKind) => {
|
|
88
|
+
if (el.tagName !== 'a' || typeof el.properties.href !== 'string') return;
|
|
89
|
+
const href = el.properties.href.split(/[?#]/)[0] ?? '';
|
|
90
|
+
if (!href.endsWith('.html') || /^[a-z][a-z0-9+.-]*:/i.test(href)) return;
|
|
91
|
+
const name = path.posix.basename(href, '.html');
|
|
92
|
+
if (TYPE_NAME_PATTERN.test(name) && !kinds.has(name)) kinds.set(name, kind);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const kindByTab = new Map<string, JavadocKind>();
|
|
96
|
+
visitElements(hast, (el) => {
|
|
97
|
+
const id = el.properties?.id;
|
|
98
|
+
if (el.tagName !== 'button' || typeof id !== 'string' || !/^class-summary-tab\d+$/.test(id)) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const kind = kindFromLabel(textOf(el));
|
|
102
|
+
if (kind) kindByTab.set(id, kind);
|
|
103
|
+
});
|
|
104
|
+
if (kindByTab.size > 0) {
|
|
105
|
+
visitElements(hast, (el) => {
|
|
106
|
+
const tab = elementClasses(el).find((name) => kindByTab.has(name));
|
|
107
|
+
if (tab) record(el, kindByTab.get(tab) as JavadocKind);
|
|
108
|
+
});
|
|
109
|
+
return kinds;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
visitElements(hast, (el) => {
|
|
113
|
+
if (el.tagName !== 'table') return;
|
|
114
|
+
const caption = findElement(el, (child) => child.tagName === 'caption');
|
|
115
|
+
const kind = caption ? kindFromLabel(textOf(caption)) : undefined;
|
|
116
|
+
if (kind) record(el, kind);
|
|
117
|
+
});
|
|
118
|
+
return kinds;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function kindFromLabel(label: string): JavadocKind | undefined {
|
|
122
|
+
const text = label
|
|
123
|
+
.replace(/\u00a0/g, ' ')
|
|
124
|
+
.replace(/\s+/g, ' ')
|
|
125
|
+
.trim()
|
|
126
|
+
.toLowerCase();
|
|
127
|
+
if (text.startsWith('all ')) return undefined;
|
|
128
|
+
if (text.startsWith('interface')) return 'interface';
|
|
129
|
+
if (text.startsWith('class')) return 'class';
|
|
130
|
+
if (text.startsWith('enum')) return 'enum';
|
|
131
|
+
if (text.startsWith('record')) return 'record';
|
|
132
|
+
if (text.startsWith('exception')) return 'exception';
|
|
133
|
+
if (text.startsWith('error')) return 'error';
|
|
134
|
+
if (text.startsWith('annotation')) return 'annotation';
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
|
|
50
138
|
async function discoverTypes(root: string): Promise<JavadocType[]> {
|
|
51
139
|
const entries = (await typesFromSearchIndex(root)) ?? (await typesFromPackageDirs(root));
|
|
52
140
|
const seen = new Set<string>();
|
|
@@ -120,10 +208,16 @@ function makeType(pkg: string, name: string): JavadocType {
|
|
|
120
208
|
name,
|
|
121
209
|
file: `${pkg.split('.').join('/')}/${name}.html`,
|
|
122
210
|
slug: `${pkg.replace(/\./g, '-')}/${name}`,
|
|
211
|
+
kind: 'class',
|
|
123
212
|
};
|
|
124
213
|
}
|
|
125
214
|
|
|
126
|
-
function renderPage(
|
|
215
|
+
function renderPage(
|
|
216
|
+
type: JavadocType,
|
|
217
|
+
html: string,
|
|
218
|
+
slugByFile: Map<string, string>,
|
|
219
|
+
summaryKind: JavadocKind | undefined
|
|
220
|
+
): SdkPage & { kind: JavadocKind } {
|
|
127
221
|
const hast = htmlToHast(html);
|
|
128
222
|
removeHastComments(hast);
|
|
129
223
|
const main =
|
|
@@ -138,7 +232,8 @@ function renderPage(type: JavadocType, html: string, slugByFile: Map<string, str
|
|
|
138
232
|
const details = findElement(main, (el) => hasClass(el, 'details'));
|
|
139
233
|
|
|
140
234
|
const description = extractDescription(declaration);
|
|
141
|
-
const
|
|
235
|
+
const kind = summaryKind ?? kindFromHeading(main);
|
|
236
|
+
const tag = KINDS.find((entry) => entry.kind === kind)?.tag ?? 'CLASS';
|
|
142
237
|
|
|
143
238
|
const kept = [declaration, details].filter((node): node is Element => node !== undefined);
|
|
144
239
|
const anchors = collectDetailAnchors(kept);
|
|
@@ -159,7 +254,7 @@ function renderPage(type: JavadocType, html: string, slugByFile: Map<string, str
|
|
|
159
254
|
.join(`\`\`\`java\n${signature}\n\`\`\``);
|
|
160
255
|
}
|
|
161
256
|
|
|
162
|
-
return { slug: type.slug, title: type.name, description, tag, content };
|
|
257
|
+
return { slug: type.slug, title: type.name, description, tag, content, kind };
|
|
163
258
|
}
|
|
164
259
|
|
|
165
260
|
function makeHrefResolver(
|
|
@@ -269,13 +364,14 @@ function codifySignatures(node: Element): string[] {
|
|
|
269
364
|
return signatures;
|
|
270
365
|
}
|
|
271
366
|
|
|
272
|
-
function
|
|
367
|
+
function kindFromHeading(scope: Element | HastRoot): JavadocKind {
|
|
273
368
|
const heading = findElement(scope, (el) => el.tagName === 'h1');
|
|
274
369
|
const title = heading ? textOf(heading).trim() : '';
|
|
275
|
-
if (title.startsWith('Annotation')) return '
|
|
276
|
-
if (title.startsWith('Enum')) return '
|
|
277
|
-
if (title.startsWith('Interface')) return '
|
|
278
|
-
return '
|
|
370
|
+
if (title.startsWith('Annotation')) return 'annotation';
|
|
371
|
+
if (title.startsWith('Enum')) return 'enum';
|
|
372
|
+
if (title.startsWith('Interface')) return 'interface';
|
|
373
|
+
if (title.startsWith('Record')) return 'record';
|
|
374
|
+
return 'class';
|
|
279
375
|
}
|
|
280
376
|
|
|
281
377
|
function extractDescription(declaration: Element | undefined): string | undefined {
|