Skip to content

fix(js): fix JSR doc-gen for libraries; exclude web-component packages#1733

Merged
kixelated merged 4 commits into
mainfrom
claude/jsr-libs-and-exclude-webcomponents
Jun 14, 2026
Merged

fix(js): fix JSR doc-gen for libraries; exclude web-component packages#1733
kixelated merged 4 commits into
mainfrom
claude/jsr-libs-and-exclude-webcomponents

Conversation

@kixelated

@kixelated kixelated commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Where we are

The deno-based release (run 27509033095) published 5 libraries to JSR: token, json, loc, msf, hang. It then exposed two more server-side issues (invisible to deno publish --dry-run, but reproducible with deno doc):

Issues fixed

1. Doc-gen can't resolve .ts extensions or bare . in the published .d.ts.
JSR generates the API docs by resolving the .d.ts import graph. The dist ships .js/.d.ts (no .ts), so:

  • net's export * as Connection from "./connection/index.ts"Failed resolving './connection/index.ts'
  • signals' dom.ts import ... from "."Failed resolving './/'

Fix: normalize the emitted .d.ts in package.ts - strip .ts extensions and rewrite bare ".""./index". Only declarations are touched; the .js keeps its specifiers for npm consumers. (The successful libs already used extensionless imports, which is why they worked.)

2. Web components fundamentally can't publish to JSR.
watch/publish/boy fail with modifying global types is not allowed - every custom element augments HTMLElementTagNameMap, and JSR prohibits global type modification outright (--allow-slow-types only silenced the warning). This isn't fixable without dropping the custom-element typing, so these three opt out with "jsr": false. publishJsr now honors that (still defaults on for everything else with a release script).

Validation

All 7 libraries pass deno doc locally - the exact doc generation deno publish runs - across every entrypoint in their generated jsr.json:

net: OK   signals: OK   json: OK   msf: OK   hang: OK   loc: OK   token: OK

The 3 web-component packages no longer generate a jsr.json. Biome clean.

After merge, the release should skip the 5 already-published libs, publish net + signals, and skip the 3 web components → green, with all 7 libraries on JSR.

Note on why this took several rounds

deno publish --dry-run validates packaging and slow types, but license validation and documentation generation only happen server-side at publish, so each surfaced only on a real run. deno doc reproduces the doc-gen step locally and is now part of how these were verified.

(Written by Claude)

🤖 Generated with Claude Code

Also (folded in from #1734)

The Check workflow was failing on a pre-existing docs dead link from #1732 (http://localhost:4443/certificate.sha256 in setup/windows.md). Generalized the VitePress ignoreDeadLinks localhost exemption to a regex so dev-example URLs do not break the doc build. Folded here so this PR is green on its own; #1734 closed as superseded.

The first successful deno publish run got 5 libs onto JSR (token, json, loc,
msf, hang) and exposed two more server-side issues that dry-run can't see:

1. JSR's doc generator can't resolve ".ts" import extensions (the dist ships
   .js/.d.ts) or a bare "." specifier in the published .d.ts. net used
   "./connection/index.ts" and signals' dom.ts imported from ".", so both failed
   doc generation. Normalize the emitted .d.ts: strip ".ts" extensions and turn
   "." into "./index". Only the .d.ts is touched; the .js keeps its specifiers.

2. JSR forbids modifying global types, and every custom element augments
   HTMLElementTagNameMap. So watch, publish, and boy fundamentally cannot publish
   to JSR. They opt out with "jsr": false; publishJsr now also honors that.

With this, all 7 libraries pass `deno doc` locally (the same doc generation the
publish performs) and the 3 web-component packages are excluded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 70ef9be2-6d2c-4b46-b948-8a097e7ccbea

📥 Commits

Reviewing files that changed from the base of the PR and between a4a7082 and 08e3ea9.

📒 Files selected for processing (1)
  • doc/.vitepress/config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • doc/.vitepress/config.ts

Walkthrough

The PR introduces a "jsr": false opt-out field to three package manifests (js/moq-boy, js/publish, js/watch). The JSR publish gating logic in release.ts switches from checking for a release script to checking pkg.jsr !== false. In package.ts, the gating condition is updated to require both a release script and pkg.jsr !== false, and the pkg.jsr field is explicitly cleared before writing dist/package.json. A new rewriteDtsImports() helper is added that scans dist/**/*.d.ts and rewrites import specifiers by removing .ts suffixes and normalizing bare "." imports to "./index"; this helper is called before JSR config generation steps. Additionally, the VitePress configuration is updated to ignore all localhost URLs with optional port and path instead of just the hardcoded port 5173.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly reflects the main changes: fixing JSR doc-gen for libraries and excluding web-component packages from JSR publishing.
Description check ✅ Passed The description comprehensively explains the issues fixed, solutions implemented, and validation performed, directly corresponding to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/jsr-libs-and-exclude-webcomponents

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 1

🤖 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 `@js/common/release.ts`:
- Around line 8-11: The JSR gating logic in release.ts checks only `pkg.jsr !==
false` to determine whether to publish to JSR, but package.ts requires both a
release script AND `pkg.jsr !== false` before generating jsr.json. This mismatch
causes failures when a package lacks a release script but has no explicit `jsr:
false` setting. To align the gating logic across both files, remove the release
script requirement from the jsr.json generation condition in package.ts so that
jsr.json is generated whenever `pkg.jsr !== false`, regardless of whether a
release script exists. This ensures the publishJsr constant in release.ts will
only attempt JSR publishing when the necessary jsr.json file has been generated.
🪄 Autofix (Beta)

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: 5a1b428d-b26c-4493-99f4-5fa6b209b471

📥 Commits

Reviewing files that changed from the base of the PR and between 39c1ef7 and 3f11321.

📒 Files selected for processing (5)
  • js/common/package.ts
  • js/common/release.ts
  • js/moq-boy/package.json
  • js/publish/package.json
  • js/watch/package.json

Comment thread js/common/release.ts Outdated
kixelated and others added 2 commits June 14, 2026 12:51
Use the identical predicate (release script present AND jsr !== false) in both
files so the generated manifest and the publish stay in lockstep. The
release-script clause is always true in release.ts (it is the release script),
so this is behavior-preserving; it just removes the apparent mismatch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR #1732 added an autolink to http://localhost:4443/certificate.sha256 in
setup/windows.md, which VitePress can't reach at build time, failing the doc
build (and every PR's `just ci`). Generalize the existing localhost exemption
from a single :5173 literal to a regex covering any localhost URL.

Folded in here so this PR is green on its own; supersedes #1734.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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.

🧹 Nitpick comments (1)
doc/.vitepress/config.ts (1)

264-266: ⚡ Quick win

Expand boundary check to handle query parameters and hash fragments.

The regex won't match localhost URLs with query parameters or hash fragments immediately after the port (e.g., http://localhost:5173?foo=bar or http://localhost:5173#section). While uncommon in documentation, these are valid URLs.

Changing (\/|$) to (\/|\?|#|$) would match all valid localhost URLs while still preventing false positives like http://localhost.example.com.

♻️ Suggested fix for more robust matching
-	/^https?:\/\/localhost(:\d+)?(\/|$)/,
+	/^https?:\/\/localhost(:\d+)?(\/|\?|#|$)/,
🤖 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 `@doc/.vitepress/config.ts` around lines 264 - 266, The regex pattern for
matching localhost URLs in the development examples check currently uses (\/|$)
which only matches a forward slash or end of string, but it doesn't account for
query parameters or hash fragments. Modify the regex pattern by changing (\/|$)
to (\/|\?|#|$) to match localhost URLs that may have query parameters (indicated
by ?) or hash fragments (indicated by #) immediately after the port, while still
maintaining the ability to prevent false positives like
http://localhost.example.com.
🤖 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.

Nitpick comments:
In `@doc/.vitepress/config.ts`:
- Around line 264-266: The regex pattern for matching localhost URLs in the
development examples check currently uses (\/|$) which only matches a forward
slash or end of string, but it doesn't account for query parameters or hash
fragments. Modify the regex pattern by changing (\/|$) to (\/|\?|#|$) to match
localhost URLs that may have query parameters (indicated by ?) or hash fragments
(indicated by #) immediately after the port, while still maintaining the ability
to prevent false positives like http://localhost.example.com.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bce50165-3b66-4220-9df3-453a8b615c18

📥 Commits

Reviewing files that changed from the base of the PR and between 3f11321 and a4a7082.

📒 Files selected for processing (2)
  • doc/.vitepress/config.ts
  • js/common/release.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • js/common/release.ts

@kixelated
kixelated enabled auto-merge (squash) June 14, 2026 20:18
…heck

Match a "?" or "#" right after the host/port too, so localhost example URLs with
a query string or fragment are covered. The "." that would start
localhost.example.com is still excluded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kixelated
kixelated merged commit 15e2e88 into main Jun 14, 2026
1 check passed
@kixelated
kixelated deleted the claude/jsr-libs-and-exclude-webcomponents branch June 14, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant