Skip to content

test(repo): [DO NOT MERGE] exercise snapi breaking-change detector#8669

Open
jacekradko wants to merge 7 commits into
mainfrom
jacek/test-snapi-detection-do-not-merge
Open

test(repo): [DO NOT MERGE] exercise snapi breaking-change detector#8669
jacekradko wants to merge 7 commits into
mainfrom
jacek/test-snapi-detection-do-not-merge

Conversation

@jacekradko
Copy link
Copy Markdown
Member

@jacekradko jacekradko commented May 27, 2026

Caution

DO NOT MERGE. This PR exists only to exercise snapi's breaking-change detector against this repo. The diff intentionally introduces breaking, non-breaking, and additive API changes and is not meant to ship. Close once the report has been collected.

Mixes the three change categories the detector cares about so we can see how each is classified. Three of the original changes land under @clerk/shared/file, which is exposed via the ./* wildcard export and is currently skipped by snapi, so two more changes were added on the explicit @clerk/backend/jwt subpath to make sure the detector actually fires.

Breaking (explicit subpath, detected)

  • @clerk/backend/jwt: hasValidSignature is no longer re-exported from the subpath barrel.

Breaking (wildcard subpath, currently hidden)

  • @clerk/shared/file: readJSONFile renamed to parseJSONFile.

Non-breaking (explicit subpath, detected)

  • @clerk/backend/webhooks: VerifyWebhookOptions gains an optional timestampToleranceSeconds?: number field.

Non-breaking (wildcard subpath, currently hidden)

  • @clerk/shared/file: extension(mimeType) gains an optional fallback?: string second parameter.

Additive (explicit subpath, detected)

  • @clerk/backend/jwt: new exported type JwtAlgorithm.

Additive (wildcard subpath, currently hidden)

  • @clerk/shared/file: new exported type MimeTypeExtension.

Wildcard handling is tracked separately on the snapi side. Modeled on clerk/snapi#21, which did the same exercise against snapi itself. Changeset is intentionally empty since nothing here will be released.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 27, 2026

🦋 Changeset detected

Latest commit: 8f4036c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

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

Not sure what this means? Click here to learn what changesets are.

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

@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment May 28, 2026 2:16am

Request Review

@jacekradko jacekradko marked this pull request as ready for review May 27, 2026 17:38
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

API Changes Report

Generated by snapi on 2026-05-28T02:18:06.808Z

Summary

Metric Count
Packages analyzed 6
Packages with changes 1
🔴 Breaking changes 1
🟡 Non-breaking changes 1
🟢 Additions 1

Warning
1 breaking change(s) detected - Major version bump required

🤖 This report was reviewed by claude-sonnet-4-6.


@clerk/backend

Version: 3.4.14 → 3.4.14
Recommended bump: MAJOR

Subpath ./jwt

🔴 Breaking Changes (1)

Changed: hasValidSignature
- hasValidSignature: (jwt: import("@clerk/shared/types").Jwt, key: string | JsonWebKey) => Promise<NonNullable<boolean | undefined>>

Removed function hasValidSignature

🤖 AI review (confidence: 98%): The hasValidSignature function is entirely absent from the current API surface. Any consumer that imported and called this function will get a compile-time or runtime error.

Migration: Remove calls to hasValidSignature or inline the equivalent signature-verification logic using the available verifyJwt function instead.

🟢 Additions (1)

Added: JwtAlgorithm
+ export type JwtAlgorithm = 'HS256' | 'HS384' | 'HS512' | 'RS256' | 'RS384' | 'RS512' | 'ES256' | 'ES384' | 'ES512';

Added type alias JwtAlgorithm

Subpath ./webhooks

🟡 Non-breaking Changes (1)

Modified: VerifyWebhookOptions (reclassified from breaking)
- export type VerifyWebhookOptions = {
-     signingSecret?: string;
- };
+ export type VerifyWebhookOptions = {
+     signingSecret?: string;
+     timestampToleranceSeconds?: number;
+ };

Breaking change in type alias VerifyWebhookOptions: Type changed: {signingSecret?:string;}{signingSecret?:string;timestampToleranceSeconds?:number;}

🤖 AI review (confidence: 95%): Adding an optional field timestampToleranceSeconds?: number to an options/input type is non-breaking. Existing consumer code that passes VerifyWebhookOptions objects without this field continues to compile and work correctly, as the new field is optional. This is a widening of an input type, which is safe for callers.


Report generated by snapi

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 0889c27d-9674-4da1-84d8-44de56113f70

📥 Commits

Reviewing files that changed from the base of the PR and between bb03ddc and ba8a50d.

📒 Files selected for processing (2)
  • .changeset/snapi-enable-ai-reviewer.md
  • .github/workflows/api-changes.yml
✅ Files skipped from review due to trivial changes (1)
  • .changeset/snapi-enable-ai-reviewer.md

📝 Walkthrough

Walkthrough

This pull request refactors shared file utilities by renaming readJSONFile to parseJSONFile and enhancing the extension helper with an optional fallback parameter. It adds a timestampToleranceSeconds field to VerifyWebhookOptions for webhook verification. The JWT module exports are updated to remove hasValidSignature and introduce a new JwtAlgorithm type. The CI workflow gains explicit environment configuration for API key access, and two new changeset metadata files are introduced.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the primary change: exercising snapi's breaking-change detector with intentional test changes.
Description check ✅ Passed The description is directly related to the changeset, providing comprehensive context about the test PR's purpose and the intentional API changes being introduced.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.


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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/shared/src/file.ts (1)

12-15: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle JSON parse failures by rejecting the Promise.

At Line 13, JSON.parse can throw inside the load event callback. That exception is not converted into a Promise rejection here, which can leave callers without a proper catch path.

Suggested fix
 export function parseJSONFile(file: File): Promise<unknown> {
   return new Promise((resolve, reject) => {
     const reader = new FileReader();
     reader.addEventListener('load', function () {
-      const result = JSON.parse(reader.result as string);
-      resolve(result);
+      try {
+        const result = JSON.parse(reader.result as string);
+        resolve(result);
+      } catch (err) {
+        reject(err);
+      }
     });

     reader.addEventListener('error', reject);
     reader.readAsText(file);
   });
 }
🤖 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 `@packages/shared/src/file.ts` around lines 12 - 15, The load handler for the
FileReader currently calls JSON.parse directly and can throw without rejecting
the surrounding Promise; update the reader.addEventListener('load', function ()
{ ... }) callback to wrap JSON.parse(reader.result as string) in a try/catch and
call reject(error) when parsing fails, and also ensure you attach a
reader.addEventListener('error', ...) that calls reject with the reader.error so
the Promise rejects on both parse and read errors (referencing the existing
resolve/reject used in this module).
🧹 Nitpick comments (3)
packages/shared/src/file.ts (2)

33-37: ⚡ Quick win

Add JSDoc for newly exported public APIs.

MimeTypeExtension and extension are exported but undocumented. Please add JSDoc blocks for both public exports.

As per coding guidelines, "Maintain comprehensive JSDoc comments for public APIs" and "All public APIs must be documented with JSDoc".

🤖 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 `@packages/shared/src/file.ts` around lines 33 - 37, Add JSDoc comments for the
exported type MimeTypeExtension and the exported function extension: document
what MimeTypeExtension represents (a union type of file extensions derived from
MimeTypeToExtensionMap for SupportedMimeType) and annotate the extension
function with param and return descriptions — include `@param` for mimeType
(SupportedMimeType) and optional fallback (string), explain behavior when
mapping is missing, and include `@returns` string; place the JSDoc immediately
above the MimeTypeExtension type alias and the extension function declaration.

9-37: ⚡ Quick win

Please add tests for the renamed and behavior-changed exports.

This change renames a public function and changes extension() fallback behavior; tests should be added/updated to cover both paths.

As per coding guidelines, "If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes."

🤖 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 `@packages/shared/src/file.ts` around lines 9 - 37, The PR renamed/changed
exported behavior but has no tests; add/modify unit tests to cover the renamed
JSON parser (parseJSONFile) and the changed extension() fallback behavior:
create tests that (1) call parseJSONFile with a mock File/Blob containing valid
JSON and assert the resolved value, (2) verify extension(mime) returns the
correct mapped extension for each SupportedMimeType, and (3) verify
extension(mime, fallback) returns the provided fallback when mime is not in
MimeTypeToExtensionMap and that extension(mime) without fallback returns an
empty string; reference parseJSONFile, MimeTypeToExtensionMap,
SupportedMimeType, and extension in your tests.
packages/backend/src/webhooks.ts (1)

15-18: ⚡ Quick win

Add tests for the new webhook option contract.

Since this PR adds a new VerifyWebhookOptions field, please include tests that cover its expected behavior (including default vs explicit tolerance values).

As per coding guidelines "**/*: If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes."

