mirror of
https://github.com/SrIzan10/starlight-typedoc.git
synced 2026-05-01 11:05:15 +00:00
feat: add support for packages entry point strategy
This commit is contained in:
29
example/astro.packages-entrypoints.config.ts
Normal file
29
example/astro.packages-entrypoints.config.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import starlight from '@astrojs/starlight'
|
||||
import { defineConfig } from 'astro/config'
|
||||
import starlightTypeDoc, { typeDocSidebarGroup } from 'starlight-typedoc'
|
||||
|
||||
export default defineConfig({
|
||||
base: '/packages-entrypoints/',
|
||||
integrations: [
|
||||
starlight({
|
||||
plugins: [
|
||||
starlightTypeDoc({
|
||||
entryPoints: ['../fixtures/packages/packages/*'],
|
||||
output: 'api-packages-entrypoints',
|
||||
tsconfig: '../fixtures/packages/tsconfig.json',
|
||||
typeDoc: {
|
||||
entryPointStrategy: 'packages',
|
||||
},
|
||||
}),
|
||||
],
|
||||
sidebar: [
|
||||
{
|
||||
label: 'Guides',
|
||||
items: [{ label: 'Example Guide', link: '/guides/example/' }],
|
||||
},
|
||||
typeDocSidebarGroup,
|
||||
],
|
||||
title: 'Starlight TypeDoc Packages Entry Points Example',
|
||||
}),
|
||||
],
|
||||
})
|
||||
@@ -9,6 +9,7 @@
|
||||
"dev": "astro dev",
|
||||
"dev:single-entrypoints": "astro dev --config astro.config.ts",
|
||||
"dev:multiple-entrypoints": "astro dev --config astro.multiple-entrypoints.config.ts",
|
||||
"dev:packages-entrypoints": "pnpm -C ../fixtures/packages run build && astro dev --config astro.packages-entrypoints.config.ts",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
|
||||
1
example/src/content/docs/.gitignore
vendored
1
example/src/content/docs/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
# Autogenerated by https://github.com/HiDeoo/starlight-typedoc
|
||||
api/
|
||||
api-multiple-entrypoints/
|
||||
api-packages-entrypoints/
|
||||
|
||||
34
fixtures/packages/package.json
Normal file
34
fixtures/packages/package.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "@starlight-typedoc/fixtures-packages",
|
||||
"version": "0.0.1",
|
||||
"license": "MIT",
|
||||
"description": "Starlight plugin to generate documentation from TypeScript using TypeDoc.",
|
||||
"author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc --build"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": "5.1.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.14.1"
|
||||
},
|
||||
"packageManager": "pnpm@8.6.1",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"keywords": [
|
||||
"starlight",
|
||||
"plugin",
|
||||
"typedoc",
|
||||
"typescript",
|
||||
"documentation",
|
||||
"astro"
|
||||
],
|
||||
"homepage": "https://github.com/HiDeoo/starlight-typedoc",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/HiDeoo/starlight-typedoc.git"
|
||||
},
|
||||
"bugs": "https://github.com/HiDeoo/starlight-typedoc/issues"
|
||||
}
|
||||
25
fixtures/packages/packages/bar/package.json
Normal file
25
fixtures/packages/packages/bar/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "bar",
|
||||
"version": "0.0.1",
|
||||
"license": "MIT",
|
||||
"description": "Starlight plugin to generate documentation from TypeScript using TypeDoc.",
|
||||
"author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@8.6.1",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"keywords": [
|
||||
"starlight",
|
||||
"plugin",
|
||||
"typedoc",
|
||||
"typescript",
|
||||
"documentation",
|
||||
"astro"
|
||||
],
|
||||
"homepage": "https://github.com/HiDeoo/starlight-typedoc",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/HiDeoo/starlight-typedoc.git"
|
||||
},
|
||||
"bugs": "https://github.com/HiDeoo/starlight-typedoc/issues"
|
||||
}
|
||||
6
fixtures/packages/packages/bar/src/functions.ts
Normal file
6
fixtures/packages/packages/bar/src/functions.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* A function that does a bar thing.
|
||||
*/
|
||||
export function doBar() {
|
||||
return 'doBar'
|
||||
}
|
||||
1
fixtures/packages/packages/bar/src/index.ts
Normal file
1
fixtures/packages/packages/bar/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './functions.js'
|
||||
8
fixtures/packages/packages/bar/tsconfig.json
Normal file
8
fixtures/packages/packages/bar/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
3
fixtures/packages/packages/bar/typedoc.json
Normal file
3
fixtures/packages/packages/bar/typedoc.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"entryPoints": ["src/index.ts"]
|
||||
}
|
||||
25
fixtures/packages/packages/foo/package.json
Normal file
25
fixtures/packages/packages/foo/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "foo",
|
||||
"version": "0.0.1",
|
||||
"license": "MIT",
|
||||
"description": "Starlight plugin to generate documentation from TypeScript using TypeDoc.",
|
||||
"author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@8.6.1",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"keywords": [
|
||||
"starlight",
|
||||
"plugin",
|
||||
"typedoc",
|
||||
"typescript",
|
||||
"documentation",
|
||||
"astro"
|
||||
],
|
||||
"homepage": "https://github.com/HiDeoo/starlight-typedoc",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/HiDeoo/starlight-typedoc.git"
|
||||
},
|
||||
"bugs": "https://github.com/HiDeoo/starlight-typedoc/issues"
|
||||
}
|
||||
16
fixtures/packages/packages/foo/src/functions.ts
Normal file
16
fixtures/packages/packages/foo/src/functions.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* A function that does a foo thing.
|
||||
* @deprecated Use the new {@link doFooFaster} function instead.
|
||||
*/
|
||||
export function doFoo() {
|
||||
return 'doFoo'
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that does another foo thing but faster.
|
||||
*
|
||||
* This is a faster alternative to {@link doFoo}.
|
||||
*/
|
||||
export function doFooFaster() {
|
||||
return 'doFoo'
|
||||
}
|
||||
1
fixtures/packages/packages/foo/src/index.ts
Normal file
1
fixtures/packages/packages/foo/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './functions.js'
|
||||
8
fixtures/packages/packages/foo/tsconfig.json
Normal file
8
fixtures/packages/packages/foo/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
3
fixtures/packages/packages/foo/typedoc.json
Normal file
3
fixtures/packages/packages/foo/typedoc.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"entryPoints": ["src/index.ts"]
|
||||
}
|
||||
9
fixtures/packages/tsconfig.base.json
Normal file
9
fixtures/packages/tsconfig.base.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"module": "NodeNext",
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
11
fixtures/packages/tsconfig.json
Normal file
11
fixtures/packages/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./packages/bar"
|
||||
},
|
||||
{
|
||||
"path": "./packages/foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import path from 'node:path'
|
||||
|
||||
import type { StarlightPlugin } from '@astrojs/starlight/types'
|
||||
import { slug } from 'github-slugger'
|
||||
import type { DeclarationReflection, ProjectReflection } from 'typedoc'
|
||||
import { type DeclarationReflection, type ProjectReflection, ReflectionKind } from 'typedoc'
|
||||
|
||||
import type { StarlightTypeDocSidebarOptions } from '..'
|
||||
|
||||
@@ -54,16 +54,43 @@ export function getSidebarFromReflections(
|
||||
})
|
||||
}
|
||||
|
||||
function getSidebarGroupFromReflections(
|
||||
function getSidebarGroupFromPackageReflections(
|
||||
options: StarlightTypeDocSidebarOptions,
|
||||
reflections: ProjectReflection | DeclarationReflection,
|
||||
outputDirectory: string,
|
||||
): SidebarGroup {
|
||||
const groups = reflections.groups ?? []
|
||||
const groups = (reflections.children ?? []).map((child) => {
|
||||
if (!child.url) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const url = path.parse(child.url)
|
||||
|
||||
return getSidebarGroupFromReflections(options, child, `${outputDirectory}/${url.dir}`, child.name)
|
||||
})
|
||||
|
||||
return {
|
||||
label: options.label ?? sidebarDefaultOptions.label,
|
||||
collapsed: options.collapsed ?? sidebarDefaultOptions.collapsed,
|
||||
items: groups.filter((item): item is SidebarGroup => item !== undefined),
|
||||
}
|
||||
}
|
||||
|
||||
function getSidebarGroupFromReflections(
|
||||
options: StarlightTypeDocSidebarOptions,
|
||||
reflections: ProjectReflection | DeclarationReflection,
|
||||
outputDirectory: string,
|
||||
label?: string,
|
||||
): SidebarGroup {
|
||||
if ((!reflections.groups || reflections.groups.length === 0) && reflections.children) {
|
||||
return getSidebarGroupFromPackageReflections(options, reflections, outputDirectory)
|
||||
}
|
||||
|
||||
const groups = reflections.groups ?? []
|
||||
|
||||
return {
|
||||
label: label ?? options.label ?? sidebarDefaultOptions.label,
|
||||
collapsed: options.collapsed ?? sidebarDefaultOptions.collapsed,
|
||||
items: groups
|
||||
.flatMap((group) => {
|
||||
if (group.title === 'Modules') {
|
||||
@@ -73,11 +100,12 @@ function getSidebarGroupFromReflections(
|
||||
}
|
||||
|
||||
const url = path.parse(child.url)
|
||||
const isParentKindModule = child.parent?.kind === ReflectionKind.Module
|
||||
|
||||
return getSidebarGroupFromReflections(
|
||||
{ collapsed: true, label: child.name },
|
||||
child,
|
||||
`${outputDirectory}/${url.dir}`,
|
||||
`${outputDirectory}/${isParentKindModule ? url.dir.split('/').slice(1).join('/') : url.dir}`,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -47,7 +47,10 @@ export async function generateTypeDoc(options: StarlightTypeDocOptions, base: st
|
||||
)
|
||||
const reflections = await app.convert()
|
||||
|
||||
if (!reflections?.groups || reflections.groups.length === 0) {
|
||||
if (
|
||||
(!reflections?.groups || reflections.groups.length === 0) &&
|
||||
!reflections?.children?.some((child) => (child.groups ?? []).length > 0)
|
||||
) {
|
||||
throw new Error('Failed to generate TypeDoc documentation.')
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
"scripts": {
|
||||
"test": "pnpm test:unit && pnpm test:e2e",
|
||||
"test:unit": "vitest",
|
||||
"test:e2e": "playwright install --with-deps chromium && playwright test",
|
||||
"test:e2e": "pnpm run test:e2e:basics && pnpm run test:e2e:packages",
|
||||
"test:e2e:basics": "TEST_TYPE=basics pnpm run playwright",
|
||||
"test:e2e:packages": "TEST_TYPE=packages pnpm run playwright",
|
||||
"playwright": "playwright install --with-deps chromium && playwright test",
|
||||
"lint": "prettier -c --cache . && eslint . --cache --max-warnings=0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -8,19 +8,29 @@ export default defineConfig({
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
testDir: 'tests/e2e',
|
||||
webServer: [
|
||||
{
|
||||
command: 'pnpm run dev:single-entrypoints',
|
||||
cwd: '../../example',
|
||||
reuseExistingServer: !process.env['CI'],
|
||||
url: 'http://localhost:4321',
|
||||
},
|
||||
{
|
||||
command: 'pnpm run dev:multiple-entrypoints',
|
||||
cwd: '../../example',
|
||||
reuseExistingServer: !process.env['CI'],
|
||||
url: 'http://localhost:4322/multiple-entrypoints/',
|
||||
},
|
||||
],
|
||||
testDir: `tests/e2e/${process.env['TEST_TYPE']}`,
|
||||
webServer:
|
||||
process.env['TEST_TYPE'] === 'basics'
|
||||
? [
|
||||
{
|
||||
command: 'pnpm run dev:single-entrypoints',
|
||||
cwd: '../../example',
|
||||
reuseExistingServer: !process.env['CI'],
|
||||
url: 'http://localhost:4321',
|
||||
},
|
||||
{
|
||||
command: 'pnpm run dev:multiple-entrypoints',
|
||||
cwd: '../../example',
|
||||
reuseExistingServer: !process.env['CI'],
|
||||
url: 'http://localhost:4322/multiple-entrypoints/',
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
command: 'pnpm run dev:packages-entrypoints',
|
||||
cwd: '../../example',
|
||||
reuseExistingServer: !process.env['CI'],
|
||||
url: 'http://localhost:4321/packages-entrypoints/',
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { DocPage } from './fixtures/DocPage'
|
||||
import { expect, test } from './test'
|
||||
import type { DocPage } from '../fixtures/DocPage'
|
||||
import { expect, test } from '../test'
|
||||
|
||||
test('should use an aside for the deprecated tag with no content', async ({ docPage }) => {
|
||||
await docPage.goto('functions/dothingb')
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect, test } from './test'
|
||||
import { expect, test } from '../test'
|
||||
|
||||
test('should add titles to the frontmatter', async ({ docPage }) => {
|
||||
await docPage.goto('classes/foo')
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { DocPage } from './fixtures/DocPage'
|
||||
import { expect, test } from './test'
|
||||
import type { DocPage } from '../fixtures/DocPage'
|
||||
import { expect, test } from '../test'
|
||||
|
||||
test('should not include pagination links by default', async ({ docPage }) => {
|
||||
await docPage.goto('classes/foo')
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect, test } from './test'
|
||||
import { expect, test } from '../test'
|
||||
|
||||
const singleEntrypointUrl = 'classes/foo'
|
||||
const multipleEntrypointsUrl = 'bar/classes/bar'
|
||||
@@ -4,13 +4,17 @@ export class DocPage {
|
||||
title: string | null = null
|
||||
|
||||
#useMultipleEntryPoints = false
|
||||
#usePackagesEntryPoints = false
|
||||
|
||||
constructor(public readonly page: Page) {}
|
||||
|
||||
async goto(url: string) {
|
||||
const baseUrl = `http://localhost:${this.#useMultipleEntryPoints ? 4322 : 4321}/${
|
||||
this.#useMultipleEntryPoints ? 'multiple-entrypoints/api-multiple-entrypoints' : 'api'
|
||||
}`
|
||||
const baseDir = this.#useMultipleEntryPoints
|
||||
? 'multiple-entrypoints/api-multiple-entrypoints'
|
||||
: this.#usePackagesEntryPoints
|
||||
? 'packages-entrypoints/api-packages-entrypoints'
|
||||
: 'api'
|
||||
const baseUrl = `http://localhost:${this.#useMultipleEntryPoints ? 4322 : 4321}/${baseDir}`
|
||||
|
||||
await this.page.goto(`${baseUrl}${url.startsWith('/') ? url : `/${url}`}${url.endsWith('/') ? '' : '/'}`)
|
||||
|
||||
@@ -22,6 +26,10 @@ export class DocPage {
|
||||
this.#useMultipleEntryPoints = true
|
||||
}
|
||||
|
||||
usePackagesEntryPoints() {
|
||||
this.#usePackagesEntryPoints = true
|
||||
}
|
||||
|
||||
get content() {
|
||||
return this.page.getByRole('main')
|
||||
}
|
||||
@@ -37,7 +45,7 @@ export class DocPage {
|
||||
}
|
||||
|
||||
get #expectedTypeDocSidebarLabel() {
|
||||
return this.#useMultipleEntryPoints ? 'API' : 'API (auto-generated)'
|
||||
return this.#useMultipleEntryPoints || this.#usePackagesEntryPoints ? 'API' : 'API (auto-generated)'
|
||||
}
|
||||
|
||||
get #typeDocSidebarRootDetails() {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { expect, test } from '../test'
|
||||
|
||||
const url = 'foo/functions/dofoo'
|
||||
|
||||
test('should include the TypeDoc sidebar group', async ({ docPage }) => {
|
||||
docPage.usePackagesEntryPoints()
|
||||
|
||||
await docPage.goto(url)
|
||||
|
||||
await expect(docPage.typeDocSidebarLabel).toBeVisible()
|
||||
})
|
||||
|
||||
test('should generate the proper items for for multiple entry points', async ({ docPage }) => {
|
||||
docPage.usePackagesEntryPoints()
|
||||
|
||||
await docPage.goto(url)
|
||||
|
||||
const items = await docPage.getTypeDocSidebarItems()
|
||||
|
||||
expect(items).toMatchObject([
|
||||
{
|
||||
label: 'bar',
|
||||
items: [
|
||||
{
|
||||
label: 'Functions',
|
||||
items: [{ name: 'doBar' }],
|
||||
},
|
||||
],
|
||||
collapsed: true,
|
||||
},
|
||||
{
|
||||
label: 'foo',
|
||||
items: [
|
||||
{
|
||||
label: 'Functions',
|
||||
items: [{ name: 'doFoo' }, { name: 'doFooFaster' }],
|
||||
},
|
||||
],
|
||||
collapsed: true,
|
||||
},
|
||||
])
|
||||
})
|
||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -75,6 +75,12 @@ importers:
|
||||
specifier: 5.1.6
|
||||
version: 5.1.6
|
||||
|
||||
fixtures/packages:
|
||||
dependencies:
|
||||
typescript:
|
||||
specifier: 5.1.6
|
||||
version: 5.1.6
|
||||
|
||||
packages/starlight-typedoc:
|
||||
dependencies:
|
||||
github-slugger:
|
||||
|
||||
Reference in New Issue
Block a user