Skip to content

About

Mdat plugin to generate API documentation from TypeScript source files using JSDoc and type information.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

mdat-plugin-api-help

NPM Package mdat-plugin-api-help License: MIT CI

Mdat plugin to generate API documentation from TypeScript source files using JSDoc and type information.

Important

This plugin is an exploratory prototype.

Overview

This is a plugin for the mdat CLI tool, which is a simple Markdown templating system optimized for embedding dynamic content in repository readmes and the like.

This plugin documents a TypeScript package's public exports in your readme. It runs TypeDoc over the package's entry point and turns the result into Markdown that fits inside a readme: signatures with parameter and return types, JSDoc descriptions, property and parameter tables, and @example blocks. Since the documentation is read from the source, it can't drift from the implementation.

Two formats are available. The full format documents every export in detail. The compact format renders one table row per export and suits large or namespaced APIs. Both are shown below, generated from a small sample library, and the API section of this readme is generated by the plugin from its own source.

Getting started

Dependencies

  • Node.js 24.16.0 or newer (specifically ^24.16.0 || >=26.3.0)
  • mdat ^3.0.0 (peer dependency)
  • typescript ^5.0.0 || ^6.0.0 (peer dependency)

You'll need mdat installed either globally or in your project. TypeDoc uses your project's TypeScript to read your code.

Installation

Add it to your project as a development dependency:

npm install --save-dev mdat-plugin-api-help

Register the plugin in your mdat config file, e.g. mdat.config.ts:

import { defineConfig } from 'mdat'
import apiHelpPlugin from 'mdat-plugin-api-help'

export default defineConfig({
  ...apiHelpPlugin,
})

Usage

Add an <!-- api-help --> placeholder comment to your Markdown file:

<!-- api-help -->

Then run the mdat CLI from your package root to expand the placeholder into an "API" section. The plugin resolves the entry point and tsconfig.json relative to the working directory.

The rule is also aliased under the <!-- api --> keyword.

Options

Options are passed as a JSON5 object in the placeholder comment. See ApiHelpRuleOptions for the full list.

<!-- api-help({ format: 'compact', include: ['sync*', '*Options'] }) -->

Full format

Every export gets a heading, its signature with parameter and return types, its description, and tables of documented parameters or properties, followed by any @example blocks. Exports are grouped under Functions, Classes, Type Aliases, and similar headings, in source order.

Parameter and return sections that would only repeat the signature are left out, so an undocumented function takes two lines rather than twelve. Type references link to their headings when the type is documented in the same placeholder.

This is the default format.

Here's the full format applied to one function from the sample library, with groupByKind: false to skip the kind heading and heading: false to skip the section heading:

greet()

greet(name: string, options?: GreetingOptions): GreetingResult

Generate a personalized greeting.

Parameters
Parameter Type Description
name string The name of the person to greet
options? GreetingOptions Configuration for the greeting
Returns

GreetingResult

A greeting result with the message and metadata

Examples
const result = greet('World')
console.log(result.message) // "Hello, World!"
const result = greet('Professor', { formal: true })
console.log(result.message) // "Good day, Professor."

Compact format

This format creates one table row per export: the signature, the return type or definition, and the first paragraph of the description. Namespaces become nested sections with their own tables. Object types are expanded one level deep, and anything nested deeper is summarized as object.

Here's the compact format applied to the whole sample library, again with heading: false:

Functions
Function Returns Description
greet(name: string, options?: GreetingOptions) GreetingResult Generate a personalized greeting.
translate(greeting: GreetingResult, language: Language) GreetingResult Translate a greeting to a different language.
hello(name: string) string Create and immediately invoke a greeting with sensible defaults.
Classes
Class Constructor Description
GreetingGenerator new GreetingGenerator(language?: Language) A greeting generator that maintains state.
Type Aliases
Type Definition Description
GreetingOptions { formal?: boolean; maxLength?: number } Configuration options for the greeting system.
GreetingResult { message: string; timestamp: Date } A greeting result with metadata.
Language "en" | "es" | "fr" | "ja" Supported greeting languages.
Variables
Variable Type Description
MAX_GREETING_LENGTH 100 Default maximum greeting length.

Selecting exports

include and exclude take top-level export names, with * as a wildcard. A namespace is selected as a whole. Use several placeholders to document different parts of an API in different places, or to mix formats. Pass heading: false to all but the first so the section heading isn't repeated:

<!-- api-help({ format: 'compact', exclude: ['*Options'] }) -->

<!-- api-help({ include: ['*Options'], groupByKind: false, heading: false }) -->

Namespaces

Namespaces (export * as things from './things') are folded into the document under their own heading. In the full format, their members are documented under qualified names like things.list(), so headings and anchors stay unique when the same name appears in several namespaces.

Headings

The rule emits its own "API" section heading at headingLevel, which defaults to 4 for placement under a level-three "Library" section, as in mdat's readme template:

## Usage

### Library

<!-- api-help -->

#### Examples

Pass a string to heading to change the heading text, or heading: false to leave it out when you've written your own heading above the placeholder or when several placeholders share one section.

Generated headings start one level below headingLevel, whether or not the section heading is shown. Full-format output for classes can nest several levels deeper. Headings that would pass level 6 are rendered as bold text instead, which at the default level includes the Parameters, Returns, and Examples headings under each export. Pass a shallower headingLevel to keep them as headings:

<!-- api-help({ headingLevel: 2 }) -->

What's documented

Everything exported from the entry point, except private and protected class members and anything tagged @internal. Default exports are documented under their declared name, and match both that name and default in include and exclude patterns.

Types that are referenced but not exported from the entry point are shown by name without a link. TypeDoc's warnings about these are logged at the debug level, since exporting a type just for the readme's sake is often not what you want.

Entry point resolution

Without an entryPoint option, the plugin reads package.json in the working directory and tries, in order:

  1. Every path under exports["."]
  2. types
  3. main
  4. module
  5. Common defaults: src/index.ts, src/lib/index.ts, index.ts, lib/index.ts

Build output paths are mapped back to their source, so a field pointing at ./dist/index.d.ts or ./dist/lib/index.js resolves to ./src/index.ts or ./src/lib/index.ts.

Logging

The plugin logs through lognow. TypeDoc's own messages are routed through the same logger, with its informational output and validation warnings at the debug level. Pass your own logger to the exported setLogger() function to capture everything; it accepts a console-like object or a LogLayer instance.

API

ApiHelpRuleOptions

ApiHelpRuleOptions = object

Options for the <!-- api-help --> rule.

Pass them as a JSON5 object in the placeholder comment, e.g. <!-- api-help({ format: 'compact', include: ['greet', '*Options'] }) -->.

Properties

Property Type Default value Description
entryPoint? string undefined Path to the TypeScript entry point, relative to the working directory. When omitted, it's inferred from package.json (exports, types, main, module), mapping build output like ./dist/index.js back to ./src/index.ts, and finally from common defaults like src/index.ts.
exclude? string[] undefined Names of top-level exports to leave out. Supports * wildcards, e.g. ['setLogger', 'default*']. Applied after include.
format? "compact" | "full" 'full' Output style. full documents every export completely: signatures, parameter and property tables, and examples. compact renders one table row per export, with a subsection per namespace.
groupByKind? boolean true Group exports under Functions, Classes, Type Aliases, etc. headings. When false, exports are listed together in sort order.
heading? boolean | string true Section heading above the generated documentation. true emits an "API" heading, false leaves the heading out, and a string replaces the heading text.
headingLevel? number 4 Heading level for the section heading (1–6). Generated headings are nested below it, whether or not the section heading is shown. Nested headings that would exceed level 6 are rendered as bold text. The default suits placement under a level-three "Library" section, as in mdat's readme template.
include? string[] undefined Names of top-level exports to document. Supports * wildcards, e.g. ['greet', '*Options']. A namespace is included with all of its members. Everything is documented when omitted.
sort? SortStrategy[] ['source-order'] TypeDoc sort strategies applied to members, in priority order. source-order and alphabetical are the useful ones for a readme; kind, static-first, instance-first, visibility, and required-first also affect class and interface members.
tsconfig? string undefined Path to a tsconfig.json, relative to the working directory. TypeDoc finds the nearest one when omitted.

Maintainers

kitschpatrol

Contributing

Issues are welcome and appreciated.

Please open an issue to discuss changes before submitting a pull request. Unsolicited PRs (especially AI-generated ones) are unlikely to be merged.

This repository uses @kitschpatrol/shared-config (via its ksc CLI) for linting and formatting, plus MDAT for readme placeholder expansion.

License

MIT © Eric Mika

About

Mdat plugin to generate API documentation from TypeScript source files using JSDoc and type information.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages