Skip to content

Commit 2765549

Browse files
authored
feat: add errorOnEmptyDocumentation option (#74)
1 parent 57d6d0b commit 2765549

File tree

6 files changed

+264
-101
lines changed

6 files changed

+264
-101
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'starlight-typedoc': minor
3+
---
4+
5+
Adds a new [`errorOnEmptyDocumentation`](https://starlight-typedoc.vercel.app/configuration/#erroronemptydocumentation) option, defaulting to `true`, to control whether the plugin should error when no TypeDoc documentation is generated.
6+
7+
Setting this option to `false` will prevent the plugin from erroring in this case which can be useful when generating documentation for multiple entry points and only some of them contain documented code at a given time.
8+
9+
The current behavior remains unchanged, and the plugin will error when no TypeDoc documentation is generated if the option is not explicitly set to `false`.

docs/src/content/docs/configuration.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,17 @@ As documented in the [TypeDoc documentation](https://typedoc.org/options/input/#
7979

8080
Whether to watch the entry point(s) for changes and regenerate the documentation when needed.
8181

82+
### `errorOnEmptyDocumentation`
83+
84+
**Type:** `boolean`
85+
**Default:** `true`
86+
87+
Whether the plugin should error when no TypeDoc documentation is generated.
88+
89+
By default, the plugin will error when no TypeDoc documentation is generated.
90+
Setting this option to `false` will prevent the plugin from erroring in this case.
91+
This can be useful when generating documentation for multiple entry points and only some of them contain documented code at a given time.
92+
8293
## Sidebar configuration
8394

8495
The sidebar configuration is an object with the following properties:

packages/starlight-typedoc/index.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ import { randomBytes } from 'node:crypto'
33
import type { StarlightPlugin } from '@astrojs/starlight/types'
44
import type { TypeDocOptions } from 'typedoc'
55

6-
import { getSidebarFromReflections, getSidebarGroupPlaceholder, type SidebarGroup } from './libs/starlight'
7-
import { generateTypeDoc, type TypeDocConfig } from './libs/typedoc'
6+
import {
7+
getSidebarFromReflections,
8+
getSidebarGroupPlaceholder,
9+
getSidebarWithoutReflections,
10+
type SidebarGroup,
11+
} from './libs/starlight'
12+
import { generateTypeDoc, NoReflectionsError, type TypeDocConfig } from './libs/typedoc'
813

914
export const typeDocSidebarGroup = getSidebarGroupPlaceholder()
1015

@@ -26,16 +31,27 @@ function makeStarlightTypeDocPlugin(sidebarGroup: SidebarGroup): (options: Starl
2631
async 'config:setup'({ astroConfig, command, config, logger, updateConfig }) {
2732
if (command === 'preview') return
2833

29-
const { outputDirectory, reflections } = await generateTypeDoc(options, astroConfig, logger)
30-
const sidebar = getSidebarFromReflections(
31-
config.sidebar,
32-
sidebarGroup,
33-
options.sidebar,
34-
reflections,
35-
outputDirectory,
36-
)
34+
try {
35+
const { outputDirectory, reflections } = await generateTypeDoc(options, astroConfig, logger)
3736

38-
updateConfig({ sidebar })
37+
updateConfig({
38+
sidebar: getSidebarFromReflections(
39+
config.sidebar,
40+
sidebarGroup,
41+
options.sidebar,
42+
reflections,
43+
outputDirectory,
44+
),
45+
})
46+
} catch (error) {
47+
if (options.errorOnEmptyDocumentation === false && error instanceof NoReflectionsError) {
48+
logger.warn('No documentation generated but ignoring as `errorOnEmptyDocumentation` is disabled.')
49+
updateConfig({ sidebar: getSidebarWithoutReflections(config.sidebar, sidebarGroup) })
50+
return
51+
}
52+
53+
throw error
54+
}
3955
},
4056
},
4157
}
@@ -47,6 +63,11 @@ export interface StarlightTypeDocOptions {
4763
* The path(s) to the entry point(s) to document.
4864
*/
4965
entryPoints: TypeDocOptions['entryPoints']
66+
/**
67+
* Whether the plugin should error when no TypeDoc documentation is generated.
68+
* @default true
69+
*/
70+
errorOnEmptyDocumentation?: boolean
5071
/**
5172
* The output directory containing the generated documentation markdown files relative to the `src/content/docs/`
5273
* directory.

packages/starlight-typedoc/libs/starlight.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,39 @@ export function getSidebarFromReflections(
6363
})
6464
}
6565

66+
export function getSidebarWithoutReflections(
67+
sidebar: StarlightUserConfigSidebar,
68+
sidebarGroupPlaceholder: SidebarGroup,
69+
): StarlightUserConfigSidebar {
70+
if (!sidebar || sidebar.length === 0) {
71+
return sidebar
72+
}
73+
74+
function removeSidebarGroupPlaceholder(
75+
entries: NonNullable<StarlightUserConfigSidebar>,
76+
): NonNullable<StarlightUserConfigSidebar> {
77+
const sidebarWithoutPlaceholder: StarlightUserConfigSidebar = []
78+
79+
for (const item of entries) {
80+
if (isSidebarManualGroup(item)) {
81+
if (item.label === sidebarGroupPlaceholder.label) continue
82+
83+
sidebarWithoutPlaceholder.push({
84+
...item,
85+
items: removeSidebarGroupPlaceholder(item.items),
86+
})
87+
continue
88+
}
89+
90+
sidebarWithoutPlaceholder.push(item)
91+
}
92+
93+
return sidebarWithoutPlaceholder
94+
}
95+
96+
return removeSidebarGroupPlaceholder(sidebar)
97+
}
98+
6699
function getSidebarGroupFromPackageReflections(
67100
options: StarlightTypeDocSidebarOptions,
68101
reflections: ProjectReflection | DeclarationReflection,

packages/starlight-typedoc/libs/typedoc.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export async function generateTypeDoc(
5858
(!reflections?.groups || reflections.groups.length === 0) &&
5959
!reflections?.children?.some((child) => (child.groups ?? []).length > 0)
6060
) {
61-
throw new Error('Failed to generate TypeDoc documentation.')
61+
throw new NoReflectionsError()
6262
}
6363

6464
const outputPath = path.join(url.fileURLToPath(config.srcDir), 'content/docs', outputDirectory)
@@ -159,4 +159,10 @@ function onRendererEnd(pagesToRemove: string[]) {
159159
}
160160
}
161161

162+
export class NoReflectionsError extends Error {
163+
constructor() {
164+
super('Failed to generate TypeDoc documentation.')
165+
}
166+
}
167+
162168
export type TypeDocConfig = Partial<Omit<TypeDocOptions, 'entryPoints' | 'tsconfig'> & PluginOptions>

0 commit comments

Comments
 (0)