@mintlify/scraping 4.0.1242 → 4.0.1244
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__/sdk-docfx.test.ts +38 -0
- package/__test__/sdk-phpdoc.test.ts +2 -3
- package/__test__/sdk-typedoc.test.ts +184 -3
- package/bin/sdk/converters/docfx.js +16 -0
- package/bin/sdk/converters/docfx.js.map +1 -1
- package/bin/sdk/converters/phpdoc.js +7 -4
- package/bin/sdk/converters/phpdoc.js.map +1 -1
- package/bin/sdk/converters/typedoc.js +94 -26
- package/bin/sdk/converters/typedoc.js.map +1 -1
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/sdk/converters/docfx.ts +23 -0
- package/src/sdk/converters/phpdoc.ts +10 -4
- package/src/sdk/converters/typedoc.ts +130 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/scraping",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1244",
|
|
4
4
|
"description": "Scrape documentation frameworks to Mintlify docs",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"format:check": "oxfmt --check"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@mintlify/common": "1.0.
|
|
46
|
+
"@mintlify/common": "1.0.1361",
|
|
47
47
|
"fast-xml-parser": "5.7.3",
|
|
48
48
|
"fs-extra": "11.1.1",
|
|
49
49
|
"graphql": "16.11.0",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"zod": "3.24.0"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@mintlify/models": "0.0.
|
|
65
|
+
"@mintlify/models": "0.0.393",
|
|
66
66
|
"@mintlify/ts-config": "2.0.2",
|
|
67
|
-
"@mintlify/validation": "0.1.
|
|
67
|
+
"@mintlify/validation": "0.1.971",
|
|
68
68
|
"@tsconfig/recommended": "1.0.2",
|
|
69
69
|
"@types/hast": "3.0.4",
|
|
70
70
|
"@types/mdast": "4.0.4",
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"optional": true
|
|
88
88
|
}
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "3b7270d4371e9e7e3370bc6c7341ffbc82346f59"
|
|
91
91
|
}
|
|
@@ -26,10 +26,14 @@ type DocfxItem = {
|
|
|
26
26
|
remarks?: string;
|
|
27
27
|
example?: string[];
|
|
28
28
|
syntax?: DocfxSyntax;
|
|
29
|
+
inheritance?: string[];
|
|
30
|
+
implements?: string[];
|
|
29
31
|
};
|
|
30
32
|
type DocfxFile = { items?: DocfxItem[]; references?: { uid?: string; name?: string }[] };
|
|
31
33
|
type TocNode = { uid?: string; type?: string; items?: TocNode[] };
|
|
32
34
|
|
|
35
|
+
const ROOT_BASE_TYPES = new Set(['System.Object', 'System.ValueType', 'System.Enum']);
|
|
36
|
+
|
|
33
37
|
const PAGE_TAGS: Record<string, string> = {
|
|
34
38
|
Class: 'CLASS',
|
|
35
39
|
Interface: 'INTERFACE',
|
|
@@ -198,6 +202,7 @@ class DocfxRenderer {
|
|
|
198
202
|
renderPage(item: DocfxItem): SdkPage {
|
|
199
203
|
const lines: string[] = [this.prose(item.summary)];
|
|
200
204
|
if (item.syntax?.content) lines.push(this.codeBlock(item.syntax.content));
|
|
205
|
+
lines.push(...this.renderHeritage(item));
|
|
201
206
|
lines.push(this.prose(item.remarks));
|
|
202
207
|
lines.push(...(item.example ?? []).map((example) => this.renderExample(example)));
|
|
203
208
|
|
|
@@ -268,6 +273,24 @@ class DocfxRenderer {
|
|
|
268
273
|
return lines;
|
|
269
274
|
}
|
|
270
275
|
|
|
276
|
+
private renderHeritage(item: DocfxItem): string[] {
|
|
277
|
+
const parent = item.inheritance?.at(-1);
|
|
278
|
+
return [
|
|
279
|
+
{
|
|
280
|
+
label: 'Extends',
|
|
281
|
+
uids: parent && !ROOT_BASE_TYPES.has(parent) ? [parent] : [],
|
|
282
|
+
},
|
|
283
|
+
{ label: 'Implements', uids: item.implements ?? [] },
|
|
284
|
+
]
|
|
285
|
+
.filter(({ uids }) => uids.length)
|
|
286
|
+
.map(
|
|
287
|
+
({ label, uids }) =>
|
|
288
|
+
`**${label}:** ${uids
|
|
289
|
+
.map((uid) => linkedCode(this.typeTokens(uid)) ?? inlineCode(this.typeName(uid)))
|
|
290
|
+
.join(', ')}`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
271
294
|
private renderEnum(item: DocfxItem): string[] {
|
|
272
295
|
const lines: string[] = ['## Members'];
|
|
273
296
|
for (const member of this.members(item).filter((child) => child.type === 'Field')) {
|
|
@@ -286,15 +286,21 @@ class PhpdocRenderer {
|
|
|
286
286
|
private renderHeritage(entry: Entry): string[] {
|
|
287
287
|
const { element } = entry;
|
|
288
288
|
const heritage = [
|
|
289
|
-
element.extends ?
|
|
290
|
-
|
|
291
|
-
].filter(
|
|
289
|
+
{ label: 'Extends', types: element.extends ? [element.extends] : [] },
|
|
290
|
+
{ label: 'Implements', types: element.implements ?? [] },
|
|
291
|
+
].filter(({ types }) => types.length);
|
|
292
292
|
if (!heritage.length) return [];
|
|
293
293
|
const modifiers = [
|
|
294
294
|
element['@_abstract'] === 'true' ? 'abstract' : '',
|
|
295
295
|
element['@_final'] === 'true' ? 'final' : '',
|
|
296
296
|
].filter(Boolean);
|
|
297
|
-
return [
|
|
297
|
+
return [
|
|
298
|
+
this.codeBlock([...modifiers, entry.keyword, entry.name].join(' ')),
|
|
299
|
+
...heritage.map(
|
|
300
|
+
({ label, types }) =>
|
|
301
|
+
`**${label}:** ${types.map((type) => linkedCode(this.typeTokens(type)) ?? inlineCode(type)).join(', ')}`
|
|
302
|
+
),
|
|
303
|
+
];
|
|
298
304
|
}
|
|
299
305
|
|
|
300
306
|
private renderMethodBody(method: PhpMethod, depth: number): string[] {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { cachedSlugify, slugify as headingSlug } from '@mintlify/common';
|
|
1
2
|
import type { SdkSymbolKind } from '@mintlify/models';
|
|
2
3
|
import fse from 'fs-extra';
|
|
3
4
|
import path from 'node:path';
|
|
@@ -120,6 +121,16 @@ const SECTIONS: {
|
|
|
120
121
|
const MAX_PLACEMENTS_PER_PAGE = 8;
|
|
121
122
|
const MAX_DECLARATION_NAME_LENGTH = 512;
|
|
122
123
|
|
|
124
|
+
const FIELD_MEMBER_KINDS = new Set<number>([KIND.property, KIND.accessor]);
|
|
125
|
+
|
|
126
|
+
function memberAnchor(member: TypedocNode, inEnum: boolean): string | undefined {
|
|
127
|
+
if (inEnum || FIELD_MEMBER_KINDS.has(member.kind)) {
|
|
128
|
+
return cachedSlugify(`${inEnum ? 'member' : 'property'}-${member.name}`, { decamelize: true });
|
|
129
|
+
}
|
|
130
|
+
if (member.kind === KIND.method) return headingSlug(`${member.name}()`);
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
|
|
123
134
|
const MEMBER_KINDS = new Set<number>([KIND.constructor, KIND.property, KIND.accessor, KIND.method]);
|
|
124
135
|
|
|
125
136
|
const DEFAULT_GROUP_TITLE_BY_KIND = new Map<number, string>([
|
|
@@ -164,7 +175,20 @@ export async function convertTypedoc(sourcePath: string): Promise<SdkReference>
|
|
|
164
175
|
}
|
|
165
176
|
}
|
|
166
177
|
|
|
167
|
-
const
|
|
178
|
+
const memberSlugById = new Map<number, string>();
|
|
179
|
+
for (const module of modules) {
|
|
180
|
+
for (const { node } of collectDeclarations(module)) {
|
|
181
|
+
const slug = slugById.get(node.id);
|
|
182
|
+
if (!slug) continue;
|
|
183
|
+
for (const child of node.children ?? []) {
|
|
184
|
+
if (child.flags?.isPrivate) continue;
|
|
185
|
+
const anchor = memberAnchor(child, node.kind === KIND.enum);
|
|
186
|
+
if (anchor) memberSlugById.set(child.id, `${slug}#${anchor}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const renderer = new TypedocRenderer(slugById, memberSlugById);
|
|
168
192
|
const pages: SdkPage[] = [];
|
|
169
193
|
const groups: SdkNavGroup[] = [];
|
|
170
194
|
const moduleGroupById = new Map<number, PathNavGroup>();
|
|
@@ -353,7 +377,10 @@ function slugify(name: string): string {
|
|
|
353
377
|
}
|
|
354
378
|
|
|
355
379
|
class TypedocRenderer {
|
|
356
|
-
constructor(
|
|
380
|
+
constructor(
|
|
381
|
+
private slugById: Map<number, string>,
|
|
382
|
+
private memberSlugById = new Map<number, string>()
|
|
383
|
+
) {}
|
|
357
384
|
|
|
358
385
|
renderOverview(node: TypedocNode, slug: string, pages: SdkPage[], namespace?: string): SdkPage {
|
|
359
386
|
const tree = parseSdkReadme(this.partsMarkdown(node.readme ?? []));
|
|
@@ -461,22 +488,15 @@ class TypedocRenderer {
|
|
|
461
488
|
}
|
|
462
489
|
|
|
463
490
|
private renderClassLike(node: TypedocNode): string[] {
|
|
464
|
-
const lines
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
];
|
|
473
|
-
if (heritage.length) {
|
|
474
|
-
lines.push(
|
|
475
|
-
this.codeBlock(
|
|
476
|
-
`${node.kind === KIND.class ? 'class' : 'interface'} ${node.name} ${heritage.join(' ')}`
|
|
477
|
-
)
|
|
491
|
+
const lines = [
|
|
492
|
+
{ label: 'Extends', types: node.extendedTypes },
|
|
493
|
+
{ label: 'Implements', types: node.implementedTypes },
|
|
494
|
+
]
|
|
495
|
+
.filter(({ types }) => types?.length)
|
|
496
|
+
.map(
|
|
497
|
+
({ label, types }) =>
|
|
498
|
+
`**${label}:** ${(types ?? []).map((type) => this.linkedOrCode(type)).join(', ')}`
|
|
478
499
|
);
|
|
479
|
-
}
|
|
480
500
|
|
|
481
501
|
const members = (node.children ?? []).filter((child) => !child.flags?.isPrivate);
|
|
482
502
|
const layout = this.memberLayout(node, members);
|
|
@@ -559,7 +579,8 @@ class TypedocRenderer {
|
|
|
559
579
|
property.name,
|
|
560
580
|
type,
|
|
561
581
|
property.flags?.isOptional === true,
|
|
562
|
-
this.comment(property.comment ?? property.getSignature?.comment)
|
|
582
|
+
this.comment(property.comment ?? property.getSignature?.comment),
|
|
583
|
+
memberAnchor(property, false)
|
|
563
584
|
)
|
|
564
585
|
);
|
|
565
586
|
}
|
|
@@ -578,7 +599,9 @@ class TypedocRenderer {
|
|
|
578
599
|
member.name,
|
|
579
600
|
member.type?.type === 'literal' ? JSON.stringify(member.type.value) : '',
|
|
580
601
|
false,
|
|
581
|
-
this.comment(member.comment)
|
|
602
|
+
this.comment(member.comment),
|
|
603
|
+
undefined,
|
|
604
|
+
memberAnchor(member, true)
|
|
582
605
|
)
|
|
583
606
|
);
|
|
584
607
|
}
|
|
@@ -586,15 +609,11 @@ class TypedocRenderer {
|
|
|
586
609
|
}
|
|
587
610
|
|
|
588
611
|
private renderSignatures(node: TypedocNode, depth: number): string[] {
|
|
612
|
+
const signatures = node.signatures ?? [];
|
|
613
|
+
if (signatures.length > 1) return this.renderOverloads(signatures, depth);
|
|
589
614
|
const lines: string[] = [];
|
|
590
|
-
for (const signature of
|
|
591
|
-
|
|
592
|
-
.map(
|
|
593
|
-
(param) =>
|
|
594
|
-
`${param.name}${param.flags?.isOptional || param.defaultValue !== undefined ? '?' : ''}: ${this.type(param.type)}`
|
|
595
|
-
)
|
|
596
|
-
.join(', ');
|
|
597
|
-
lines.push(this.codeBlock(`${signature.name}(${params}): ${this.type(signature.type)}`));
|
|
615
|
+
for (const signature of signatures) {
|
|
616
|
+
lines.push(this.codeBlock(this.signatureLine(signature)));
|
|
598
617
|
const comment = this.comment(signature.comment);
|
|
599
618
|
if (comment) lines.push(comment);
|
|
600
619
|
if (signature.parameters?.length) {
|
|
@@ -621,18 +640,91 @@ class TypedocRenderer {
|
|
|
621
640
|
return lines;
|
|
622
641
|
}
|
|
623
642
|
|
|
643
|
+
private renderOverloads(signatures: TypedocNode[], depth: number): string[] {
|
|
644
|
+
const lines = [
|
|
645
|
+
this.codeBlock(signatures.map((signature) => this.signatureLine(signature)).join('\n')),
|
|
646
|
+
...distinct(signatures.map((signature) => this.comment(signature.comment))),
|
|
647
|
+
];
|
|
648
|
+
|
|
649
|
+
const names = distinct(
|
|
650
|
+
signatures.flatMap((signature) => (signature.parameters ?? []).map((param) => param.name))
|
|
651
|
+
);
|
|
652
|
+
if (names.length) lines.push(detailHeading('Parameters', depth));
|
|
653
|
+
for (const name of names) {
|
|
654
|
+
const params = signatures.map((signature) =>
|
|
655
|
+
signature.parameters?.find((param) => param.name === name)
|
|
656
|
+
);
|
|
657
|
+
const present = params.filter((param) => param !== undefined);
|
|
658
|
+
const optional = params.some(
|
|
659
|
+
(param) => !param || param.flags?.isOptional === true || param.defaultValue !== undefined
|
|
660
|
+
);
|
|
661
|
+
const body = distinct(present.map((param) => this.comment(param.comment))).join('\n\n');
|
|
662
|
+
const types = this.distinctTypes(present.map((param) => param.type));
|
|
663
|
+
const [only] = types;
|
|
664
|
+
if (types.length === 1) {
|
|
665
|
+
lines.push(this.typeField(name, only, optional, body));
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
const variants = types.map((type) => `- ${this.linkedOrCode(type)}`).join('\n');
|
|
669
|
+
lines.push(
|
|
670
|
+
responseField(
|
|
671
|
+
name,
|
|
672
|
+
types.map((type) => this.type(type)).join(' | '),
|
|
673
|
+
optional,
|
|
674
|
+
[`**Type:** one of\n\n${variants}`, body].filter(Boolean).join('\n\n')
|
|
675
|
+
)
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
const returnTypes = this.distinctTypes(signatures.map((signature) => signature.type)).filter(
|
|
680
|
+
(type) => this.type(type) !== 'void'
|
|
681
|
+
);
|
|
682
|
+
if (returnTypes.length) {
|
|
683
|
+
lines.push(
|
|
684
|
+
detailHeading('Returns', depth),
|
|
685
|
+
returnTypes.map((type) => this.linkedOrCode(type)).join(' | '),
|
|
686
|
+
...distinct(
|
|
687
|
+
signatures.map((signature) => {
|
|
688
|
+
const returns = signature.comment?.blockTags?.find((tag) => tag.tag === '@returns');
|
|
689
|
+
return returns ? this.parts(returns.content) : '';
|
|
690
|
+
})
|
|
691
|
+
)
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
return lines;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
private distinctTypes(types: (TypedocType | undefined)[]): (TypedocType | undefined)[] {
|
|
698
|
+
return [...new Map(types.map((type) => [this.linkedOrCode(type), type])).values()];
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
private signatureLine(signature: TypedocNode): string {
|
|
702
|
+
const params = (signature.parameters ?? [])
|
|
703
|
+
.map(
|
|
704
|
+
(param) =>
|
|
705
|
+
`${param.name}${param.flags?.isOptional || param.defaultValue !== undefined ? '?' : ''}: ${this.type(param.type)}`
|
|
706
|
+
)
|
|
707
|
+
.join(', ');
|
|
708
|
+
return `${signature.name}(${params}): ${this.type(signature.type)}`;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
private linkedOrCode(type?: TypedocType): string {
|
|
712
|
+
return this.linkedType(type) ?? inlineCode(this.type(type));
|
|
713
|
+
}
|
|
714
|
+
|
|
624
715
|
private typeField(
|
|
625
716
|
name: string,
|
|
626
717
|
type: TypedocType | undefined,
|
|
627
718
|
optional: boolean,
|
|
628
|
-
body?: string
|
|
719
|
+
body?: string,
|
|
720
|
+
id?: string
|
|
629
721
|
): string {
|
|
630
722
|
const tokens = this.typeTokens(type);
|
|
631
723
|
const [only] = tokens;
|
|
632
724
|
const typeHref = tokens.length === 1 && only?.href ? `/${only.href}` : undefined;
|
|
633
725
|
const linked = typeHref ? undefined : this.linkedType(type);
|
|
634
726
|
const content = [linked && `**Type:** ${linked}`, body].filter(Boolean).join('\n\n');
|
|
635
|
-
return responseField(name, this.type(type), optional, content, typeHref);
|
|
727
|
+
return responseField(name, this.type(type), optional, content, typeHref, id);
|
|
636
728
|
}
|
|
637
729
|
|
|
638
730
|
private codeBlock(code: string): string {
|
|
@@ -661,9 +753,11 @@ class TypedocRenderer {
|
|
|
661
753
|
return parts
|
|
662
754
|
.map((part) => {
|
|
663
755
|
if (part.kind === 'inline-tag') {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
756
|
+
const slug =
|
|
757
|
+
typeof part.target === 'number'
|
|
758
|
+
? (this.slugById.get(part.target) ?? this.memberSlugById.get(part.target))
|
|
759
|
+
: undefined;
|
|
760
|
+
if (slug) return `[${part.text}](/${slug})`;
|
|
667
761
|
if (typeof part.target === 'string') return `[${part.text}](${part.target})`;
|
|
668
762
|
return `\`${part.text}\``;
|
|
669
763
|
}
|
|
@@ -790,3 +884,7 @@ function headingText(title: unknown): string {
|
|
|
790
884
|
function detailHeading(title: string, depth: number): string {
|
|
791
885
|
return depth <= MAX_HEADING_DEPTH ? `${'#'.repeat(depth)} ${title}` : `**${title}**`;
|
|
792
886
|
}
|
|
887
|
+
|
|
888
|
+
function distinct(items: string[]): string[] {
|
|
889
|
+
return [...new Set(items)].filter(Boolean);
|
|
890
|
+
}
|