Skip to content

Conversation

mcansh
Copy link
Owner

@mcansh mcansh commented Jul 31, 2025

Signed-off-by: GitHub noreply@github.com

mcansh added 4 commits July 30, 2025 17:15
…error handling

Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: GitHub <noreply@github.com>
Copy link

changeset-bot bot commented Jul 31, 2025

⚠️ No Changeset found

Latest commit: b60c084

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

codecov bot commented Jul 31, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (6d0ddbe) to head (b60c084).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #57      +/-   ##
==========================================
+ Coverage   93.80%   97.31%   +3.50%     
==========================================
  Files          19       21       +2     
  Lines         872     1080     +208     
  Branches      215      265      +50     
==========================================
+ Hits          818     1051     +233     
+ Misses         54       29      -25     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @mcansh, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily focuses on improving the developer experience and consistency within the monorepo by introducing a new shared configuration package for tsdown, a build tool. This centralization streamlines build setups across various packages. Concurrently, the vitest-response-matchers package has undergone a substantial refactoring to enhance its reliability, type safety, and testing capabilities. Minor tooling updates and code formatting adjustments are also included to maintain overall code quality.

Highlights

  • Centralized tsdown Configuration: Introduced a new @mcansh/config package that provides a defaultBuildConfig and a mergeBuildConfig utility. This allows other packages in the monorepo to easily adopt and extend a standardized tsdown build configuration, reducing boilerplate and ensuring consistency.
  • tsdown Integration: Updated tsdown.config.ts files in http-helmet, url, and vitest-response-matchers packages to leverage the new @mcansh/config package, simplifying their build configurations.
  • Enhanced Vitest Response Matchers: Significantly refactored the vitest-response-matchers package. This includes introducing a new utils.ts file for common helpers, updating matcher type definitions to correctly handle asynchronous operations (e.g., toHaveJsonBody, toHaveTextBody, toThrowResponse) by returning Promise<MatcherResult>, improving the robustness of existing matchers with better error handling and more comprehensive test cases, and extending toMatchResponse to support header matching.
  • Tooling and Dependency Updates: Updated various monorepo-level configurations and dependencies, including adding tsgo for type checking, integrating prettier-plugin-jsdoc for improved JSDoc formatting, and removing custom publish.js and version.js scripts (implying reliance on standard changeset or pnpm commands).
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

pkg-pr-new bot commented Jul 31, 2025

More templates

npm i https://pkg.pr.new/mcansh/packages/@mcansh/config@57
npm i https://pkg.pr.new/mcansh/packages/@mcansh/http-helmet@57
npm i https://pkg.pr.new/mcansh/packages/@mcansh/url@57
npm i https://pkg.pr.new/mcansh/packages/@mcansh/vitest-response-matchers@57

commit: b60c084

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new @mcansh/config package to centralize tsdown build configurations, which is a great step towards improving maintainability and consistency across the monorepo. The refactoring of other packages to use this new config package is well-executed and demonstrates its value.

Additionally, there are significant improvements to the @mcansh/vitest-response-matchers package, including making several matchers asynchronous for correctness and enhancing their APIs. The move to changesets for versioning and publishing by removing custom scripts is also a welcome modernization of the project's tooling.

I've identified a few areas for improvement, including a critical bug in header matching logic and a couple of high-severity issues related to package metadata and a logic regression. Addressing these will further strengthen the quality of the codebase.

Comment on lines +23 to 44
if (expected.headers) {
for (const [name, value] of Object.entries(expected.headers)) {
if (response.headers.get(name) !== value) {
return {
pass: false,
actual: {
status: response.status,
statusText: response.statusText,
headers: formatHeaders(response.headers),
},
expected: {
status: expected.status,
statusText: expected.statusText,
headers: formatHeaders(expected.headers),
},
message() {
return `Expected response to have (status: ${expected.status}, statusText: "${expected.statusText}"), but received (status: ${response.status}, statusText: "${response.statusText}")`;
},
};
}
}
}

Choose a reason for hiding this comment

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

critical

The current implementation for checking headers is incorrect. Object.entries(expected.headers) will not work as intended for Headers objects or string[][] arrays, which are valid HeadersInit types. This will cause the matcher to fail to check headers correctly in those cases.

To fix this, you should normalize expected.headers into a Headers object before iterating over it. This ensures all HeadersInit types are handled correctly. I've also improved the failure message to be more specific about which header failed.

  if (expected.headers) {
    const expectedHeaders = new Headers(expected.headers);
    for (const [name, value] of expectedHeaders.entries()) {
      if (response.headers.get(name) !== value) {
        return {
          pass: false,
          actual: {
            status: response.status,
            statusText: response.statusText,
            headers: formatHeaders(response.headers),
          },
          expected: {
            status: expected.status,
            statusText: expected.statusText,
            headers: formatHeaders(expected.headers),
          },
          message() {
            return `Expected header "${name}" to be "${value}", but got "${response.headers.get(
              name,
            )}"`;
          },
        };
      }
    }
  }

"repository": {
"type": "git",
"url": "git+https://github.com/mcansh/packages.git",
"directory": "./packages/vitest-response-matchers"

Choose a reason for hiding this comment

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

high

The repository.directory field appears to have an incorrect value. It should point to this package's directory, ./packages/config, instead of ./packages/vitest-response-matchers. This could cause issues for tools that rely on this metadata for package discovery and linking.

    "directory": "./packages/config"

Comment on lines +19 to 39
if (!isResponse(error)) {
return expectedResponseError(error);
}

if (expected.status && expected.statusText) {
return {
message: () => `Did not throw a Response`,
pass: false,
actual: error,
expected: `[Response]`,
pass:
error.status === expected.status &&
error.statusText === expected.statusText,
actual: { status: error.status, statusText: error.statusText },
expected: { status: expected.status, statusText: expected.statusText },
message: () => `Expected to throw a Response`,
};
}

let expectedResponse =
expected instanceof Response ? expected : new Response(null, expected);

return {
pass: error.status === expected.status,
actual: { status: error.status },
expected: { status: expected.status },
message: () => `Expected to throw a Response`,
pass:
error instanceof Response &&
error.status === expectedResponse.status &&
error.statusText === expectedResponse.statusText,
actual: { status: error.status, statusText: error.statusText },
expected: { status: expected.status, statusText: expected.statusText },
};

Choose a reason for hiding this comment

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

high

This refactoring introduces a regression. The previous implementation correctly handled expected as a Response object by checking both status and statusText. The new logic may only check the status if expected.statusText is an empty string (which is the default for many status codes), because if (expected.status && expected.statusText) will evaluate to false.

To restore the correct behavior, you can normalize the expected value into a Response object before performing the comparison, similar to the original implementation.

  if (!isResponse(error)) {
    return expectedResponseError(error);
  }

  const expectedResponse =
    expected instanceof Response ? expected : new Response(null, expected);

  return {
    pass:
      error.status === expectedResponse.status &&
      error.statusText === expectedResponse.statusText,
    actual: { status: error.status, statusText: error.statusText },
    expected: {
      status: expectedResponse.status,
      statusText: expectedResponse.statusText,
    },
    message: () => `Expected to throw a Response`,
  };

Comment on lines +51 to +54
let config = mergeBuildConfig((config) => {
config.dts = false;
return {};
});

Choose a reason for hiding this comment

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

medium

This test case is a bit confusing because it relies on mutating the defaultBuildConfig object. While it currently passes, this approach can be brittle and hard to reason about.

A clearer way to write this test would be to have the function return the desired configuration overrides without modifying the input object. This avoids side effects and makes the test's intent more explicit.

      let config = mergeBuildConfig(() => ({
        dts: false,
      }));

Copy link

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
packages b60c084 Commit Preview URL

Branch Preview URL
Jul 31 2025, 06:55 PM

@mcansh mcansh changed the base branch from main to dev August 5, 2025 20:03
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