@apify/docusaurus-plugin-typedoc-api 3.0.0
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/LICENSE +21 -0
- package/README.md +290 -0
- package/assets/styles-8ad572ec.css +303 -0
- package/lib/components/AnchorLink.js +22 -0
- package/lib/components/AnchorLink.js.map +1 -0
- package/lib/components/ApiChangelog.js +28 -0
- package/lib/components/ApiChangelog.js.map +1 -0
- package/lib/components/ApiDataContext.js +16 -0
- package/lib/components/ApiDataContext.js.map +1 -0
- package/lib/components/ApiIndex.js +80 -0
- package/lib/components/ApiIndex.js.map +1 -0
- package/lib/components/ApiItem.js +86 -0
- package/lib/components/ApiItem.js.map +1 -0
- package/lib/components/ApiItemLayout.js +69 -0
- package/lib/components/ApiItemLayout.js.map +1 -0
- package/lib/components/ApiPage.js +69 -0
- package/lib/components/ApiPage.js.map +1 -0
- package/lib/components/Breadcrumb.js +38 -0
- package/lib/components/Breadcrumb.js.map +1 -0
- package/lib/components/Comment.js +56 -0
- package/lib/components/Comment.js.map +1 -0
- package/lib/components/CommentBadges.js +35 -0
- package/lib/components/CommentBadges.js.map +1 -0
- package/lib/components/DefaultValue.js +49 -0
- package/lib/components/DefaultValue.js.map +1 -0
- package/lib/components/Flags.js +27 -0
- package/lib/components/Flags.js.map +1 -0
- package/lib/components/Footer.js +18 -0
- package/lib/components/Footer.js.map +1 -0
- package/lib/components/Hierarchy.js +27 -0
- package/lib/components/Hierarchy.js.map +1 -0
- package/lib/components/Icon.js +27 -0
- package/lib/components/Icon.js.map +1 -0
- package/lib/components/Index.js +87 -0
- package/lib/components/Index.js.map +1 -0
- package/lib/components/Markdown.js +204 -0
- package/lib/components/Markdown.js.map +1 -0
- package/lib/components/Member.js +68 -0
- package/lib/components/Member.js.map +1 -0
- package/lib/components/MemberDeclaration.js +64 -0
- package/lib/components/MemberDeclaration.js.map +1 -0
- package/lib/components/MemberGetterSetter.js +61 -0
- package/lib/components/MemberGetterSetter.js.map +1 -0
- package/lib/components/MemberReference.js +38 -0
- package/lib/components/MemberReference.js.map +1 -0
- package/lib/components/MemberSignatureBody.js +91 -0
- package/lib/components/MemberSignatureBody.js.map +1 -0
- package/lib/components/MemberSignatureTitle.js +52 -0
- package/lib/components/MemberSignatureTitle.js.map +1 -0
- package/lib/components/MemberSignatures.js +61 -0
- package/lib/components/MemberSignatures.js.map +1 -0
- package/lib/components/MemberSources.js +33 -0
- package/lib/components/MemberSources.js.map +1 -0
- package/lib/components/Members.js +51 -0
- package/lib/components/Members.js.map +1 -0
- package/lib/components/MembersGroup.js +39 -0
- package/lib/components/MembersGroup.js.map +1 -0
- package/lib/components/Parameter.js +145 -0
- package/lib/components/Parameter.js.map +1 -0
- package/lib/components/Reflection.js +112 -0
- package/lib/components/Reflection.js.map +1 -0
- package/lib/components/SourceLink.js +37 -0
- package/lib/components/SourceLink.js.map +1 -0
- package/lib/components/Type.js +341 -0
- package/lib/components/Type.js.map +1 -0
- package/lib/components/TypeAndParent.js +27 -0
- package/lib/components/TypeAndParent.js.map +1 -0
- package/lib/components/TypeParameters.js +36 -0
- package/lib/components/TypeParameters.js.map +1 -0
- package/lib/components/TypeParametersGeneric.js +27 -0
- package/lib/components/TypeParametersGeneric.js.map +1 -0
- package/lib/components/VersionBanner.js +39 -0
- package/lib/components/VersionBanner.js.map +1 -0
- package/lib/hooks/useBreadcrumbs.js +9 -0
- package/lib/hooks/useBreadcrumbs.js.map +1 -0
- package/lib/hooks/useGitRefName.js +9 -0
- package/lib/hooks/useGitRefName.js.map +1 -0
- package/lib/hooks/useMinimalLayout.js +9 -0
- package/lib/hooks/useMinimalLayout.js.map +1 -0
- package/lib/hooks/useReflection.js +19 -0
- package/lib/hooks/useReflection.js.map +1 -0
- package/lib/hooks/useReflectionMap.js +9 -0
- package/lib/hooks/useReflectionMap.js.map +1 -0
- package/lib/index.js +320 -0
- package/lib/index.js.map +1 -0
- package/lib/markdownLoader.js +11 -0
- package/lib/markdownLoader.js.map +1 -0
- package/lib/plugin/data.js +332 -0
- package/lib/plugin/data.js.map +1 -0
- package/lib/plugin/sidebar.js +105 -0
- package/lib/plugin/sidebar.js.map +1 -0
- package/lib/plugin/structure/0.23.js +48 -0
- package/lib/plugin/structure/0.23.js.map +1 -0
- package/lib/plugin/url.js +49 -0
- package/lib/plugin/url.js.map +1 -0
- package/lib/plugin/version.js +83 -0
- package/lib/plugin/version.js.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/utils/hierarchy.js +35 -0
- package/lib/utils/hierarchy.js.map +1 -0
- package/lib/utils/icons.js +124 -0
- package/lib/utils/icons.js.map +1 -0
- package/lib/utils/links.js +10 -0
- package/lib/utils/links.js.map +1 -0
- package/lib/utils/markdown.js +69 -0
- package/lib/utils/markdown.js.map +1 -0
- package/lib/utils/visibility.js +25 -0
- package/lib/utils/visibility.js.map +1 -0
- package/package.json +57 -0
- package/src/components/AnchorLink.tsx +14 -0
- package/src/components/ApiChangelog.tsx +26 -0
- package/src/components/ApiDataContext.ts +17 -0
- package/src/components/ApiIndex.tsx +109 -0
- package/src/components/ApiItem.tsx +110 -0
- package/src/components/ApiItemLayout.tsx +96 -0
- package/src/components/ApiPage.tsx +78 -0
- package/src/components/Breadcrumb.tsx +41 -0
- package/src/components/Comment.tsx +74 -0
- package/src/components/CommentBadges.tsx +40 -0
- package/src/components/DefaultValue.tsx +48 -0
- package/src/components/Flags.tsx +29 -0
- package/src/components/Footer.tsx +13 -0
- package/src/components/Hierarchy.tsx +27 -0
- package/src/components/Icon.tsx +20 -0
- package/src/components/Index.tsx +109 -0
- package/src/components/Markdown.tsx +241 -0
- package/src/components/Member.tsx +64 -0
- package/src/components/MemberDeclaration.tsx +67 -0
- package/src/components/MemberGetterSetter.tsx +69 -0
- package/src/components/MemberReference.tsx +43 -0
- package/src/components/MemberSignatureBody.tsx +121 -0
- package/src/components/MemberSignatureTitle.tsx +65 -0
- package/src/components/MemberSignatures.tsx +64 -0
- package/src/components/MemberSources.tsx +42 -0
- package/src/components/Members.tsx +62 -0
- package/src/components/MembersGroup.tsx +47 -0
- package/src/components/Parameter.tsx +165 -0
- package/src/components/README.md +9 -0
- package/src/components/Reflection.tsx +136 -0
- package/src/components/SourceLink.tsx +46 -0
- package/src/components/Type.tsx +377 -0
- package/src/components/TypeAndParent.tsx +26 -0
- package/src/components/TypeParameters.tsx +37 -0
- package/src/components/TypeParametersGeneric.tsx +25 -0
- package/src/components/VersionBanner.tsx +44 -0
- package/src/components/styles.css +303 -0
- package/src/hooks/useBreadcrumbs.ts +6 -0
- package/src/hooks/useGitRefName.ts +6 -0
- package/src/hooks/useMinimalLayout.ts +6 -0
- package/src/hooks/useReflection.ts +18 -0
- package/src/hooks/useReflectionMap.ts +7 -0
- package/src/index.ts +420 -0
- package/src/markdownLoader.ts +10 -0
- package/src/plugin/data.ts +389 -0
- package/src/plugin/sidebar.ts +139 -0
- package/src/plugin/structure/0.23.ts +58 -0
- package/src/plugin/url.ts +49 -0
- package/src/plugin/version.ts +118 -0
- package/src/types.ts +165 -0
- package/src/utils/hierarchy.ts +46 -0
- package/src/utils/icons.ts +103 -0
- package/src/utils/links.ts +10 -0
- package/src/utils/markdown.ts +82 -0
- package/src/utils/visibility.ts +31 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import * as TypeDoc from 'typedoc';
|
|
4
|
+
import { JSONOutput, ReflectionKind } from 'typedoc';
|
|
5
|
+
import ts from 'typescript';
|
|
6
|
+
import { normalizeUrl } from '@docusaurus/utils';
|
|
7
|
+
import type {
|
|
8
|
+
DeclarationReflectionMap,
|
|
9
|
+
DocusaurusPluginTypeDocApiOptions,
|
|
10
|
+
PackageReflectionGroup,
|
|
11
|
+
ResolvedPackageConfig,
|
|
12
|
+
} from '../types';
|
|
13
|
+
import { migrateToVersion0230 } from './structure/0.23';
|
|
14
|
+
import { getKindSlug, getPackageSlug, joinUrl } from './url';
|
|
15
|
+
|
|
16
|
+
function shouldEmit(projectRoot: string, tsconfigPath: string) {
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
18
|
+
const { config, error } = ts.readConfigFile(tsconfigPath, (name) =>
|
|
19
|
+
fs.readFileSync(name, 'utf8'),
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if (error) {
|
|
23
|
+
throw new Error(`Failed to load ${tsconfigPath}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const result = ts.parseJsonConfigFileContent(config, ts.sys, projectRoot, {}, tsconfigPath);
|
|
27
|
+
|
|
28
|
+
if (result.errors.length > 0) {
|
|
29
|
+
throw new Error(`Failed to parse ${tsconfigPath}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result.projectReferences && result.projectReferences.length > 0 ? 'docs' : 'none';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Persist build state as a global, since the plugin is re-evaluated every hot reload.
|
|
36
|
+
// Because of this, we can't use state in the plugin or module scope.
|
|
37
|
+
if (!global.typedocBuild) {
|
|
38
|
+
global.typedocBuild = { count: 0 };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function generateJson(
|
|
42
|
+
projectRoot: string,
|
|
43
|
+
entryPoints: string[],
|
|
44
|
+
outFile: string,
|
|
45
|
+
options: DocusaurusPluginTypeDocApiOptions,
|
|
46
|
+
): Promise<boolean> {
|
|
47
|
+
/* eslint-disable sort-keys */
|
|
48
|
+
|
|
49
|
+
// Running the TypeDoc compiler is pretty slow...
|
|
50
|
+
// We should only load on the 1st build, and use cache for subsequent reloads.
|
|
51
|
+
if (global.typedocBuild.count > 0 && fs.existsSync(outFile)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const app = new TypeDoc.Application();
|
|
56
|
+
const tsconfig = path.join(projectRoot, options.tsconfigName!);
|
|
57
|
+
|
|
58
|
+
app.options.addReader(new TypeDoc.TSConfigReader());
|
|
59
|
+
app.options.addReader(new TypeDoc.TypeDocReader());
|
|
60
|
+
|
|
61
|
+
app.bootstrap({
|
|
62
|
+
skipErrorChecking: true,
|
|
63
|
+
// Only emit when using project references
|
|
64
|
+
emit: shouldEmit(projectRoot, tsconfig),
|
|
65
|
+
// Only document the public API by default
|
|
66
|
+
excludeExternals: true,
|
|
67
|
+
excludeInternal: true,
|
|
68
|
+
excludePrivate: true,
|
|
69
|
+
excludeProtected: true,
|
|
70
|
+
// Enable verbose logging when debugging
|
|
71
|
+
logLevel: options.debug ? 'Verbose' : 'Info',
|
|
72
|
+
inlineTags: [
|
|
73
|
+
'@link',
|
|
74
|
+
'@inheritDoc',
|
|
75
|
+
'@label',
|
|
76
|
+
'@linkcode',
|
|
77
|
+
'@linkplain',
|
|
78
|
+
'@apilink',
|
|
79
|
+
'@doclink',
|
|
80
|
+
] as `@${string}`[],
|
|
81
|
+
...options.typedocOptions,
|
|
82
|
+
// Control how config and packages are detected
|
|
83
|
+
tsconfig,
|
|
84
|
+
entryPoints: entryPoints.map((ep) => path.join(projectRoot, ep)),
|
|
85
|
+
entryPointStrategy: 'expand',
|
|
86
|
+
exclude: options.exclude,
|
|
87
|
+
// We use a fake category title so that we can fallback to the parent group
|
|
88
|
+
defaultCategory: 'CATEGORY',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const project = app.convert();
|
|
92
|
+
|
|
93
|
+
if (project) {
|
|
94
|
+
await app.generateJson(project, outFile);
|
|
95
|
+
|
|
96
|
+
global.typedocBuild.count += 1;
|
|
97
|
+
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function createReflectionMap(
|
|
105
|
+
items: JSONOutput.DeclarationReflection[] = [],
|
|
106
|
+
): DeclarationReflectionMap {
|
|
107
|
+
const map: DeclarationReflectionMap = {};
|
|
108
|
+
|
|
109
|
+
items.forEach((item) => {
|
|
110
|
+
map[item.id] = item;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return map;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function loadPackageJsonAndDocs(
|
|
117
|
+
initialDir: string,
|
|
118
|
+
pkgFileName: string = 'package.json',
|
|
119
|
+
readmeFileName: string = 'README.md',
|
|
120
|
+
changelogFileName: string = 'CHANGELOG.md',
|
|
121
|
+
) {
|
|
122
|
+
let currentDir = initialDir;
|
|
123
|
+
|
|
124
|
+
while (!fs.existsSync(path.join(currentDir, pkgFileName))) {
|
|
125
|
+
currentDir = path.dirname(currentDir);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const readmePath = path.join(currentDir, readmeFileName);
|
|
129
|
+
const changelogPath = path.join(currentDir, changelogFileName);
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
packageJson: JSON.parse(fs.readFileSync(path.join(currentDir, pkgFileName), 'utf8')) as {
|
|
133
|
+
name: string;
|
|
134
|
+
version: string;
|
|
135
|
+
},
|
|
136
|
+
readmePath: fs.existsSync(readmePath) ? readmePath : '',
|
|
137
|
+
changelogPath: fs.existsSync(changelogPath) ? changelogPath : '',
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function addMetadataToReflections(
|
|
142
|
+
project: JSONOutput.ProjectReflection,
|
|
143
|
+
packageSlug: string,
|
|
144
|
+
urlPrefix: string,
|
|
145
|
+
): JSONOutput.ProjectReflection {
|
|
146
|
+
const permalink = `/${joinUrl(urlPrefix, packageSlug)}`;
|
|
147
|
+
|
|
148
|
+
if (project.children) {
|
|
149
|
+
// eslint-disable-next-line no-param-reassign
|
|
150
|
+
project.children = project.children.map((child) => {
|
|
151
|
+
migrateToVersion0230(child);
|
|
152
|
+
|
|
153
|
+
const kindSlugPart = getKindSlug(child);
|
|
154
|
+
const childSlug = kindSlugPart ? `/${kindSlugPart}/${child.name}` : `#${child.name}`;
|
|
155
|
+
const childPermalink = permalink + childSlug;
|
|
156
|
+
|
|
157
|
+
// We need to go another level deeper and only use fragments
|
|
158
|
+
if (child.kind === ReflectionKind.Namespace && child.children) {
|
|
159
|
+
// eslint-disable-next-line no-param-reassign
|
|
160
|
+
child.children = child.children.map((grandChild) => ({
|
|
161
|
+
...grandChild,
|
|
162
|
+
permalink: normalizeUrl([`${childPermalink}#${grandChild.name}`]),
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
...child,
|
|
168
|
+
permalink: normalizeUrl([childPermalink]),
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
...project,
|
|
175
|
+
permalink: normalizeUrl([permalink]),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function mergeReflections(base: JSONOutput.ProjectReflection, next: JSONOutput.ProjectReflection) {
|
|
180
|
+
if (Array.isArray(base.children) && Array.isArray(next.children)) {
|
|
181
|
+
base.children.push(...next.children);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (Array.isArray(base.groups) && Array.isArray(next.groups)) {
|
|
185
|
+
next.groups.forEach((group) => {
|
|
186
|
+
const baseGroup = base.groups?.find((g) => g.title === group.title);
|
|
187
|
+
|
|
188
|
+
if (baseGroup) {
|
|
189
|
+
baseGroup.children?.push(...(group.children ?? []));
|
|
190
|
+
} else {
|
|
191
|
+
base.groups?.push(group);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// We can remove refs since were merging all reflections into one
|
|
196
|
+
// eslint-disable-next-line no-param-reassign
|
|
197
|
+
base.groups = base.groups.filter((group) => group.title !== 'References');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function sortReflectionGroups(reflections: JSONOutput.ProjectReflection[]) {
|
|
202
|
+
reflections.forEach((reflection) => {
|
|
203
|
+
const map = createReflectionMap(reflection.children);
|
|
204
|
+
const sort = (a: number, b: number) => (map[a].name < map[b].name ? -1 : 1);
|
|
205
|
+
|
|
206
|
+
reflection.categories?.forEach((category) => {
|
|
207
|
+
category.children?.sort(sort);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
reflection.groups?.forEach((group) => {
|
|
211
|
+
group.children?.sort(sort);
|
|
212
|
+
|
|
213
|
+
group.categories?.forEach((category) => {
|
|
214
|
+
category.children?.sort(sort);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function matchesEntryPoint(
|
|
221
|
+
sourceFile: string,
|
|
222
|
+
entryPoint: string,
|
|
223
|
+
{ deep, single }: { deep: boolean; single: boolean },
|
|
224
|
+
): boolean {
|
|
225
|
+
// Single package
|
|
226
|
+
if (single) {
|
|
227
|
+
return (
|
|
228
|
+
// src/index.ts === src/index.ts
|
|
229
|
+
(!deep && sourceFile === entryPoint) ||
|
|
230
|
+
// index.ts === src/index.ts
|
|
231
|
+
(!deep && sourceFile === path.basename(entryPoint)) ||
|
|
232
|
+
// some/deep/file.ts === ...
|
|
233
|
+
deep
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Multiple packages
|
|
238
|
+
return (
|
|
239
|
+
// packages/foo/src/index.ts === packages/foo/src/index.ts
|
|
240
|
+
// foo/src/index.ts ~ packages/foo/src/index.ts
|
|
241
|
+
(!deep && (sourceFile === entryPoint || entryPoint.endsWith(sourceFile))) ||
|
|
242
|
+
// packages/foo/src/some/deep/file.ts === packages/foo/src/
|
|
243
|
+
(deep && sourceFile.startsWith(entryPoint))
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function extractReflectionModules(
|
|
248
|
+
project: JSONOutput.ProjectReflection,
|
|
249
|
+
isSinglePackage: boolean,
|
|
250
|
+
): JSONOutput.ProjectReflection[] {
|
|
251
|
+
const modules: JSONOutput.ProjectReflection[] = [];
|
|
252
|
+
|
|
253
|
+
const inheritChildren = () => {
|
|
254
|
+
project.children?.forEach((child) => {
|
|
255
|
+
if (child.kind === ReflectionKind.Module) {
|
|
256
|
+
modules.push(child);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// Single packages are extremely difficult, as the TypeDoc structure is
|
|
262
|
+
// different for every kind of package entry point pattern
|
|
263
|
+
if (isSinglePackage) {
|
|
264
|
+
const hasNoModules = project.children?.every((child) => child.kind !== ReflectionKind.Module);
|
|
265
|
+
|
|
266
|
+
if (hasNoModules) {
|
|
267
|
+
// No "module" children:
|
|
268
|
+
// - Polyrepos
|
|
269
|
+
// - Monorepos with 1 package
|
|
270
|
+
modules.push(project);
|
|
271
|
+
} else {
|
|
272
|
+
// Has "module" children:
|
|
273
|
+
// - Polyrepos with deep imports
|
|
274
|
+
// - Polyrepos with multi-imports
|
|
275
|
+
// - Monorepos
|
|
276
|
+
inheritChildren();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Multiple packages are extremely simple, as every package is a module reflection
|
|
280
|
+
// as a child on the top-level project reflection
|
|
281
|
+
} else {
|
|
282
|
+
inheritChildren();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return modules;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function flattenAndGroupPackages(
|
|
289
|
+
packageConfigs: ResolvedPackageConfig[],
|
|
290
|
+
project: JSONOutput.ProjectReflection,
|
|
291
|
+
urlPrefix: string,
|
|
292
|
+
options: DocusaurusPluginTypeDocApiOptions,
|
|
293
|
+
versioned: boolean = false,
|
|
294
|
+
): PackageReflectionGroup[] {
|
|
295
|
+
const isSinglePackage = packageConfigs.length === 1;
|
|
296
|
+
const modules = extractReflectionModules(project, isSinglePackage);
|
|
297
|
+
|
|
298
|
+
// Loop through every TypeDoc module and group based on package and entry point
|
|
299
|
+
const packages: Record<string, PackageReflectionGroup> = {};
|
|
300
|
+
const packagesWithDeepImports: JSONOutput.ProjectReflection[] = [];
|
|
301
|
+
|
|
302
|
+
modules.forEach((mod) => {
|
|
303
|
+
const relSourceFile = mod.sources?.[0]?.fileName ?? '';
|
|
304
|
+
|
|
305
|
+
packageConfigs.some((cfg) =>
|
|
306
|
+
Object.entries(cfg.entryPoints).some(([importPath, entry]) => {
|
|
307
|
+
const relEntryPoint = joinUrl(cfg.packagePath, entry.path);
|
|
308
|
+
const isUsingDeepImports = !entry.path.match(/\.tsx?$/);
|
|
309
|
+
|
|
310
|
+
if (
|
|
311
|
+
!matchesEntryPoint(relSourceFile, relEntryPoint, {
|
|
312
|
+
deep: isUsingDeepImports,
|
|
313
|
+
single: isSinglePackage,
|
|
314
|
+
})
|
|
315
|
+
) {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// We have a matching entry point, so store the record
|
|
320
|
+
if (!packages[cfg.packagePath]) {
|
|
321
|
+
const { packageJson, readmePath, changelogPath } = loadPackageJsonAndDocs(
|
|
322
|
+
path.join(options.projectRoot, cfg.packagePath),
|
|
323
|
+
options.packageJsonName,
|
|
324
|
+
options.readmeName,
|
|
325
|
+
options.changelogName,
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
packages[cfg.packagePath] = {
|
|
329
|
+
entryPoints: [],
|
|
330
|
+
packageName: (versioned && cfg.packageName) || packageJson.name,
|
|
331
|
+
packageVersion: (versioned && cfg.packageVersion) || packageJson.version,
|
|
332
|
+
readmePath,
|
|
333
|
+
changelogPath,
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// eslint-disable-next-line no-param-reassign
|
|
337
|
+
cfg.packageName = packages[cfg.packagePath].packageName;
|
|
338
|
+
// eslint-disable-next-line no-param-reassign
|
|
339
|
+
cfg.packageVersion = packages[cfg.packagePath].packageVersion;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Add metadata to package and children reflections
|
|
343
|
+
const urlSlug = getPackageSlug(cfg, importPath, isSinglePackage);
|
|
344
|
+
const reflection = addMetadataToReflections(mod, urlSlug, urlPrefix);
|
|
345
|
+
const existingEntry = packages[cfg.packagePath].entryPoints.find(
|
|
346
|
+
(ep) => ep.urlSlug === urlSlug,
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
if (existingEntry) {
|
|
350
|
+
if (isUsingDeepImports) {
|
|
351
|
+
mergeReflections(existingEntry.reflection, reflection);
|
|
352
|
+
} else {
|
|
353
|
+
// eslint-disable-next-line no-console
|
|
354
|
+
console.error(`Entry point ${urlSlug} already defined. How did you get here?`);
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
packages[cfg.packagePath].entryPoints.push({
|
|
358
|
+
index: importPath === 'index',
|
|
359
|
+
label: entry.label,
|
|
360
|
+
reflection,
|
|
361
|
+
urlSlug,
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
if (isUsingDeepImports) {
|
|
365
|
+
packagesWithDeepImports.push(reflection);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Update the reflection name since its useless
|
|
370
|
+
reflection.name =
|
|
371
|
+
importPath === 'index'
|
|
372
|
+
? packages[cfg.packagePath].packageName
|
|
373
|
+
: joinUrl(packages[cfg.packagePath].packageName, importPath);
|
|
374
|
+
|
|
375
|
+
return true;
|
|
376
|
+
}),
|
|
377
|
+
);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// Since we merged multiple reflections together, we'll need to sort groups manually
|
|
381
|
+
sortReflectionGroups(packagesWithDeepImports);
|
|
382
|
+
|
|
383
|
+
// Sort packages by name
|
|
384
|
+
return Object.values(packages).sort((a, b) => a.packageName.localeCompare(b.packageName));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export function formatPackagesWithoutHostInfo(packages: PackageReflectionGroup[]) {
|
|
388
|
+
return packages.map(({ changelogPath, readmePath, ...pkg }) => pkg);
|
|
389
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { JSONOutput } from 'typedoc';
|
|
2
|
+
import { normalizeUrl } from '@docusaurus/utils';
|
|
3
|
+
import type {
|
|
4
|
+
DeclarationReflectionMap,
|
|
5
|
+
DocusaurusPluginTypeDocApiOptions,
|
|
6
|
+
PackageReflectionGroup,
|
|
7
|
+
SidebarItem,
|
|
8
|
+
} from '../types';
|
|
9
|
+
import { removeScopes } from '../utils/links';
|
|
10
|
+
import { createReflectionMap } from './data';
|
|
11
|
+
|
|
12
|
+
export function groupSidebarItems(
|
|
13
|
+
map: DeclarationReflectionMap,
|
|
14
|
+
groups: JSONOutput.ReflectionGroup[],
|
|
15
|
+
): SidebarItem[] {
|
|
16
|
+
const items: SidebarItem[] = [];
|
|
17
|
+
const sortedGroups = [...groups].sort((a, b) => a.title.localeCompare(b.title));
|
|
18
|
+
|
|
19
|
+
function getLastItemInGroup(index: number) {
|
|
20
|
+
const length = sortedGroups[index]?.children?.length;
|
|
21
|
+
|
|
22
|
+
return length ? sortedGroups[index]?.children?.[length - 1] : undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
sortedGroups.forEach((group, groupIndex) => {
|
|
26
|
+
const { children } = group;
|
|
27
|
+
|
|
28
|
+
if (!children || children.length === 0) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
items.push({
|
|
33
|
+
collapsed: true,
|
|
34
|
+
collapsible: true,
|
|
35
|
+
items: children.map((id, index) => {
|
|
36
|
+
const child = map[id];
|
|
37
|
+
|
|
38
|
+
// We map previous/next from here since the sidebar is grouped by type,
|
|
39
|
+
// and we only want to link based on this order.
|
|
40
|
+
const previousId = index === 0 ? getLastItemInGroup(groupIndex - 1) : children[index - 1];
|
|
41
|
+
const nextId =
|
|
42
|
+
index === children.length - 1
|
|
43
|
+
? groups[groupIndex + 1]?.children?.[0]
|
|
44
|
+
: children[index + 1];
|
|
45
|
+
|
|
46
|
+
if (previousId) {
|
|
47
|
+
child.previousId = previousId;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (nextId) {
|
|
51
|
+
child.nextId = nextId;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
href: child.permalink,
|
|
56
|
+
label: child.name,
|
|
57
|
+
type: 'link',
|
|
58
|
+
};
|
|
59
|
+
}),
|
|
60
|
+
label: group.title,
|
|
61
|
+
type: 'category',
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return items;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function extractReflectionSidebar(pkg: JSONOutput.ProjectReflection): SidebarItem[] {
|
|
69
|
+
return pkg.groups ? groupSidebarItems(createReflectionMap(pkg.children), pkg.groups) : [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function extractSidebar(
|
|
73
|
+
packages: PackageReflectionGroup[],
|
|
74
|
+
scopes: string[],
|
|
75
|
+
changelogs: boolean,
|
|
76
|
+
sortSidebar: NonNullable<DocusaurusPluginTypeDocApiOptions['sortSidebar']>,
|
|
77
|
+
): SidebarItem[] {
|
|
78
|
+
if (packages.length === 0) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const items: SidebarItem[] = packages.map((pkg) => {
|
|
83
|
+
let subItems: SidebarItem[] = [];
|
|
84
|
+
|
|
85
|
+
pkg.entryPoints.forEach((entry) => {
|
|
86
|
+
// Index entry point should always bubble up reflection groups
|
|
87
|
+
if (entry.index) {
|
|
88
|
+
subItems.push(...extractReflectionSidebar(entry.reflection));
|
|
89
|
+
// Otherwise nest non-index entry points behind categories
|
|
90
|
+
} else {
|
|
91
|
+
subItems.push({
|
|
92
|
+
collapsed: true,
|
|
93
|
+
collapsible: true,
|
|
94
|
+
items: extractReflectionSidebar(entry.reflection),
|
|
95
|
+
label: entry.label,
|
|
96
|
+
type: 'category',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Always include the overview as the 1st item
|
|
102
|
+
const indexHref = pkg.entryPoints.find((entry) => entry.index)?.reflection.permalink ?? '';
|
|
103
|
+
|
|
104
|
+
subItems = subItems.sort((a, d) =>
|
|
105
|
+
sortSidebar('label' in a ? a.label : '', 'label' in d ? d.label : ''),
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
subItems.unshift({
|
|
109
|
+
href: indexHref,
|
|
110
|
+
label: 'Overview',
|
|
111
|
+
type: 'link',
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (pkg.changelogPath && changelogs) {
|
|
115
|
+
subItems.push({
|
|
116
|
+
href: normalizeUrl([indexHref, 'changelog']),
|
|
117
|
+
label: 'Changelog',
|
|
118
|
+
type: 'link',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
collapsed: true,
|
|
124
|
+
collapsible: true,
|
|
125
|
+
items: subItems,
|
|
126
|
+
label: removeScopes(pkg.packageName, scopes),
|
|
127
|
+
type: 'category',
|
|
128
|
+
} as const;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const sidebar = items.filter((item) => 'items' in item && items.length > 0);
|
|
132
|
+
|
|
133
|
+
// Collapse sidebar when only 1 package
|
|
134
|
+
if (packages.length === 1 && sidebar.length === 1 && sidebar[0].type === 'category') {
|
|
135
|
+
return sidebar[0].items;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return sidebar;
|
|
139
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
|
|
3
|
+
import { JSONOutput } from 'typedoc';
|
|
4
|
+
|
|
5
|
+
interface OldComment {
|
|
6
|
+
shortText?: string;
|
|
7
|
+
text?: string;
|
|
8
|
+
tags?: { tag: string; text: string }[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface OldDeclarationReflection {
|
|
12
|
+
typeParameter?: JSONOutput.TypeParameterReflection[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// https://github.com/TypeStrong/typedoc/releases/tag/v0.23.0
|
|
16
|
+
// https://github.com/milesj/docusaurus-plugin-typedoc-api/pull/50
|
|
17
|
+
export function migrateToVersion0230(reflection: JSONOutput.DeclarationReflection) {
|
|
18
|
+
if (Array.isArray(reflection.getSignature)) {
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
20
|
+
reflection.getSignature = reflection.getSignature[0];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (Array.isArray(reflection.setSignature)) {
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
25
|
+
reflection.setSignature = reflection.setSignature[0];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if ('typeParameter' in reflection) {
|
|
29
|
+
reflection.typeParameters = (reflection as OldDeclarationReflection).typeParameter;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (
|
|
33
|
+
reflection.comment &&
|
|
34
|
+
('shortText' in reflection.comment ||
|
|
35
|
+
'text' in reflection.comment ||
|
|
36
|
+
'tags' in reflection.comment)
|
|
37
|
+
) {
|
|
38
|
+
const comment = reflection.comment as OldComment;
|
|
39
|
+
const summary: JSONOutput.CommentDisplayPart[] = [];
|
|
40
|
+
|
|
41
|
+
if (comment.shortText) {
|
|
42
|
+
summary.push({ kind: 'text', text: comment.shortText });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (comment.text) {
|
|
46
|
+
summary.push({ kind: 'text', text: comment.text });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
reflection.comment = {
|
|
50
|
+
blockTags: comment.tags?.map((tag) => ({
|
|
51
|
+
content: [{ kind: 'text', text: tag.text }],
|
|
52
|
+
name: tag.tag,
|
|
53
|
+
tag: `@${tag.tag}`,
|
|
54
|
+
})),
|
|
55
|
+
summary,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { JSONOutput, ReflectionKind } from 'typedoc';
|
|
3
|
+
import type { ResolvedPackageConfig } from '../types';
|
|
4
|
+
|
|
5
|
+
export function joinUrl(...paths: string[]): string {
|
|
6
|
+
return path.join(...paths).replace(/\\/g, '/');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getKindSlug(decl: JSONOutput.DeclarationReflection): string {
|
|
10
|
+
switch (decl.kind) {
|
|
11
|
+
case ReflectionKind.Module:
|
|
12
|
+
return 'package';
|
|
13
|
+
case ReflectionKind.Namespace:
|
|
14
|
+
return 'namespace';
|
|
15
|
+
case ReflectionKind.Enum:
|
|
16
|
+
return 'enum';
|
|
17
|
+
case ReflectionKind.Function:
|
|
18
|
+
return 'function';
|
|
19
|
+
case ReflectionKind.Class:
|
|
20
|
+
return 'class';
|
|
21
|
+
case ReflectionKind.Interface:
|
|
22
|
+
return 'interface';
|
|
23
|
+
default:
|
|
24
|
+
return '';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function getPackageSlug(
|
|
29
|
+
pkgConfig: ResolvedPackageConfig,
|
|
30
|
+
importPath: string,
|
|
31
|
+
isSinglePackage: boolean,
|
|
32
|
+
): string {
|
|
33
|
+
// Monorepo with 1 package has special handling
|
|
34
|
+
if (isSinglePackage && pkgConfig.packageSlug !== '.') {
|
|
35
|
+
return '.';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// packages/foo -> foo
|
|
39
|
+
const slug = pkgConfig.packageSlug ?? path.basename(pkgConfig.packagePath);
|
|
40
|
+
|
|
41
|
+
// bar/baz -> bar-baz
|
|
42
|
+
const importName = importPath.replace(/\\/g, '-');
|
|
43
|
+
|
|
44
|
+
if (importName === 'index') {
|
|
45
|
+
return slug;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return `${slug}-${importName}`;
|
|
49
|
+
}
|