Skip to content

Conversation

@panteliselef
Copy link
Member

@panteliselef panteliselef commented Nov 18, 2025

Description

Moves all keys into a single file, for easier discovery and maintenance.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • Refactor
    • Centralized cache key management and updated multiple hooks and hook typings to use unified stable key constants for more consistent behavior and maintainability.
  • Tests
    • Minor test updates and type casts to align with the new stable key typings.
  • Chores
    • Added a placeholder changeset file.

@panteliselef panteliselef self-assigned this Nov 18, 2025
@changeset-bot
Copy link

changeset-bot bot commented Nov 18, 2025

🦋 Changeset detected

Latest commit: 42530a0

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

vercel bot commented Nov 18, 2025

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

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Nov 18, 2025 4:27pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

A new centralized stable-keys module (STABLE_KEYS + ResourceCacheStableKey) was added. Multiple hooks and a billing helper were updated to replace hard-coded cache/resource key strings with those constants, and createCacheKeys and billing hook types were updated to use ResourceCacheStableKey. A placeholder changeset was added.

Changes

Cohort / File(s) Summary
Changeset
\.changeset/flat-grapes-visit.md
Empty placeholder changeset added
Stable Keys Module
packages/shared/src/react/stable-keys.ts
New module exporting STABLE_KEYS (const) and ResourceCacheStableKey union type
Cache Keys Configuration
packages/shared/src/react/hooks/createCacheKeys.ts
Removed generic StableKey extends string; stablePrefix parameter now typed as ResourceCacheStableKey; added import of ResourceCacheStableKey
Organization Hooks
packages/shared/src/react/hooks/useOrganization.tsx, packages/shared/src/react/hooks/useOrganizationList.tsx
Replaced hardcoded stablePrefix strings with corresponding STABLE_KEYS constants
API Keys Hook
packages/shared/src/react/hooks/useAPIKeys.ts
Replaced 'apiKeys' literal with STABLE_KEYS.API_KEYS_KEY
Billing & Payment Hooks
packages/shared/src/react/hooks/usePlans.tsx, packages/shared/src/react/hooks/useStatements.tsx, packages/shared/src/react/hooks/usePaymentAttempts.tsx, packages/shared/src/react/hooks/usePaymentMethods.tsx, packages/shared/src/react/hooks/createBillingPaginatedHook.tsx
Replaced literal resourceType/stable keys with STABLE_KEYS constants; BillingHookConfig.resourceType typed as ResourceCacheStableKey
Subscription Hooks
packages/shared/src/react/hooks/useSubscription.rq.tsx, packages/shared/src/react/hooks/useSubscription.swr.tsx
Replaced 'commerce-subscription' literal with STABLE_KEYS.SUBSCRIPTION_KEY
Tests
packages/shared/src/react/hooks/__tests__/*
Tests updated to import/cast to ResourceCacheStableKey (type-only changes) — e.g., usePagesOrInfinite.spec.ts, createBillingPaginatedHook.spec.tsx
Manifest / Misc
package.json
Manifest entries referenced by changesets/tests (no substantive runtime change)

Sequence Diagram(s)

No sequence diagram provided — changes centralize constants and adjust typings without altering runtime control flow.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • Areas to review closely:
    • Confirm STABLE_KEYS includes every previously used key and values match expected resource identifiers.
    • Verify all createCacheKeys call sites (including ones outside this diff) compile with the removed generic and new ResourceCacheStableKey typing.
    • Check callers of createBillingPaginatedHook for compatibility with resourceType: ResourceCacheStableKey.
    • Inspect tests for any runtime assumptions affected by the type-only casts.

Poem

🐰 I hopped through code and gathered keys,

tucked each string beneath small leaves.
One basket holds them, tidy and neat,
type-safe burrows for caches to meet—
a joyful rabbit hums, "Done and sweet!" 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing a stable keys registry for billing and paginated hooks, which aligns with the primary objective of moving all keys into a centralized file.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch elef/refactor-keys

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

@panteliselef panteliselef changed the title chore(share): Add stable keys registry for billing and paginated hooks chore(shared): Add stable keys registry for billing and paginated hooks Nov 18, 2025
Copy link
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: 0

🧹 Nitpick comments (1)
packages/shared/src/react/stable-keys.ts (1)

15-28: Consider consistent naming for billing keys.

The billing-related keys have inconsistent prefixing:

  • PLANS_KEY = 'plans' (no prefix)
  • SUBSCRIPTION_KEY = 'commerce-subscription' (commerce prefix)
  • PAYMENT_METHODS_KEY = 'commerce-payment-methods' (commerce prefix)
  • PAYMENT_ATTEMPTS_KEY = 'billing-payment-attempts' (billing prefix)
  • STATEMENTS_KEY = 'billing-statements' (billing prefix)

For consistency, consider either:

  1. Adding the billing- prefix to PLANS_KEY → 'billing-plans' (matches the old value and aligns with PAYMENT_ATTEMPTS_KEY, STATEMENTS_KEY)
  2. Or removing prefixes from all billing keys for brevity

This would improve predictability and reduce confusion about naming conventions.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5966383 and 95a6efe.

📒 Files selected for processing (12)
  • .changeset/flat-grapes-visit.md (1 hunks)
  • packages/shared/src/react/hooks/createCacheKeys.ts (1 hunks)
  • packages/shared/src/react/hooks/useAPIKeys.ts (2 hunks)
  • packages/shared/src/react/hooks/useOrganization.tsx (5 hunks)
  • packages/shared/src/react/hooks/useOrganizationList.tsx (4 hunks)
  • packages/shared/src/react/hooks/usePaymentAttempts.tsx (1 hunks)
  • packages/shared/src/react/hooks/usePaymentMethods.tsx (1 hunks)
  • packages/shared/src/react/hooks/usePlans.tsx (1 hunks)
  • packages/shared/src/react/hooks/useStatements.tsx (1 hunks)
  • packages/shared/src/react/hooks/useSubscription.rq.tsx (2 hunks)
  • packages/shared/src/react/hooks/useSubscription.swr.tsx (2 hunks)
  • packages/shared/src/react/stable-keys.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (10)
packages/shared/src/react/hooks/useOrganization.tsx (1)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/createCacheKeys.ts (1)
packages/shared/src/react/stable-keys.ts (1)
  • ResourceCacheStableKey (53-53)
packages/shared/src/react/hooks/usePlans.tsx (4)
packages/shared/src/react/hooks/index.ts (1)
  • usePlans (15-15)
packages/clerk-js/src/ui/contexts/components/Plans.tsx (1)
  • usePlans (80-91)
packages/shared/src/react/hooks/createBillingPaginatedHook.tsx (1)
  • createBillingPaginatedHook (73-152)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/useStatements.tsx (2)
packages/shared/src/react/hooks/createBillingPaginatedHook.tsx (1)
  • createBillingPaginatedHook (73-152)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/useOrganizationList.tsx (1)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/usePaymentAttempts.tsx (5)
packages/shared/src/react/hooks/index.ts (1)
  • usePaymentAttempts (13-13)
packages/clerk-js/src/ui/contexts/components/Plans.tsx (1)
  • usePaymentAttempts (56-59)
packages/shared/src/react/hooks/createBillingPaginatedHook.tsx (1)
  • createBillingPaginatedHook (73-152)
packages/shared/src/types/billing.ts (1)
  • GetPaymentAttemptsParams (425-425)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/useAPIKeys.ts (1)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/useSubscription.rq.tsx (1)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/usePaymentMethods.tsx (2)
packages/shared/src/react/hooks/createBillingPaginatedHook.tsx (1)
  • createBillingPaginatedHook (73-152)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
packages/shared/src/react/hooks/useSubscription.swr.tsx (1)
packages/shared/src/react/stable-keys.ts (1)
  • STABLE_KEYS (30-51)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: pr-title-lint
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (12)
.changeset/flat-grapes-visit.md (1)

1-2: Reminder: Complete the changeset description.

The changeset file is currently empty. Before merging, add a description of the changes and specify the affected packages and version bump type (patch/minor/major).

packages/shared/src/react/hooks/useSubscription.swr.tsx (1)

12-12: LGTM! Clean refactor to use centralized stable key.

The replacement of the hardcoded string literal with STABLE_KEYS.SUBSCRIPTION_KEY improves maintainability and reduces the risk of typos across the codebase.

Also applies to: 44-44

packages/shared/src/react/hooks/useStatements.tsx (1)

3-3: LGTM! Consistent use of centralized stable key.

The refactor aligns with the broader PR pattern of replacing string literals with constants from the STABLE_KEYS registry.

Also applies to: 11-11

packages/shared/src/react/hooks/useAPIKeys.ts (1)

6-6: LGTM! Proper use of the centralized stable key registry.

Replacing the hardcoded 'apiKeys' string with STABLE_KEYS.API_KEYS_KEY maintains consistency with the rest of the PR's refactoring effort.

Also applies to: 108-108

packages/shared/src/react/hooks/usePaymentMethods.tsx (1)

3-3: LGTM! Clean refactor for billing hook.

The change from 'commerce-payment-methods' to STABLE_KEYS.PAYMENT_METHODS_KEY is consistent with the centralized stable key approach across all billing hooks.

Also applies to: 11-11

packages/shared/src/react/hooks/useOrganization.tsx (1)

20-20: LGTM! Comprehensive refactor of all organization-related keys.

All four cache key replacements correctly reference the centralized STABLE_KEYS constants:

  • DOMAINS_KEY
  • MEMBERSHIP_REQUESTS_KEY
  • MEMBERSHIPS_KEY
  • INVITATIONS_KEY

This ensures consistency across the organization context.

Also applies to: 372-372, 394-394, 416-416, 438-438

packages/shared/src/react/hooks/useOrganizationList.tsx (1)

14-14: LGTM! Complete refactor of organization list keys.

All three user-related cache keys now reference the centralized constants:

  • USER_MEMBERSHIPS_KEY
  • USER_INVITATIONS_KEY
  • USER_SUGGESTIONS_KEY

This maintains consistency with the organization hooks refactor.

Also applies to: 322-322, 345-345, 367-367

packages/shared/src/react/hooks/useSubscription.rq.tsx (1)

13-13: LGTM! React Query implementation aligned with SWR.

Both the React Query and SWR implementations of useSubscription now reference the same STABLE_KEYS.SUBSCRIPTION_KEY, ensuring consistency across different data-fetching strategies.

Also applies to: 29-29

packages/shared/src/react/hooks/usePaymentAttempts.tsx (1)

3-3: LGTM! Clean refactor to centralized stable keys.

The cache key value remains unchanged ('billing-payment-attempts'), making this a safe refactor that improves maintainability and type safety.

Also applies to: 11-11

packages/shared/src/react/stable-keys.ts (1)

30-53: LGTM! Type-safe stable keys implementation.

The const assertion and type definition properly ensure type safety for cache keys across the codebase.

packages/shared/src/react/hooks/createCacheKeys.ts (1)

1-1: LGTM! Excellent type safety improvement.

Replacing the generic StableKey extends string with the concrete ResourceCacheStableKey type ensures that only values from STABLE_KEYS can be used as cache key prefixes. This prevents arbitrary strings and provides better autocomplete and compile-time validation.

Also applies to: 6-15

packages/shared/src/react/hooks/usePlans.tsx (1)

11-11: No cache key change—review comment is incorrect.

The original review comment assumed a cache key change from 'billing-plans' to 'plans', but verification shows:

  • PLANS_KEY has always been 'plans' since its creation in stable-keys.ts (commit 95a6efe)
  • No reference to 'billing-plans' exists anywhere in the codebase
  • usePlans.tsx currently and historically uses STABLE_KEYS.PLANS_KEY
  • No uncommitted changes to this file (git diff is empty)

The line shown is the current stable state, not a modification. There is no breaking change to address.

Likely an incorrect or invalid review comment.

Copy link
Member

@wobsoriano wobsoriano left a comment

Choose a reason for hiding this comment

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

🚢

Copy link
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

🧹 Nitpick comments (1)
packages/shared/src/react/hooks/__tests__/usePagesOrInfinite.spec.ts (1)

47-51: Consider supplementing with tests that use actual stable keys from the registry.

While the type assertion approach is reasonable for testing the generic behavior of usePagesOrInfinite, the test suite would benefit from also including test cases that use actual STABLE_KEYS constants. This would:

  • Validate that the integration with the new stable keys registry works correctly in practice
  • Catch potential issues if the registry structure or type definition changes
  • Align the tests more closely with how the hook is used in production code (where other files use STABLE_KEYS constants instead of arbitrary strings)

Consider adding a few test cases like:

import { STABLE_KEYS } from '../../stable-keys';

// Example test case using actual stable key
it('works with actual stable keys from registry', async () => {
  const fetcher = vi.fn(async (p: any) => ({
    data: [{ id: 'item-1' }],
    total_count: 1,
  }));

  const params = { initialPage: 1, pageSize: 10 };
  const config = buildConfig(params);
  // Use actual stable key without casting
  const keys = createCacheKeys({
    stablePrefix: STABLE_KEYS.ORGANIZATIONS, // or another appropriate key
    authenticated: true,
    tracked: {},
    untracked: { args: params },
  });

  const { result } = renderUsePagesOrInfinite({ fetcher, config, keys });
  await waitFor(() => expect(result.current.isLoading).toBe(false));
  expect(result.current.data).toHaveLength(1);
});
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 95a6efe and 719bb7c.

📒 Files selected for processing (2)
  • packages/shared/src/react/hooks/__tests__/usePagesOrInfinite.spec.ts (2 hunks)
  • packages/shared/src/react/hooks/createBillingPaginatedHook.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/shared/src/react/hooks/__tests__/usePagesOrInfinite.spec.ts (1)
packages/shared/src/react/stable-keys.ts (1)
  • ResourceCacheStableKey (53-53)
packages/shared/src/react/hooks/createBillingPaginatedHook.tsx (1)
packages/shared/src/react/stable-keys.ts (1)
  • ResourceCacheStableKey (53-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
packages/shared/src/react/hooks/__tests__/usePagesOrInfinite.spec.ts (1)

5-5: LGTM!

The import is correctly added to support the new ResourceCacheStableKey type.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 18, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7248

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@7248

@clerk/clerk-expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/clerk-react

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

@clerk/react-router

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

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@7248

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@7248

@clerk/types

npm i https://pkg.pr.new/@clerk/types@7248

@clerk/upgrade

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

@clerk/vue

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

commit: 42530a0

Copy link
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: 0

🧹 Nitpick comments (1)
packages/shared/src/react/hooks/__tests__/createBillingPaginatedHook.spec.tsx (1)

37-37: Consider using a valid stable key or creating a test constant.

The type assertions 'dummy' as ResourceCacheStableKey bypass the type system's constraint that resourceType should be a valid key from the STABLE_KEYS registry. While acceptable for test code, this undermines the type safety introduced by the centralized keys registry.

Consider one of these approaches:

  1. Use an actual stable key from STABLE_KEYS if appropriate for testing
  2. Export a dedicated test constant (e.g., TEST_RESOURCE_KEY) from stable-keys.ts
  3. Add a comment explaining why the type assertion is acceptable in this test context

Apply this diff to add clarifying comments:

 const useDummyAuth = createBillingPaginatedHook<DummyResource, DummyParams>({
   hookName: 'useDummyAuth',
+  // Note: 'dummy' is used for testing purposes only and is not a real stable key
   resourceType: 'dummy' as ResourceCacheStableKey,
   useFetcher: useFetcherMock,
 });

 const useDummyUnauth = createBillingPaginatedHook<DummyResource, DummyParams>({
   hookName: 'useDummyUnauth',
+  // Note: 'dummy' is used for testing purposes only and is not a real stable key
   resourceType: 'dummy' as ResourceCacheStableKey,
   useFetcher: useFetcherMock,
   options: { unauthenticated: true },
 });

Also applies to: 43-43

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 719bb7c and 42530a0.

📒 Files selected for processing (2)
  • packages/shared/src/react/hooks/__tests__/createBillingPaginatedHook.spec.tsx (2 hunks)
  • packages/shared/src/react/stable-keys.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/shared/src/react/stable-keys.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/shared/src/react/hooks/__tests__/createBillingPaginatedHook.spec.tsx (2)
packages/shared/src/react/stable-keys.ts (1)
  • ResourceCacheStableKey (53-53)
packages/shared/src/react/hooks/createBillingPaginatedHook.tsx (1)
  • createBillingPaginatedHook (74-153)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
packages/shared/src/react/hooks/__tests__/createBillingPaginatedHook.spec.tsx (1)

5-5: LGTM!

The import is necessary for the type casting applied to the test hooks.

@panteliselef panteliselef merged commit 66fdeb4 into main Nov 18, 2025
76 of 77 checks passed
@panteliselef panteliselef deleted the elef/refactor-keys branch November 18, 2025 16:51
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.

3 participants