Skip to content

Angular: Extract Compodoc parsing into its own package - #35749

Merged
valentinpalkovic merged 1 commit into
nextfrom
valentin/sb11-angular-compodoc-package
Aug 5, 2026
Merged

valentinpalkovic merged 1 commit into
nextfrom
valentin/sb11-angular-compodoc-package

Conversation

@valentinpalkovic

@valentinpalkovic valentinpalkovic commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Closes #

What I did

The code that turns Compodoc's output into argTypes existed twice, once in each of the two Angular framework packages, as byte-identical copies. Any fix applied to one had to be remembered for the other, and in practice they drifted. This moves it into a single place both packages share.

The extracted module no longer assumes it is running in a browser. The things that differ between environments are passed in rather than reached for: the Compodoc data, the feature flag, a logger, and the helper that unwraps Compodoc's HTML-rendered JSDoc comments. Each framework's preview supplies its own.

The shared package is private and is compiled into both Angular framework packages rather than published, so nothing new appears on npm and neither package gains a runtime dependency.

Nothing about the rendered output changes. Both frameworks' existing test suites pass without being touched, and the preview still unwraps HTML the same way it always has.

This is the first of a stack of two. It stands on its own; the follow-up adds a server-side Angular docgen provider that becomes the second consumer of the extracted parsing.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

  1. Generate an Angular sandbox: yarn task --task sandbox --start-from auto --template angular-vite/default-ts
  2. Open Storybook in your browser and go to any component's Docs page
  3. Confirm the props table and Controls look exactly as they do on next, with the same descriptions and default values
  4. Repeat steps 1-3 with --template angular-cli/default-ts, since both Angular framework packages now share the extracted code

The recorded Angular docgen baselines are unchanged, so a diff in those would indicate an unintended behaviour change.

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Declare whether manual QA will be needed for this PR during the next release, through qa:needed or qa:skip

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

@valentinpalkovic valentinpalkovic added ci:normal Run our default set of CI jobs (choose this for most PRs). maintenance User-facing maintenance tasks qa:skip Pull Requests that do not need any QA. (e.g. documentation) labels Aug 4, 2026
@valentinpalkovic
valentinpalkovic marked this pull request as ready for review August 4, 2026 11:34
@valentinpalkovic
valentinpalkovic requested a review from a team August 4, 2026 11:34
@valentinpalkovic valentinpalkovic self-assigned this Aug 4, 2026
@valentinpalkovic
valentinpalkovic force-pushed the valentin/sb11-angular-compodoc-package branch from ef82271 to 4628f33 Compare August 4, 2026 11:41
@coderabbitai

coderabbitai Bot commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR adds a shared @storybook/angular-compodoc package with environment-independent parsing and a browser adapter. Angular integrations re-export the shared APIs and types through their existing import paths.

Changes

Angular Compodoc centralization

Layer / File(s) Summary
Compodoc data models
code/lib/angular-compodoc/src/compodoc-types.ts
Defines Compodoc metadata models and the aggregate CompodocJson structure.
Shared extraction and parsing logic
code/lib/angular-compodoc/src/extract-arg-types.ts
Implements validation, lookup, type extraction, default-value handling, argType generation, alias resolution, enum handling, and Angular model() synthesis.
Shared parser test suite
code/lib/angular-compodoc/src/extract-arg-types.test.ts
Tests cyclic alias termination, alias resolution to enum values, and incomplete enumeration data.
Public API entry point
code/lib/angular-compodoc/src/index.ts
Exports Compodoc models and shared validation, lookup, and extraction functions.
Browser API adapter
code/lib/angular-compodoc/src/browser.ts, code/lib/angular-compodoc/src/typings.d.ts
Reads Compodoc JSON and feature flags from Storybook globals. Supplies logging and HTML unwrapping. Exposes browser extraction APIs.
Package configuration and build registration
code/lib/angular-compodoc/package.json, code/lib/angular-compodoc/build-config.ts, code/lib/angular-compodoc/project.json, code/lib/angular-compodoc/tsconfig.json, code/lib/angular-compodoc/vitest.config.ts, code/lib/angular-compodoc/README.md, scripts/build/entry-configs.ts
Adds package metadata, project configuration, build entries, test and TypeScript configuration, documentation, and monorepo build registration.
Angular framework integration
code/frameworks/angular/src/client/compodoc.ts, code/frameworks/angular/src/client/compodoc-types.ts, code/frameworks/angular/package.json, code/frameworks/angular-vite/src/client/compodoc.ts, code/frameworks/angular-vite/src/client/compodoc-types.ts, code/frameworks/angular-vite/package.json
Both Angular integrations remove local Compodoc implementations and models. They add the shared package and preserve existing import paths through re-exports.