🤖 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 `@packages/backend/src/webhooks.ts` around lines 15 - 18, Add unit tests
exercising the new VerifyWebhookOptions.timestampToleranceSeconds behavior:
create tests that call the webhook verification function (e.g., verifyWebhook in
packages/backend/src/webhooks.ts) with (1) no timestampToleranceSeconds to
assert the default tolerance is applied, and (2) an explicit
timestampToleranceSeconds value to assert the provided tolerance is used.
Include cases that are just inside and just outside the tolerance window to
verify acceptance/rejection behavior, and add assertions for both default vs
explicit outcomes using the same signing/timestamp fixtures.
🤖 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 `@packages/backend/src/webhooks.ts`:
- Around line 15-18: The public option timestampToleranceSeconds is defined but
unused; update the verification flow in verifyWebhook to accept and apply this
tolerance when checking the webhook timestamp against the replay-window (i.e.,
add a parameter or read the option in verifyWebhook and expand the allowed delta
by timestampToleranceSeconds when comparing now - incomingTimestamp to the
configured replayWindow), or remove/deprecate timestampToleranceSeconds from the
public API; modify the verifyWebhook function (and any callers that construct
its options) so the replay-time check uses timestampToleranceSeconds to increase
the permitted difference.

---

Outside diff comments:
In `@packages/shared/src/file.ts`:
- Around line 12-15: The load handler for the FileReader currently calls
JSON.parse directly and can throw without rejecting the surrounding Promise;
update the reader.addEventListener('load', function () { ... }) callback to wrap
JSON.parse(reader.result as string) in a try/catch and call reject(error) when
parsing fails, and also ensure you attach a reader.addEventListener('error',
...) that calls reject with the reader.error so the Promise rejects on both
parse and read errors (referencing the existing resolve/reject used in this
module).

---

Nitpick comments:
In `@packages/backend/src/webhooks.ts`:
- Around line 15-18: Add unit tests exercising the new
VerifyWebhookOptions.timestampToleranceSeconds behavior: create tests that call
the webhook verification function (e.g., verifyWebhook in
packages/backend/src/webhooks.ts) with (1) no timestampToleranceSeconds to
assert the default tolerance is applied, and (2) an explicit
timestampToleranceSeconds value to assert the provided tolerance is used.
Include cases that are just inside and just outside the tolerance window to
verify acceptance/rejection behavior, and add assertions for both default vs
explicit outcomes using the same signing/timestamp fixtures.

In `@packages/shared/src/file.ts`:
- Around line 33-37: Add JSDoc comments for the exported type MimeTypeExtension
and the exported function extension: document what MimeTypeExtension represents
(a union type of file extensions derived from MimeTypeToExtensionMap for
SupportedMimeType) and annotate the extension function with param and return
descriptions — include `@param` for mimeType (SupportedMimeType) and optional
fallback (string), explain behavior when mapping is missing, and include
`@returns` string; place the JSDoc immediately above the MimeTypeExtension type
alias and the extension function declaration.
- Around line 9-37: The PR renamed/changed exported behavior but has no tests;
add/modify unit tests to cover the renamed JSON parser (parseJSONFile) and the
changed extension() fallback behavior: create tests that (1) call parseJSONFile
with a mock File/Blob containing valid JSON and assert the resolved value, (2)
verify extension(mime) returns the correct mapped extension for each
SupportedMimeType, and (3) verify extension(mime, fallback) returns the provided
fallback when mime is not in MimeTypeToExtensionMap and that extension(mime)
without fallback returns an empty string; reference parseJSONFile,
MimeTypeToExtensionMap, SupportedMimeType, and extension in your tests.
🪄 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: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 9dd4ff24-7de6-4c52-870e-6fc8f2907940

📥 Commits

Reviewing files that changed from the base of the PR and between f76a808 and b8aa2f4.

📒 Files selected for processing (3)
  • .changeset/test-snapi-detection-do-not-merge.md
  • packages/backend/src/webhooks.ts
  • packages/shared/src/file.ts

Comment thread packages/backend/src/webhooks.ts
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 27, 2026

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8669

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8669

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8669

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8669

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@8669

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8669

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8669

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8669

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8669

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8669

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8669

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8669

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8669

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8669

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8669

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8669

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8669

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8669

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8669

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8669

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8669

commit: 8f4036c

…nd/jwt

Adds two more snapi-visible changes on an explicit (non-wildcard) subpath:
- BREAKING: drop hasValidSignature from the @clerk/backend/jwt barrel
- ADDITIVE: export a new JwtAlgorithm type from the same barrel

The existing changes to @clerk/shared/file land under the './*' wildcard
export, which the current snapi build skips, so this PR otherwise wouldn't
surface anything breaking once the snapi pin is bumped.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/backend/src/jwt/index.ts (1)

8-9: ⚡ Quick win

Add JSDoc for the new public JwtAlgorithm type export.

This adds a new public API type without API docs in packages/**/src.

Proposed patch
-export type JwtAlgorithm = 'HS256' | 'HS384' | 'HS512' | 'RS256' | 'RS384' | 'RS512' | 'ES256' | 'ES384' | 'ES512';
+/**
+ * Supported JWT signing algorithms for Clerk backend JWT helpers.
+ *
+ * `@example`
+ * const alg: JwtAlgorithm = 'RS256';
+ */
+export type JwtAlgorithm =
+  | 'HS256'
+  | 'HS384'
+  | 'HS512'
+  | 'RS256'
+  | 'RS384'
+  | 'RS512'
+  | 'ES256'
+  | 'ES384'
+  | 'ES512';

As per coding guidelines, "packages//src//*.{ts,tsx}: Maintain comprehensive JSDoc comments for public APIs" and "All public APIs must be documented with JSDoc".

🤖 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 `@packages/backend/src/jwt/index.ts` around lines 8 - 9, Add a JSDoc block for
the exported type JwtAlgorithm explaining that it represents supported JWT
signing algorithms and list the allowed string literal values ('HS256', 'HS384',
'HS512', 'RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512'); include a
one-line description, `@public` (or `@internal` if not public), and a short example
or usage note referencing where it's used (e.g., in JWT creation/verification
functions) so the public API in packages/backend/src/jwt/index.ts is documented.
🤖 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 `@packages/backend/src/jwt/index.ts`:
- Around line 8-9: Add a JSDoc block for the exported type JwtAlgorithm
explaining that it represents supported JWT signing algorithms and list the
allowed string literal values ('HS256', 'HS384', 'HS512', 'RS256', 'RS384',
'RS512', 'ES256', 'ES384', 'ES512'); include a one-line description, `@public` (or
`@internal` if not public), and a short example or usage note referencing where
it's used (e.g., in JWT creation/verification functions) so the public API in
packages/backend/src/jwt/index.ts is documented.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: de55a71e-1264-42ae-9bc6-04a4837989c5

📥 Commits

Reviewing files that changed from the base of the PR and between b8aa2f4 and c8cb9bd.

📒 Files selected for processing (2)
  • packages/backend/src/__tests__/exports.test.ts
  • packages/backend/src/jwt/index.ts
💤 Files with no reviewable changes (1)
  • packages/backend/src/tests/exports.test.ts

- drop the paths: filter on the push trigger so publish-baseline runs on every main/release-branch commit, keeping the cache that check-api restores hot.
- bump SNAPI_PACKAGE to the current snapi main HEAD; the previous pin predates subpath snapshot support, so changes on subpath exports (e.g. @clerk/backend/webhooks) were never detected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant