Skip to content

Latest commit

 

History

History
309 lines (233 loc) · 8.32 KB

File metadata and controls

309 lines (233 loc) · 8.32 KB

@datalackey/update-markdown-uml

Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files.


Terminology

This tool uses component to denote a cohesive group of TypeScript source files that live in a single directory under src/. This is the same concept Java developers know as a package — a named namespace boundary that groups related types and controls visibility. The word "package" is avoided here because in a Node/npm workspace it already means something else (a publishable npm artifact), which would create ambiguity.

What It Does

Given a TypeScript project organised into components (one directory per component under src/), this tool:

  • generates a component overview flowchart showing cross-component import dependencies
  • generates a components table with one row per component
  • generates per-component class diagrams showing classes, interfaces, and type aliases

All three sections are injected into a single Markdown file between fixed marker pairs. Running the tool again is a no-op if nothing has changed — output is fully deterministic.


Installation

npm install --save-dev @datalackey/update-markdown-uml

Usage

Place three marker pairs in the Markdown file where you want the diagrams to appear:

  <!-- UML:components:START -->
  <!-- UML:components:END -->

  <!-- UML:components-table:START -->
  <!-- UML:components-table:END -->

  <!-- UML:component-details:START -->
  <!-- UML:component-details:END -->

Then run:

npx update-markdown-uml README.md

The tool discovers src/ automatically when it exists next to the target Markdown file. Use --source <path> to override.

For CI drift detection, use --check:

npx update-markdown-uml --check README.md

Options

update-markdown-uml [options] <file>

Options:
  --source <path>                       Override source root discovery (default: src/)
  --exclude-components <cmp1,cmp2>      Leaf directory names to exclude from all output
  --test-patterns-to-skip <pat1,pat2>   Glob patterns for test files to skip during discovery
  -t <pat1,pat2>                        Short form of --test-patterns-to-skip
  --check                               Do not write; exit non-zero if content is stale
  --verbose                             Print per-component type counts
  --quiet                               Suppress all non-error output
  --debug                               Print debug diagnostics to stderr
  --help                                Show this help message and exit
  --version                             Print version and exit

This tool processes a single Markdown file per invocation. Recursive folder traversal is not supported — each UML diagram is tied to a specific source tree, so the association must be declared explicitly. For workspace-wide runs use autogen-markdown-doc.

For full documentation of shared CLI behavior (--check, --verbose, --quiet, exit codes) see Common CLI Behavior.


Example

This folder contains a sample project that demonstrates the tool's output.

Running the sample and reproducing the output you see above by actually installing and running the tool is a good way to get a feel for how it works. Copy/paste the code below to clone the sample, install dependencies, and run the tool.

To view the rendered mermaid graph you could use VSCode's built-in markdown preview, or push it to github and view it in the browser.

rm -rf /tmp/run-sample 
mkdir /tmp/run-sample 
cp -r javascript/update-markdown-uml/tests/e2e/fixtures/math-cli/* /tmp/run-sample/  
cd /tmp/run-sample/  
npm install
npx update-markdown-uml README.md
echo Load the README file into your favorite Markdown viewer. Enjoy the injected UML diagrams.

Source tree

A simple two-component project: a cli layer that delegates computation to a math-engine layer.

src/
  cli/
    AddCommand.ts
    ArgParser.ts
    CliCommand.ts
    CliRunner.ts
    CommandRegistry.ts
    ParsedArgs.ts
    SubtractCommand.ts
  math-engine/
    MathEngine.ts
    MathError.ts
    MathResult.ts
    Operation.ts

cli imports from math-engine. math-engine has no dependency on cli.

Generated output

Component overview — one subgraph per component, arrows show import direction:

flowchart TB
  subgraph cli["cli"]
  end
  subgraph math-engine["math-engine"]
  end

  cli --> math-engine
Loading

Components table — names link to the class diagram section below. Descriptions are read from an optional _COMPONENT_INFO.md file in each component directory; TBD appears when the file is absent. The description is the first sentence of the file — text up to and including the first period (.); everything after that period is ignored.

Note: if the file exists but contains no period, the description is treated as missing (TBD) and a warning is printed identifying the file. To suppress TBD without providing a description, create _COMPONENT_INFO.md with a blank first line (no period needed for an empty file).

Component Description
cli Command-line interface layer that parses arguments and dispatches math operations to the math-engine component
math-engine Code for System Backend -- which enables CLI front-end access to a suite of sophisticated math functions

Class diagrams — one per component, showing classes, interfaces, type aliases, and relationships:

cli

classDiagram
  direction TB
  class AddCommand {
    +name unknown
    +description unknown
    -engine MathEngine
    +execute(args) void
  }
  class ArgParser {
    +parse(argv) ParsedArgs
  }
  class CliCommand {
    <<interface>>
    +name string
    +description string
    +execute(args) void
  }
  class CliRunner {
    -registry CommandRegistry
    -parser ArgParser
    +run(argv) void
  }
  class CommandRegistry {
    -commands Map<string, CliCommand>
    +register(command) void
    +get(name) CliCommand | undefined
    +listAll() CliCommand[]
  }
  class ParsedArgs {
    <<interface>>
    +command "add" | "subtract"
    +a number
    +b number
  }
  class SubtractCommand {
    +name unknown
    +description unknown
    -engine MathEngine
    +execute(args) void
  }

  AddCommand ..|> CliCommand
  SubtractCommand ..|> CliCommand
Loading

math-engine

classDiagram
  direction TB
  class MathEngine {
    +add(a, b) MathResult
    +subtract(a, b) MathResult
    -validate(op, a, b) void
  }
  class MathError {
    +operation Operation
  }
  class MathResult {
    <<interface>>
    +value number
    +operation Operation
    +operands [number, number]
  }
  class Operation {
    <<type>>
  }
Loading

Side Note on How to Correct Unknown Properties

Properties initialised with a literal value and no explicit type annotation (e.g. readonly name = "add") are rendered as unknown because the tool reads TypeScript source without full type resolution. Adding an explicit annotation (readonly name: string = "add") resolves this.


Built With

For the full workspace tech stack see: TECH-STACK.md


Contributing and Releasing

For code overview, development setup, build workflow, and release procedures (including how to trigger a publish via Changesets), see CONTRIBUTING.md.