mirror of
https://github.com/SrIzan10/starlight-typedoc.git
synced 2026-05-01 11:05:15 +00:00
feat: typedoc 0.28 support (#77)
This commit is contained in:
7
.changeset/kind-owls-thank.md
Normal file
7
.changeset/kind-owls-thank.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'starlight-typedoc': minor
|
||||
---
|
||||
|
||||
⚠️ **BREAKING CHANGE:** The minimum supported version of `typedoc` is now `0.28.0`.
|
||||
|
||||
⚠️ **BREAKING CHANGE:** The minimum supported version of `typedoc-plugin-markdown` is now `4.6.0`.
|
||||
@@ -33,7 +33,7 @@ import { PackageManagers } from '@hideoo/starlight-plugins-docs-components'
|
||||
/** @param {MarkdownPageEvent} page */
|
||||
(page) => {
|
||||
// Customize the frontmatter for a specific page.
|
||||
if (page.model.url === 'variables/something.md') {
|
||||
if (page.url === 'variables/something.md') {
|
||||
// Update the frontmatter of the generated page.
|
||||
page.frontmatter = {
|
||||
// Include a sidebar badge with the text 'New'.
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
"astro": "^5.3.0",
|
||||
"sharp": "^0.33.5",
|
||||
"starlight-typedoc": "workspace:*",
|
||||
"typedoc": "^0.26.5",
|
||||
"typedoc-plugin-frontmatter": "^1.0.0",
|
||||
"typedoc-plugin-markdown": "^4.1.1",
|
||||
"typedoc-plugin-mdn-links": "^3.0.3"
|
||||
"typedoc": "^0.28.1",
|
||||
"typedoc-plugin-frontmatter": "^1.3.0",
|
||||
"typedoc-plugin-markdown": "^4.6.0",
|
||||
"typedoc-plugin-mdn-links": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17.1"
|
||||
|
||||
@@ -6,7 +6,7 @@ export function load(app) {
|
||||
MarkdownPageEvent.BEGIN,
|
||||
/** @param {MarkdownPageEvent} page */
|
||||
(page) => {
|
||||
if (page.model.url === 'variables/anObject.md') {
|
||||
if (page.url === 'variables/anObject.md') {
|
||||
page.frontmatter = {
|
||||
sidebar: {
|
||||
badge: {
|
||||
|
||||
@@ -32,7 +32,7 @@ function makeStarlightTypeDocPlugin(sidebarGroup: SidebarGroup): (options: Starl
|
||||
if (command === 'preview') return
|
||||
|
||||
try {
|
||||
const { outputDirectory, reflections } = await generateTypeDoc(options, astroConfig, logger)
|
||||
const { definitions, outputDirectory, reflections } = await generateTypeDoc(options, astroConfig, logger)
|
||||
|
||||
updateConfig({
|
||||
sidebar: getSidebarFromReflections(
|
||||
@@ -40,6 +40,7 @@ function makeStarlightTypeDocPlugin(sidebarGroup: SidebarGroup): (options: Starl
|
||||
sidebarGroup,
|
||||
options.sidebar,
|
||||
reflections,
|
||||
definitions,
|
||||
outputDirectory,
|
||||
),
|
||||
})
|
||||
@@ -62,7 +63,7 @@ export interface StarlightTypeDocOptions {
|
||||
/**
|
||||
* The path(s) to the entry point(s) to document.
|
||||
*/
|
||||
entryPoints: TypeDocOptions['entryPoints']
|
||||
entryPoints: NonNullable<TypeDocOptions['entryPoints']>
|
||||
/**
|
||||
* Whether the plugin should error when no TypeDoc documentation is generated.
|
||||
* @default true
|
||||
@@ -86,7 +87,7 @@ export interface StarlightTypeDocOptions {
|
||||
/**
|
||||
* The path to the `tsconfig.json` file to use for the documentation generation.
|
||||
*/
|
||||
tsconfig: TypeDocOptions['tsconfig']
|
||||
tsconfig: NonNullable<TypeDocOptions['tsconfig']>
|
||||
/**
|
||||
* Additional TypeDoc configuration.
|
||||
* @see https://typedoc.org/options
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
|
||||
import type { StarlightTypeDocSidebarOptions } from '..'
|
||||
|
||||
import type { TypeDocDefinitions } from './typedoc'
|
||||
|
||||
const externalLinkRegex = /^(http|ftp)s?:\/\//
|
||||
|
||||
const sidebarDefaultOptions = {
|
||||
@@ -33,13 +35,20 @@ export function getSidebarFromReflections(
|
||||
sidebarGroupPlaceholder: SidebarGroup,
|
||||
options: StarlightTypeDocSidebarOptions = {},
|
||||
reflections: ProjectReflection | DeclarationReflection,
|
||||
definitions: TypeDocDefinitions,
|
||||
baseOutputDirectory: string,
|
||||
): StarlightUserConfigSidebar {
|
||||
if (!sidebar || sidebar.length === 0) {
|
||||
return sidebar
|
||||
}
|
||||
|
||||
const sidebarGroup = getSidebarGroupFromReflections(options, reflections, baseOutputDirectory, baseOutputDirectory)
|
||||
const sidebarGroup = getSidebarGroupFromReflections(
|
||||
options,
|
||||
reflections,
|
||||
definitions,
|
||||
baseOutputDirectory,
|
||||
baseOutputDirectory,
|
||||
)
|
||||
|
||||
function replaceSidebarGroupPlaceholder(group: SidebarManualGroup): SidebarGroup {
|
||||
if (group.label === sidebarGroupPlaceholder.label) {
|
||||
@@ -99,20 +108,24 @@ export function getSidebarWithoutReflections(
|
||||
function getSidebarGroupFromPackageReflections(
|
||||
options: StarlightTypeDocSidebarOptions,
|
||||
reflections: ProjectReflection | DeclarationReflection,
|
||||
definitions: TypeDocDefinitions,
|
||||
baseOutputDirectory: string,
|
||||
): SidebarGroup {
|
||||
const groups = (reflections.children ?? []).map((child) => {
|
||||
if (!child.url) {
|
||||
const url = definitions[child.id]
|
||||
|
||||
if (!url) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const url = path.parse(child.url)
|
||||
const parsedPath = path.parse(url)
|
||||
|
||||
return getSidebarGroupFromReflections(
|
||||
options,
|
||||
child,
|
||||
definitions,
|
||||
baseOutputDirectory,
|
||||
`${baseOutputDirectory}/${url.dir}`,
|
||||
`${baseOutputDirectory}/${parsedPath.dir}`,
|
||||
child.name,
|
||||
)
|
||||
})
|
||||
@@ -127,12 +140,13 @@ function getSidebarGroupFromPackageReflections(
|
||||
function getSidebarGroupFromReflections(
|
||||
options: StarlightTypeDocSidebarOptions,
|
||||
reflections: ProjectReflection | DeclarationReflection,
|
||||
definitions: TypeDocDefinitions,
|
||||
baseOutputDirectory: string,
|
||||
outputDirectory: string,
|
||||
label?: string,
|
||||
): SidebarGroup {
|
||||
if ((!reflections.groups || reflections.groups.length === 0) && reflections.children) {
|
||||
return getSidebarGroupFromPackageReflections(options, reflections, outputDirectory)
|
||||
return getSidebarGroupFromPackageReflections(options, reflections, definitions, outputDirectory)
|
||||
}
|
||||
|
||||
const groups = reflections.groups ?? []
|
||||
@@ -144,32 +158,37 @@ function getSidebarGroupFromReflections(
|
||||
.flatMap((group) => {
|
||||
if (group.title === 'Modules') {
|
||||
return group.children.map((child) => {
|
||||
if (!child.url || child.variant === 'document') {
|
||||
const url = definitions[child.id]
|
||||
|
||||
if (!url || child.variant === 'document') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const url = path.parse(child.url)
|
||||
const parsedPath = path.parse(url)
|
||||
const isParentKindModule = child.parent?.kind === ReflectionKind.Module
|
||||
|
||||
return getSidebarGroupFromReflections(
|
||||
{ collapsed: true, label: child.name },
|
||||
child,
|
||||
definitions,
|
||||
baseOutputDirectory,
|
||||
`${outputDirectory}/${isParentKindModule ? url.dir.split('/').slice(1).join('/') : url.dir}`,
|
||||
`${outputDirectory}/${isParentKindModule ? parsedPath.dir.split('/').slice(1).join('/') : parsedPath.dir}`,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
if (isReferenceReflectionGroup(group)) {
|
||||
return getReferencesSidebarGroup(group, baseOutputDirectory)
|
||||
return getReferencesSidebarGroup(group, definitions, baseOutputDirectory)
|
||||
}
|
||||
|
||||
const directory = `${outputDirectory}/${slug(group.title.toLowerCase())}`
|
||||
|
||||
// The groups generated using the `@group` tag do not have an associated directory on disk.
|
||||
const isGroupWithDirectory = group.children.some((child) =>
|
||||
path.posix.join(baseOutputDirectory, child.url?.replace('\\', '/') ?? '').startsWith(directory),
|
||||
)
|
||||
const isGroupWithDirectory = group.children.some((child) => {
|
||||
return path.posix
|
||||
.join(baseOutputDirectory, definitions[child.id]?.replace('\\', '/') ?? '')
|
||||
.startsWith(directory)
|
||||
})
|
||||
|
||||
if (!isGroupWithDirectory) {
|
||||
return undefined
|
||||
@@ -190,6 +209,7 @@ function getSidebarGroupFromReflections(
|
||||
|
||||
function getReferencesSidebarGroup(
|
||||
group: ReflectionGroup,
|
||||
definitions: TypeDocDefinitions,
|
||||
baseOutputDirectory: string,
|
||||
): SidebarManualGroup | undefined {
|
||||
const referenceItems: LinkItem[] = group.children
|
||||
@@ -205,13 +225,15 @@ function getReferencesSidebarGroup(
|
||||
target = target.parent
|
||||
}
|
||||
|
||||
if (!target.url) {
|
||||
const url = definitions[target.id]
|
||||
|
||||
if (!url) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
label: reference.name,
|
||||
link: getRelativeURL(target.url, getStarlightTypeDocOutputDirectory(baseOutputDirectory)),
|
||||
link: getRelativeURL(url, getStarlightTypeDocOutputDirectory(baseOutputDirectory)),
|
||||
}
|
||||
})
|
||||
.filter((item): item is LinkItem => item !== undefined)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import path from 'node:path'
|
||||
|
||||
import { Reflection, type Comment, type CommentTag, type Options, type CommentDisplayPart } from 'typedoc'
|
||||
import { MarkdownTheme, MarkdownThemeContext, type MarkdownPageEvent } from 'typedoc-plugin-markdown'
|
||||
|
||||
@@ -9,99 +7,93 @@ const customBlockTagTypes = ['@deprecated'] as const
|
||||
const customModifiersTagTypes = ['@alpha', '@beta', '@experimental'] as const
|
||||
|
||||
export class StarlightTypeDocTheme extends MarkdownTheme {
|
||||
override getRenderContext(event: MarkdownPageEvent): StarlightTypeDocThemeRenderContext {
|
||||
override getRenderContext(event: MarkdownPageEvent<Reflection>): StarlightTypeDocThemeRenderContext {
|
||||
return new StarlightTypeDocThemeRenderContext(this, event, this.application.options)
|
||||
}
|
||||
}
|
||||
|
||||
class StarlightTypeDocThemeRenderContext extends MarkdownThemeContext {
|
||||
#markdownThemeContext: MarkdownThemeContext
|
||||
|
||||
constructor(theme: MarkdownTheme, event: MarkdownPageEvent, options: Options) {
|
||||
constructor(theme: MarkdownTheme, event: MarkdownPageEvent<Reflection>, options: Options) {
|
||||
super(theme, event, options)
|
||||
|
||||
this.#markdownThemeContext = new MarkdownThemeContext(theme, event, options)
|
||||
const superPartials = this.partials
|
||||
|
||||
this.partials = {
|
||||
...superPartials,
|
||||
comment: (comment, options) => {
|
||||
const filteredComment = { ...comment } as Comment
|
||||
filteredComment.blockTags = []
|
||||
filteredComment.modifierTags = new Set<`@${string}`>()
|
||||
|
||||
const customTags: CustomTag[] = []
|
||||
|
||||
for (const blockTag of comment.blockTags) {
|
||||
if (this.#isCustomBlockCommentTagType(blockTag.tag)) {
|
||||
customTags.push({ blockTag, type: blockTag.tag })
|
||||
} else {
|
||||
blockTag.content = blockTag.content.map((part) => this.#parseCommentDisplayPart(part))
|
||||
filteredComment.blockTags.push(blockTag)
|
||||
}
|
||||
}
|
||||
|
||||
for (const modifierTag of comment.modifierTags) {
|
||||
if (this.#isCustomModifierCommentTagType(modifierTag)) {
|
||||
customTags.push({ type: modifierTag })
|
||||
} else {
|
||||
filteredComment.modifierTags.add(modifierTag)
|
||||
}
|
||||
}
|
||||
|
||||
filteredComment.summary = comment.summary.map((part) => this.#parseCommentDisplayPart(part))
|
||||
|
||||
let markdown = superPartials.comment(filteredComment, options)
|
||||
|
||||
if (options?.showSummary === false) {
|
||||
return markdown
|
||||
}
|
||||
|
||||
for (const customCommentTag of customTags) {
|
||||
switch (customCommentTag.type) {
|
||||
case '@alpha': {
|
||||
markdown = this.#addReleaseStageAside(markdown, 'Alpha')
|
||||
break
|
||||
}
|
||||
case '@beta': {
|
||||
markdown = this.#addReleaseStageAside(markdown, 'Beta')
|
||||
break
|
||||
}
|
||||
case '@deprecated': {
|
||||
markdown = this.#addDeprecatedAside(markdown, customCommentTag.blockTag)
|
||||
break
|
||||
}
|
||||
case '@experimental': {
|
||||
markdown = this.#addReleaseStageAside(markdown, 'Experimental')
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return markdown
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
override getRelativeUrl(url: string): string {
|
||||
override urlTo(reflection: Reflection): string {
|
||||
const outputDirectory = this.options.getValue('starlight-typedoc-output')
|
||||
const baseUrl = typeof outputDirectory === 'string' ? outputDirectory : ''
|
||||
|
||||
return getRelativeURL(url, baseUrl, this.page.url)
|
||||
}
|
||||
|
||||
override partials: MarkdownThemeContext['partials'] = {
|
||||
// @ts-expect-error https://github.com/tgreyuk/typedoc-plugin-markdown/blob/2bc4136a364c1d1ab44789d6148cd19c425ce63c/docs/pages/docs/customizing-output.mdx#custom-theme
|
||||
...this.partials,
|
||||
comment: (comment, options) => {
|
||||
const filteredComment = { ...comment } as Comment
|
||||
filteredComment.blockTags = []
|
||||
filteredComment.modifierTags = new Set<`@${string}`>()
|
||||
|
||||
const customTags: CustomTag[] = []
|
||||
|
||||
for (const blockTag of comment.blockTags) {
|
||||
if (this.#isCustomBlockCommentTagType(blockTag.tag)) {
|
||||
customTags.push({ blockTag, type: blockTag.tag })
|
||||
} else {
|
||||
blockTag.content = blockTag.content.map((part) => this.#parseCommentDisplayPart(part))
|
||||
filteredComment.blockTags.push(blockTag)
|
||||
}
|
||||
}
|
||||
|
||||
for (const modifierTag of comment.modifierTags) {
|
||||
if (this.#isCustomModifierCommentTagType(modifierTag)) {
|
||||
customTags.push({ type: modifierTag })
|
||||
} else {
|
||||
filteredComment.modifierTags.add(modifierTag)
|
||||
}
|
||||
}
|
||||
|
||||
filteredComment.summary = comment.summary.map((part) => this.#parseCommentDisplayPart(part))
|
||||
|
||||
let markdown = this.#markdownThemeContext.partials.comment(filteredComment, options)
|
||||
|
||||
if (options?.showSummary === false) {
|
||||
return markdown
|
||||
}
|
||||
|
||||
for (const customCommentTag of customTags) {
|
||||
switch (customCommentTag.type) {
|
||||
case '@alpha': {
|
||||
markdown = this.#addReleaseStageAside(markdown, 'Alpha')
|
||||
break
|
||||
}
|
||||
case '@beta': {
|
||||
markdown = this.#addReleaseStageAside(markdown, 'Beta')
|
||||
break
|
||||
}
|
||||
case '@deprecated': {
|
||||
markdown = this.#addDeprecatedAside(markdown, customCommentTag.blockTag)
|
||||
break
|
||||
}
|
||||
case '@experimental': {
|
||||
markdown = this.#addReleaseStageAside(markdown, 'Experimental')
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return markdown
|
||||
},
|
||||
return getRelativeURL(this.router.getFullUrl(reflection), baseUrl, this.page.url)
|
||||
}
|
||||
|
||||
#parseCommentDisplayPart = (part: CommentDisplayPart): CommentDisplayPart => {
|
||||
if (
|
||||
part.kind === 'inline-tag' &&
|
||||
(part.tag === '@link' || part.tag === '@linkcode' || part.tag === '@linkplain') &&
|
||||
part.target instanceof Reflection &&
|
||||
typeof part.target.url === 'string'
|
||||
part.target instanceof Reflection
|
||||
) {
|
||||
return {
|
||||
...part,
|
||||
target: this.getRelativeUrl(
|
||||
path.posix.join(this.options.getValue('entryPointStrategy') === 'packages' ? '../..' : '..', part.target.url),
|
||||
),
|
||||
target: this.urlTo(part.target),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fs from 'node:fs'
|
||||
import * as fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import url from 'node:url'
|
||||
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
TSConfigReader,
|
||||
type TypeDocOptions,
|
||||
ParameterType,
|
||||
type Reflection,
|
||||
RendererEvent,
|
||||
type PageDefinition,
|
||||
} from 'typedoc'
|
||||
import type { MarkdownPageEvent, PluginOptions } from 'typedoc-plugin-markdown'
|
||||
|
||||
@@ -47,11 +47,23 @@ export async function generateTypeDoc(
|
||||
options.entryPoints,
|
||||
options.tsconfig,
|
||||
options.typeDoc,
|
||||
outputDirectory,
|
||||
{
|
||||
base: config.base,
|
||||
directory: outputDirectory,
|
||||
path: path.join(url.fileURLToPath(config.srcDir), 'content/docs', outputDirectory),
|
||||
},
|
||||
options.pagination ?? false,
|
||||
config.base,
|
||||
logger,
|
||||
)
|
||||
|
||||
const definitions: TypeDocDefinitions = {}
|
||||
app.renderer.on(RendererEvent.END, (event) => {
|
||||
for (const page of event.pages) {
|
||||
if (!('id' in page.model)) continue
|
||||
definitions[page.model.id] = page.url
|
||||
}
|
||||
})
|
||||
|
||||
const reflections = await app.convert()
|
||||
|
||||
if (
|
||||
@@ -61,26 +73,21 @@ export async function generateTypeDoc(
|
||||
throw new NoReflectionsError()
|
||||
}
|
||||
|
||||
const outputPath = path.join(url.fileURLToPath(config.srcDir), 'content/docs', outputDirectory)
|
||||
await (options.watch
|
||||
? app.convertAndWatch(async (reflections) => {
|
||||
await app.generateOutputs(reflections)
|
||||
})
|
||||
: app.generateOutputs(reflections))
|
||||
|
||||
if (options.watch) {
|
||||
app.convertAndWatch(async (reflections) => {
|
||||
await app.generateDocs(reflections, outputPath)
|
||||
})
|
||||
} else {
|
||||
await app.generateDocs(reflections, outputPath)
|
||||
}
|
||||
|
||||
return { outputDirectory, reflections }
|
||||
return { definitions, outputDirectory, reflections }
|
||||
}
|
||||
|
||||
async function bootstrapApp(
|
||||
entryPoints: TypeDocOptions['entryPoints'],
|
||||
tsconfig: TypeDocOptions['tsconfig'],
|
||||
entryPoints: NonNullable<TypeDocOptions['entryPoints']>,
|
||||
tsconfig: NonNullable<TypeDocOptions['tsconfig']>,
|
||||
config: TypeDocConfig = {},
|
||||
outputDirectory: string,
|
||||
output: TypeDocOutput,
|
||||
pagination: boolean,
|
||||
base: string,
|
||||
logger: AstroIntegrationLogger,
|
||||
) {
|
||||
const pagesToRemove: string[] = []
|
||||
@@ -93,15 +100,16 @@ async function bootstrapApp(
|
||||
plugin: [...(config.plugin ?? []), 'typedoc-plugin-markdown'],
|
||||
entryPoints,
|
||||
tsconfig,
|
||||
outputs: [{ name: 'markdown', path: output.path }],
|
||||
})
|
||||
app.logger = new StarlightTypeDocLogger(logger)
|
||||
app.options.addReader(new TSConfigReader())
|
||||
app.renderer.defineTheme('starlight-typedoc', StarlightTypeDocTheme)
|
||||
app.renderer.on(PageEvent.BEGIN, (event: PageEvent<Reflection>) => {
|
||||
onRendererPageBegin(event, pagination)
|
||||
app.renderer.on(PageEvent.BEGIN, (event) => {
|
||||
onRendererPageBegin(event as MarkdownPageEvent, pagination)
|
||||
})
|
||||
app.renderer.on(PageEvent.END, (event: PageEvent<Reflection>) => {
|
||||
const shouldRemovePage = onRendererPageEnd(event, pagination)
|
||||
app.renderer.on(PageEvent.END, (event) => {
|
||||
const shouldRemovePage = onRendererPageEnd(event as MarkdownPageEvent, pagination)
|
||||
if (shouldRemovePage) {
|
||||
pagesToRemove.push(event.filename)
|
||||
}
|
||||
@@ -110,7 +118,7 @@ async function bootstrapApp(
|
||||
onRendererEnd(pagesToRemove)
|
||||
})
|
||||
app.options.addDeclaration({
|
||||
defaultValue: getStarlightTypeDocOutputDirectory(outputDirectory, base),
|
||||
defaultValue: getStarlightTypeDocOutputDirectory(output.directory, output.base),
|
||||
help: 'The starlight-typedoc output directory containing the generated documentation markdown files relative to the `src/content/docs/` directory.',
|
||||
name: 'starlight-typedoc-output',
|
||||
type: ParameterType.String,
|
||||
@@ -166,3 +174,10 @@ export class NoReflectionsError extends Error {
|
||||
}
|
||||
|
||||
export type TypeDocConfig = Partial<Omit<TypeDocOptions, 'entryPoints' | 'tsconfig'> & PluginOptions>
|
||||
export type TypeDocDefinitions = Record<string, PageDefinition['url']>
|
||||
|
||||
interface TypeDocOutput {
|
||||
base: string
|
||||
directory: string
|
||||
path: string
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@astrojs/starlight": ">=0.32.0",
|
||||
"typedoc": ">=0.26.5",
|
||||
"typedoc-plugin-markdown": ">=4.1.1"
|
||||
"typedoc": ">=0.28.0",
|
||||
"typedoc-plugin-markdown": ">=4.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17.1"
|
||||
|
||||
@@ -37,7 +37,7 @@ test('should properly format links with anchors for a single entry point', async
|
||||
.getByRole('link', { exact: true, name: 'constructor' })
|
||||
.getAttribute('href')
|
||||
|
||||
expect(barConstructorLinkHref).toEqual('/api/classes/bar/#constructors')
|
||||
expect(barConstructorLinkHref).toEqual('/api/classes/bar/#constructor')
|
||||
})
|
||||
|
||||
test('should properly format links with anchors for multiple entry points', async ({ docPage }) => {
|
||||
@@ -49,7 +49,7 @@ test('should properly format links with anchors for multiple entry points', asyn
|
||||
.getByRole('link', { exact: true, name: 'constructor' })
|
||||
.getAttribute('href')
|
||||
|
||||
expect(barConstructorLinkHref).toEqual('/multiple-entrypoints/api-multiple-entrypoints/bar/classes/bar/#constructors')
|
||||
expect(barConstructorLinkHref).toEqual('/multiple-entrypoints/api-multiple-entrypoints/bar/classes/bar/#constructor')
|
||||
})
|
||||
|
||||
test('should disable edit links', async ({ docPage }) => {
|
||||
@@ -88,12 +88,12 @@ test('should properly format links in summary', async ({ docPage }) => {
|
||||
await docPage.goto('functions/dothingfaster')
|
||||
|
||||
await docPage.content.getByRole('link', { exact: true, name: 'doThingB' }).click()
|
||||
await docPage.page.waitForURL('**/api/functions/dothingb')
|
||||
await docPage.page.waitForURL('**/api/functions/dothingb/')
|
||||
})
|
||||
|
||||
test('should properly format links in block tag comments', async ({ docPage }) => {
|
||||
await docPage.goto('classes/foo')
|
||||
|
||||
await docPage.content.locator('h4:has-text("See") + p a').click()
|
||||
await docPage.page.waitForURL('**/api/interfaces/thing')
|
||||
await docPage.page.waitForURL('**/api/interfaces/thing/')
|
||||
})
|
||||
|
||||
@@ -41,11 +41,6 @@ test('should generate the proper items for for a single entry point', async ({ d
|
||||
const items = await docPage.getTypeDocSidebarItems()
|
||||
|
||||
expect(items).toMatchObject([
|
||||
{
|
||||
label: 'References',
|
||||
items: [{ name: 'doThingARef' }],
|
||||
collapsed: true,
|
||||
},
|
||||
{
|
||||
label: 'Enumerations',
|
||||
items: [{ name: 'ANumericEnum' }, { name: 'AStringEnum' }],
|
||||
@@ -76,6 +71,11 @@ test('should generate the proper items for for a single entry point', async ({ d
|
||||
items: [{ name: 'doThingA' }, { name: 'doThingB' }, { name: 'doThingC' }, { name: 'doThingFaster' }],
|
||||
collapsed: true,
|
||||
},
|
||||
{
|
||||
label: 'References',
|
||||
items: [{ name: 'doThingARef' }],
|
||||
collapsed: true,
|
||||
},
|
||||
// `MyCustomGroup` defined in `fixtures/basics/src/Baz.ts` does not have a directory on disk which means it should
|
||||
// not be included in the sidebar.
|
||||
])
|
||||
|
||||
@@ -15,5 +15,5 @@ test('should properly format links in block tag comments', async ({ docPage }) =
|
||||
await docPage.goto('foo/functions/dofoofaster')
|
||||
|
||||
await docPage.content.getByRole('link', { exact: true, name: 'doFoo' }).click()
|
||||
await docPage.page.waitForURL('**/api-packages-entrypoints/foo/functions/dofoo')
|
||||
await docPage.page.waitForURL('**/api-packages-entrypoints/foo/functions/dofoo/')
|
||||
})
|
||||
|
||||
@@ -184,7 +184,7 @@ describe('getSidebarWithoutReflections', () => {
|
||||
})
|
||||
|
||||
function getTestSidebar(sidebar: Parameters<typeof getSidebarFromReflections>[0]) {
|
||||
return getSidebarFromReflections(sidebar, typeDocSidebarGroup, {}, {} as ProjectReflection, 'api')
|
||||
return getSidebarFromReflections(sidebar, typeDocSidebarGroup, {}, {} as ProjectReflection, {}, 'api')
|
||||
}
|
||||
|
||||
function getTestSidebarWithoutReflections(sidebar: Parameters<typeof getSidebarFromReflections>[0]) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fs from 'node:fs'
|
||||
import * as fs from 'node:fs'
|
||||
|
||||
import type { AstroIntegrationLogger, AstroConfig } from 'astro'
|
||||
import { afterAll, afterEach, beforeAll, expect, test, vi } from 'vitest'
|
||||
@@ -6,6 +6,16 @@ import { afterAll, afterEach, beforeAll, expect, test, vi } from 'vitest'
|
||||
import type { StarlightTypeDocOptions } from '../..'
|
||||
import { generateTypeDoc } from '../../libs/typedoc'
|
||||
|
||||
vi.mock(import('node:fs'), async (importOriginal) => {
|
||||
const mod = await importOriginal()
|
||||
return {
|
||||
...mod,
|
||||
mkdirSync: vi.fn(),
|
||||
rmSync: vi.fn(),
|
||||
writeFileSync: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
const starlightTypeDocOptions = {
|
||||
tsconfig: '../../fixtures/basics/tsconfig.json',
|
||||
typeDoc: {
|
||||
@@ -177,11 +187,11 @@ test('should output index with correct module path', async () => {
|
||||
|
||||
expect(
|
||||
content.includes(`
|
||||
- [bar](/api/namespaces/bar/)
|
||||
- [foo](/api/namespaces/foo/)
|
||||
- [functions](/api/namespaces/functions/)
|
||||
- [shared](/api/namespaces/shared/)
|
||||
- [types](/api/namespaces/types/)`),
|
||||
- [bar](/api/starlight-typedoc/namespaces/bar/)
|
||||
- [foo](/api/starlight-typedoc/namespaces/foo/)
|
||||
- [functions](/api/starlight-typedoc/namespaces/functions/)
|
||||
- [shared](/api/starlight-typedoc/namespaces/shared/)
|
||||
- [types](/api/starlight-typedoc/namespaces/types/)`),
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
|
||||
@@ -3,5 +3,10 @@ import { defineConfig } from 'vitest/config'
|
||||
export default defineConfig({
|
||||
test: {
|
||||
include: ['tests/unit/**/*.test.ts'],
|
||||
server: {
|
||||
deps: {
|
||||
inline: ['typedoc'],
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
90
pnpm-lock.yaml
generated
90
pnpm-lock.yaml
generated
@@ -69,17 +69,17 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../packages/starlight-typedoc
|
||||
typedoc:
|
||||
specifier: ^0.26.5
|
||||
version: 0.26.5(typescript@5.7.2)
|
||||
specifier: ^0.28.1
|
||||
version: 0.28.1(typescript@5.7.2)
|
||||
typedoc-plugin-frontmatter:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0(typedoc-plugin-markdown@4.1.1)
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(typedoc-plugin-markdown@4.6.0)
|
||||
typedoc-plugin-markdown:
|
||||
specifier: ^4.1.1
|
||||
version: 4.1.1(typedoc@0.26.5)
|
||||
specifier: ^4.6.0
|
||||
version: 4.6.0(typedoc@0.28.1)
|
||||
typedoc-plugin-mdn-links:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3(typedoc@0.26.5)
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1(typedoc@0.28.1)
|
||||
|
||||
fixtures/basics:
|
||||
dependencies:
|
||||
@@ -102,11 +102,11 @@ importers:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
typedoc:
|
||||
specifier: '>=0.26.5'
|
||||
version: 0.26.5(typescript@5.7.2)
|
||||
specifier: '>=0.28.0'
|
||||
version: 0.28.1(typescript@5.7.2)
|
||||
typedoc-plugin-markdown:
|
||||
specifier: '>=4.1.1'
|
||||
version: 4.1.1(typedoc@0.26.5)
|
||||
specifier: '>=4.6.0'
|
||||
version: 4.6.0(typedoc@0.28.1)
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
specifier: ^1.49.1
|
||||
@@ -328,7 +328,7 @@ packages:
|
||||
/@astrojs/yaml2ts@0.2.2:
|
||||
resolution: {integrity: sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==}
|
||||
dependencies:
|
||||
yaml: 2.6.1
|
||||
yaml: 2.7.0
|
||||
dev: true
|
||||
|
||||
/@babel/code-frame@7.26.2:
|
||||
@@ -932,6 +932,14 @@ packages:
|
||||
'@expressive-code/core': 0.40.2
|
||||
dev: false
|
||||
|
||||
/@gerrit0/mini-shiki@3.2.1:
|
||||
resolution: {integrity: sha512-HbzRC6MKB6U8kQhczz0APKPIzFHTrcqhaC7es2EXInq1SpjPVnpVSIsBe6hNoLWqqCx1n5VKiPXq6PfXnHZKOQ==}
|
||||
dependencies:
|
||||
'@shikijs/engine-oniguruma': 3.2.1
|
||||
'@shikijs/types': 3.2.1
|
||||
'@shikijs/vscode-textmate': 10.0.2
|
||||
dev: false
|
||||
|
||||
/@hideoo/eslint-config@4.0.0(eslint@9.17.0)(typescript@5.7.2):
|
||||
resolution: {integrity: sha512-QtcFEH37jaCNp2oWBQ1goySA7LAgA334RIhigm3PV4sfvbtUInXO5Hau6DePHJOwgku5niRR/qvDq4dgsmjpsQ==}
|
||||
peerDependencies:
|
||||
@@ -1477,6 +1485,13 @@ packages:
|
||||
'@shikijs/types': 1.29.2
|
||||
'@shikijs/vscode-textmate': 10.0.2
|
||||
|
||||
/@shikijs/engine-oniguruma@3.2.1:
|
||||
resolution: {integrity: sha512-wZZAkayEn6qu2+YjenEoFqj0OyQI64EWsNR6/71d1EkG4sxEOFooowKivsWPpaWNBu3sxAG+zPz5kzBL/SsreQ==}
|
||||
dependencies:
|
||||
'@shikijs/types': 3.2.1
|
||||
'@shikijs/vscode-textmate': 10.0.2
|
||||
dev: false
|
||||
|
||||
/@shikijs/langs@1.29.2:
|
||||
resolution: {integrity: sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ==}
|
||||
dependencies:
|
||||
@@ -1493,6 +1508,13 @@ packages:
|
||||
'@shikijs/vscode-textmate': 10.0.2
|
||||
'@types/hast': 3.0.4
|
||||
|
||||
/@shikijs/types@3.2.1:
|
||||
resolution: {integrity: sha512-/NTWAk4KE2M8uac0RhOsIhYQf4pdU0OywQuYDGIGAJ6Mjunxl2cGiuLkvu4HLCMn+OTTLRWkjZITp+aYJv60yA==}
|
||||
dependencies:
|
||||
'@shikijs/vscode-textmate': 10.0.2
|
||||
'@types/hast': 3.0.4
|
||||
dev: false
|
||||
|
||||
/@shikijs/vscode-textmate@10.0.2:
|
||||
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
|
||||
|
||||
@@ -6512,45 +6534,45 @@ packages:
|
||||
reflect.getprototypeof: 1.0.8
|
||||
dev: true
|
||||
|
||||
/typedoc-plugin-frontmatter@1.0.0(typedoc-plugin-markdown@4.1.1):
|
||||
resolution: {integrity: sha512-Mqn96+RjUjPUz/42H8MOp/8eOKjE5MVIgZRFDGmSI2YuggnMZSfh5MMpvd6ykjNTpq7gV5D2iwjqLt8nYRg9rg==}
|
||||
/typedoc-plugin-frontmatter@1.3.0(typedoc-plugin-markdown@4.6.0):
|
||||
resolution: {integrity: sha512-xYQFMAecMlsRUjmf9oM/Sq2FVz4zlgcbIeVFNLdO118CHTN06gIKJNSlyExh9+Xl8sK0YhIvoQwViUURxritWA==}
|
||||
peerDependencies:
|
||||
typedoc-plugin-markdown: '>=4.0.0'
|
||||
typedoc-plugin-markdown: '>=4.5.0'
|
||||
dependencies:
|
||||
typedoc-plugin-markdown: 4.1.1(typedoc@0.26.5)
|
||||
yaml: 2.6.1
|
||||
typedoc-plugin-markdown: 4.6.0(typedoc@0.28.1)
|
||||
yaml: 2.7.0
|
||||
dev: false
|
||||
|
||||
/typedoc-plugin-markdown@4.1.1(typedoc@0.26.5):
|
||||
resolution: {integrity: sha512-ZQv8FXn1TBZAvhWMgOL8hE472rwv1dzSr/KIIUGPmdNXybeS6jmK7d1OwKhorLuGbPDQGl6U97BwfkFTcydAkw==}
|
||||
/typedoc-plugin-markdown@4.6.0(typedoc@0.28.1):
|
||||
resolution: {integrity: sha512-RG90uC1QqGN9kPBjzEckEf0v9yIYlLoNYKm4OqjwEGFJJGOLUDs5pIEQQDR2tAv1RD7D8GUSakRlcHMTipyaOA==}
|
||||
engines: {node: '>= 18'}
|
||||
peerDependencies:
|
||||
typedoc: 0.26.x
|
||||
typedoc: 0.28.x
|
||||
dependencies:
|
||||
typedoc: 0.26.5(typescript@5.7.2)
|
||||
typedoc: 0.28.1(typescript@5.7.2)
|
||||
dev: false
|
||||
|
||||
/typedoc-plugin-mdn-links@3.0.3(typedoc@0.26.5):
|
||||
resolution: {integrity: sha512-NXhIpwQnsg7BcyMCHVqj3tUK+DL4g3Bt96JbFl4APzTGFkA+iM6GfZ/fn3TAqJ8O0CXG5R9BfWxolw1m1omNuQ==}
|
||||
/typedoc-plugin-mdn-links@5.0.1(typedoc@0.28.1):
|
||||
resolution: {integrity: sha512-eofdcc2nZZpipz/ubjG+7UYMi6Xu95svUwnZ+ClJh6NJdrv7kAOerL9N3iDOpo5kwQeK86GqPWwnv6LUGo5Wrw==}
|
||||
peerDependencies:
|
||||
typedoc: '>= 0.23.14 || 0.24.x'
|
||||
typedoc: 0.27.x || 0.28.x
|
||||
dependencies:
|
||||
typedoc: 0.26.5(typescript@5.7.2)
|
||||
typedoc: 0.28.1(typescript@5.7.2)
|
||||
dev: false
|
||||
|
||||
/typedoc@0.26.5(typescript@5.7.2):
|
||||
resolution: {integrity: sha512-Vn9YKdjKtDZqSk+by7beZ+xzkkr8T8CYoiasqyt4TTRFy5+UHzL/mF/o4wGBjRF+rlWQHDb0t6xCpA3JNL5phg==}
|
||||
engines: {node: '>= 18'}
|
||||
/typedoc@0.28.1(typescript@5.7.2):
|
||||
resolution: {integrity: sha512-Mn2VPNMaxoe/hlBiLriG4U55oyAa3Xo+8HbtEwV7F5WEOPXqtxzGuMZhJYHaqFJpajeQ6ZDUC2c990NAtTbdgw==}
|
||||
engines: {node: '>= 18', pnpm: '>= 10'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.7.2
|
||||
typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.7.2
|
||||
dependencies:
|
||||
'@gerrit0/mini-shiki': 3.2.1
|
||||
lunr: 2.3.9
|
||||
markdown-it: 14.1.0
|
||||
minimatch: 9.0.5
|
||||
shiki: 1.29.2
|
||||
typescript: 5.7.2
|
||||
yaml: 2.6.1
|
||||
yaml: 2.7.0
|
||||
dev: false
|
||||
|
||||
/typesafe-path@0.2.2:
|
||||
@@ -7279,8 +7301,8 @@ packages:
|
||||
engines: {node: '>= 14'}
|
||||
dev: true
|
||||
|
||||
/yaml@2.6.1:
|
||||
resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==}
|
||||
/yaml@2.7.0:
|
||||
resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==}
|
||||
engines: {node: '>= 14'}
|
||||
hasBin: true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user