Sequence Diagram(s)

sequenceDiagram
  participant AngularIntegration
  participant BrowserAdapter
  participant StorybookGlobals
  participant SharedParser

  AngularIntegration->>BrowserAdapter: call extractArgTypes(component)
  BrowserAdapter->>StorybookGlobals: read Compodoc JSON and FEATURES
  BrowserAdapter->>SharedParser: call extractArgTypesFromData
  SharedParser-->>BrowserAdapter: return ArgTypes
  BrowserAdapter-->>AngularIntegration: return ArgTypes
Loading

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
code/lib/angular-compodoc/src/extract-arg-types.test.ts (1)

39-74: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the model() signal path.

The three cases cover alias and enum resolution. The most intricate logic in the module is the model() detection at lines 344-350 and the ${name}Change synthesis at lines 398-421 of extract-arg-types.ts. That logic relies on a name appearing in both inputsClass and outputsClass, which no test exercises. A regression there would change rendered arg tables silently.

Add a case where the same name exists in both arrays. Assert that the bare output row is suppressed and that <name>Change is present with category: 'outputs' and no defaultValue.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/lib/angular-compodoc/src/extract-arg-types.test.ts` around lines 39 -
74, Add a test in the extractArgTypesFromData suite that provides the same
property name in both inputsClass and outputsClass, exercising model()
detection. Assert the bare input/output row is omitted and the synthesized
<name>Change entry exists with category 'outputs' and no defaultValue.
code/lib/angular-compodoc/src/extract-arg-types.ts (1)

347-350: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

The as Property[] cast can let a method reach the synthesis block.

readMembers(componentData, 'outputsClass') returns (Method | Property)[]. The filter only compares names, then the result is cast to Property[]. Line 360 excludes methods from the suppression branch, but modelProperties keeps them. A Method entry in outputsClass whose name also exists in inputsClass would then produce summary: "(e: undefined) => void" at line 411, and the original output row would not be suppressed.

Narrow with isMethod instead of casting.

♻️ Proposed narrowing
-  const modelProperties = readMembers(componentData, 'outputsClass').filter((item) =>
-    inputClassNames.has(item.name)
-  ) as Property[];
+  const modelProperties = readMembers(componentData, 'outputsClass').filter(
+    (item): item is Property => !isMethod(item) && inputClassNames.has(item.name)
+  );

Also applies to: 398-414

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/lib/angular-compodoc/src/extract-arg-types.ts` around lines 347 - 350,
Update the modelProperties filter in the outputsClass handling to exclude
methods using the existing isMethod type guard, rather than relying on the
Property[] cast. Ensure modelPropertyNames and the later synthesis logic only
receive actual properties, while preserving the existing name-matching behavior.
code/lib/angular-compodoc/src/compodoc-types.ts (1)

28-54: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Align Class and Pipe with Compodoc output.

Class uses type: 'class' without ngname. Pipe uses type: 'pipe' with ngname. Swap the literals and move ngname to Pipe.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/lib/angular-compodoc/src/compodoc-types.ts` around lines 28 - 54, Update
the Class and Pipe interfaces in compodoc-types.ts to match Compodoc output: set
Class.type to 'class' and remove ngname, while setting Pipe.type to 'pipe' and
adding ngname. Leave the remaining properties unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/lib/angular-compodoc/README.md`:
- Around line 7-8: Update the integration contract in the README to include
unwrapHtml alongside the existing Compodoc JSON, feature flag, and logger
arguments for the root API, and state that the ./browser adapter supplies it
from the browser environment.

