Skip to content

fix: check the file tree before the timeline reports removed types#3000

Open
thribhuvan003 wants to merge 4 commits into
npmx-dev:mainfrom
thribhuvan003:fix/timeline-types-file-check
Open

fix: check the file tree before the timeline reports removed types#3000
thribhuvan003 wants to merge 4 commits into
npmx-dev:mainfrom
thribhuvan003:fix/timeline-types-file-check

Conversation

@thribhuvan003

Copy link
Copy Markdown

The timeline computed hasTypes from packument fields only, so packages that ship declaration files next to their entry points (without a types field) showed a false "TypeScript types removed" event.

Now when a version would produce that event, the endpoint fetches its file tree and re-checks it with the same detectTypesStatus the package page uses, capped at 5 lookups per request so a timeline page never fans out. Added unit tests for the implicit-declarations case, a genuine removal, and a failed file tree lookup.

fixes #2791

@vercel

vercel Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Jul 5, 2026 7:50am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Jul 5, 2026 7:50am
npmx-lunaria Ignored Ignored Jul 5, 2026 7:50am

Request Review

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

Hello! Thank you for opening your first PR to npmx, @thribhuvan003! 🚀

Here’s what will happen next:

  1. Our GitHub bots will run to check your changes.
    If they spot any issues you will see some error messages on this PR.
    Don’t hesitate to ask any questions if you’re not sure what these mean!

  2. In a few minutes, you’ll be able to see a preview of your changes on Vercel

  3. One or more of our maintainers will take a look and may ask you to make changes.
    We try to be responsive, but don’t worry if this takes a few days.

@coderabbitai

coderabbitai Bot commented Jul 5, 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e53306a7-d87a-4b78-b36d-963b121d31ee

📥 Commits

Reviewing files that changed from the base of the PR and between 1250b7a and f8a90b7.

📒 Files selected for processing (1)
  • test/unit/server/api/registry/timeline/pkg.get.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/unit/server/api/registry/timeline/pkg.get.spec.ts

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved timeline hasTypes detection for older package versions by re-checking adjacent version metadata when it’s incomplete, preventing incorrect “types removed” emissions.
    • Added a per-request cap on version comparisons and kept pagination based on the updated version list.
    • If file-tree inspection or detection fails, the timeline now safely retains the original version data.
  • Tests

    • Expanded timeline API unit tests to cover detection from declaration-file contents, cases with none present, and graceful handling when lookups fail.

Walkthrough

The timeline endpoint now re-checks missing hasTypes values by inspecting package file trees, with a per-request cap, and the unit tests cover declaration-file presence, absence, and lookup failure.

Changes

Timeline hasTypes detection fix

Layer / File(s) Summary
File-tree based hasTypes re-check
server/api/registry/timeline/[...pkg].get.ts
Imports detectTypesStatus, defines MAX_FILE_TREE_CHECKS, and adds a bounded loop that re-checks missing hasTypes values using the package file tree, updating TimelineVersion.hasTypes on success or retaining the original value on failure.
Tests for hasTypes re-check
test/unit/server/api/registry/timeline/pkg.get.spec.ts
Adds a getPackageFileTree mock and three test cases covering declaration files present, absent, and file-tree lookup rejection scenarios.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant TimelineEndpoint
  participant PackageFileTree
  participant DetectTypesStatus

  Client->>TimelineEndpoint: GET timeline for package
  TimelineEndpoint->>TimelineEndpoint: Build and sort version list
  loop up to MAX_FILE_TREE_CHECKS
    TimelineEndpoint->>PackageFileTree: getPackageFileTree(version)
    alt lookup succeeds
      PackageFileTree-->>TimelineEndpoint: file tree
      TimelineEndpoint->>DetectTypesStatus: detectTypesStatus(fileTree)
      DetectTypesStatus-->>TimelineEndpoint: types status
      TimelineEndpoint->>TimelineEndpoint: Update hasTypes
    else lookup fails
      PackageFileTree-->>TimelineEndpoint: error
      TimelineEndpoint->>TimelineEndpoint: Keep original hasTypes
    end
  end
  TimelineEndpoint-->>Client: Paginated timeline response
Loading
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: re-checking the file tree before reporting removed types.
Description check ✅ Passed The description matches the changeset and explains the false removal event fix and added tests.
Linked Issues check ✅ Passed The implementation addresses #2791 by using file-tree type detection to avoid false 'types removed' events.
Out of Scope Changes check ✅ Passed The changes stay focused on the timeline handler and its tests, with no obvious unrelated additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 2 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
server/api/registry/timeline/[...pkg].get.ts 85.71% 0 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

@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)
server/api/registry/timeline/[...pkg].get.ts (1)

105-114: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Bound the file-tree lookups

getPackageFileTree accepts a signal, but this handler never supplies one. Add AbortSignal.timeout(...) here — or wire event.node.req close into an AbortController if you need disconnect cancellation — so a slow jsDelivr response cannot hold the request open across all MAX_FILE_TREE_CHECKS.

🤖 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 `@server/api/registry/timeline/`[...pkg].get.ts around lines 105 - 114, The
file-tree lookup in the timeline handler is not bounded, so a slow
getPackageFileTree call can keep the request open too long. Update the logic in
the [...pkg].get handler to pass an AbortSignal to getPackageFileTree,
preferably using AbortSignal.timeout(...), or wire event.node.req close into an
AbortController if you want disconnect cancellation. Keep the existing try/catch
behavior and make sure the signal is applied consistently for the
MAX_FILE_TREE_CHECKS loop.
🤖 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 `@server/api/registry/timeline/`[...pkg].get.ts:
- Around line 105-114: The file-tree lookup in the timeline handler is not
bounded, so a slow getPackageFileTree call can keep the request open too long.
Update the logic in the [...pkg].get handler to pass an AbortSignal to
getPackageFileTree, preferably using AbortSignal.timeout(...), or wire
event.node.req close into an AbortController if you want disconnect
cancellation. Keep the existing try/catch behavior and make sure the signal is
applied consistently for the MAX_FILE_TREE_CHECKS loop.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 365f9fa2-20ff-4bab-9df5-6313dc69d7b2

📥 Commits

Reviewing files that changed from the base of the PR and between e731a54 and de82b27.

📒 Files selected for processing (2)
  • server/api/registry/timeline/[...pkg].get.ts
  • test/unit/server/api/registry/timeline/pkg.get.spec.ts

@ghostdevv ghostdevv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There seems to be a util we can re-use analyzePackage, for example:

const { pkg, typesPackage, files } = await fetchPackageWithTypesAndFiles(packageName, version)
const createPackage = await findAssociatedCreatePackage(packageName, pkg)
const analysis = analyzePackage(pkg, {
typesPackage,
createPackage,
files,
})

(we don't need to pass createPackage here)

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.

Incorrect label in the timeline "Typescript types removed"

2 participants