In `@code/lib/angular-compodoc/src/browser.ts`:
- Around line 40-41: Update unwrapHtml to return a guaranteed string by applying
a null fallback to the parsed document body's textContent, preserving the
existing HTML parsing behavior.

---

Nitpick comments:
In `@code/lib/angular-compodoc/src/compodoc-types.ts`:
- Around line 28-54: Update the Class and Pipe interfaces in compodoc-types.ts
to match Compodoc output: set Class.type to 'class' and remove ngname, while
setting Pipe.type to 'pipe' and adding ngname. Leave the remaining properties
unchanged.

In `@code/lib/angular-compodoc/src/extract-arg-types.test.ts`:
- Around line 39-74: Add a test in the extractArgTypesFromData suite that
provides the same property name in both inputsClass and outputsClass, exercising
model() detection. Assert the bare input/output row is omitted and the
synthesized <name>Change entry exists with category 'outputs' and no
defaultValue.

In `@code/lib/angular-compodoc/src/extract-arg-types.ts`:
- Around line 347-350: Update the modelProperties filter in the outputsClass
handling to exclude methods using the existing isMethod type guard, rather than
relying on the Property[] cast. Ensure modelPropertyNames and the later
synthesis logic only receive actual properties, while preserving the existing
name-matching behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 84871fc3-3c0c-4db7-a6db-cc5f79153cb9

📥 Commits

Reviewing files that changed from the base of the PR and between 6b5ca96 and ef82271.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (20)
  • code/frameworks/angular-vite/package.json
  • code/frameworks/angular-vite/src/client/compodoc-types.ts
  • code/frameworks/angular-vite/src/client/compodoc.ts
  • code/frameworks/angular/package.json
  • code/frameworks/angular/src/client/compodoc-types.ts
  • code/frameworks/angular/src/client/compodoc.ts
  • code/lib/angular-compodoc/README.md
  • code/lib/angular-compodoc/build-config.ts
  • code/lib/angular-compodoc/package.json
  • code/lib/angular-compodoc/project.json
  • code/lib/angular-compodoc/src/browser.ts
  • code/lib/angular-compodoc/src/compodoc-types.ts
  • code/lib/angular-compodoc/src/extract-arg-types.test.ts
  • code/lib/angular-compodoc/src/extract-arg-types.ts
  • code/lib/angular-compodoc/src/index.ts
  • code/lib/angular-compodoc/src/typings.d.ts
  • code/lib/angular-compodoc/tsconfig.json
  • code/lib/angular-compodoc/vitest.config.ts
  • scripts/build/entry-configs.ts
  • scripts/verdaccio.yaml
💤 Files with no reviewable changes (1)
  • scripts/verdaccio.yaml

Comment thread code/lib/angular-compodoc/README.md Outdated
Comment thread code/lib/angular-compodoc/src/browser.ts Outdated
@valentinpalkovic
valentinpalkovic force-pushed the valentin/sb11-angular-compodoc-package branch from 4628f33 to fa60c5c Compare August 4, 2026 12:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/lib/angular-compodoc/src/compodoc-types.ts`:
- Line 20: Update the Property type definition in compodoc-types.ts to allow
type to be omitted, matching extractType’s existing defaultValue-based inference
path. Preserve the current string type when provided and use the project’s
existing TypeScript optional-property conventions.
- Around line 28-54: Update the Class interface to use type 'class' and remove
ngname, and update the Pipe interface to use type 'pipe' and require ngname,
matching the Compodoc payload schemas while leaving their other fields
unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c725ffee-58ff-4046-92ac-27efdb8f69dc

📥 Commits

Reviewing files that changed from the base of the PR and between 4628f33 and fa60c5c.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (19)
  • code/frameworks/angular-vite/package.json
  • code/frameworks/angular-vite/src/client/compodoc-types.ts
  • code/frameworks/angular-vite/src/client/compodoc.ts
  • code/frameworks/angular/package.json
  • code/frameworks/angular/src/client/compodoc-types.ts
  • code/frameworks/angular/src/client/compodoc.ts
  • code/lib/angular-compodoc/README.md
  • code/lib/angular-compodoc/build-config.ts
  • code/lib/angular-compodoc/package.json
  • code/lib/angular-compodoc/project.json
  • code/lib/angular-compodoc/src/browser.ts
  • code/lib/angular-compodoc/src/compodoc-types.ts
  • code/lib/angular-compodoc/src/extract-arg-types.test.ts
  • code/lib/angular-compodoc/src/extract-arg-types.ts
  • code/lib/angular-compodoc/src/index.ts
  • code/lib/angular-compodoc/src/typings.d.ts
  • code/lib/angular-compodoc/tsconfig.json
  • code/lib/angular-compodoc/vitest.config.ts
  • scripts/build/entry-configs.ts
🚧 Files skipped from review as they are similar to previous changes (17)
  • code/frameworks/angular/package.json
  • code/frameworks/angular-vite/package.json
  • code/lib/angular-compodoc/package.json
  • code/lib/angular-compodoc/vitest.config.ts
  • code/lib/angular-compodoc/src/extract-arg-types.test.ts
  • code/frameworks/angular-vite/src/client/compodoc-types.ts
  • code/frameworks/angular-vite/src/client/compodoc.ts
  • code/frameworks/angular/src/client/compodoc.ts
  • scripts/build/entry-configs.ts
  • code/lib/angular-compodoc/README.md
  • code/lib/angular-compodoc/build-config.ts
  • code/frameworks/angular/src/client/compodoc-types.ts
  • code/lib/angular-compodoc/tsconfig.json
  • code/lib/angular-compodoc/src/typings.d.ts
  • code/lib/angular-compodoc/src/browser.ts
  • code/lib/angular-compodoc/src/extract-arg-types.ts
  • code/lib/angular-compodoc/project.json

Comment thread code/lib/angular-compodoc/src/compodoc-types.ts Outdated
Comment thread code/lib/angular-compodoc/src/compodoc-types.ts
Comment thread code/lib/angular-compodoc/src/extract-arg-types.ts
@valentinpalkovic
valentinpalkovic force-pushed the valentin/sb11-angular-compodoc-package branch from fa60c5c to d906da3 Compare August 4, 2026 13:42
Comment thread code/lib/angular-compodoc/src/compodoc-types.ts Outdated
The code that turns Compodoc's output into argTypes existed twice, once in
each of the two Angular framework packages, as byte-identical copies. Any
fix applied to one had to be remembered for the other, and in practice they
drifted. It now lives in one place both of them share.

The extracted module no longer assumes a browser. What differs between
environments is passed in rather than reached for: the Compodoc data, the
feature flag, a logger, and the helper that unwraps Compodoc's
HTML-rendered JSDoc. Each framework's preview supplies its own.

The shared package is private and compiled into both framework packages
rather than published, so nothing new appears on npm and neither package
gains a runtime dependency.

No behaviour changes. Both frameworks' existing test suites pass untouched,
and the preview still unwraps HTML with DOMParser exactly as before.
@valentinpalkovic
valentinpalkovic force-pushed the valentin/sb11-angular-compodoc-package branch 2 times, most recently from 53f1137 to 9095526 Compare August 4, 2026 19:22
@valentinpalkovic
valentinpalkovic force-pushed the valentin/sb11-angular-compodoc-package branch from 9095526 to 53f1137 Compare August 5, 2026 00:34
@valentinpalkovic
valentinpalkovic merged commit 0641ba4 into next Aug 5, 2026
150 of 156 checks passed
@valentinpalkovic
valentinpalkovic deleted the valentin/sb11-angular-compodoc-package branch August 5, 2026 12:40
@github-actions github-actions Bot mentioned this pull request Aug 5, 2026
2 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:normal Run our default set of CI jobs (choose this for most PRs). maintenance User-facing maintenance tasks qa:skip Pull Requests that do not need any QA. (e.g. documentation)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants