Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/mighty-frogs-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ package-lock.json
pnpm-lock.yaml
playground
packages/backend/tests/**/*.js
packages/clerk-js/src/core/resources/internal.ts
packages/clerk-js/src/core/resources/index.ts
/**/CHANGELOG.md
renovate.json5
3 changes: 2 additions & 1 deletion packages/clerk-js/src/core/__tests__/clerk.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EmailLinkErrorCodeStatus } from '@clerk/shared/error';
import type {
ActiveSessionResource,
PendingSessionResource,
Expand All @@ -13,7 +14,7 @@ import type { DevBrowser } from '../auth/devBrowser';
import { Clerk } from '../clerk';
import { eventBus, events } from '../events';
import type { DisplayConfig, Organization } from '../resources/internal';
import { BaseResource, Client, EmailLinkErrorCodeStatus, Environment, SignIn, SignUp } from '../resources/internal';
import { BaseResource, Client, Environment, SignIn, SignUp } from '../resources/internal';
import { mockJwt } from '../test/fixtures';

const mockClientFetch = jest.fn();
Expand Down
19 changes: 9 additions & 10 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { inBrowser as inClientSide, isValidBrowserOnline } from '@clerk/shared/browser';
import { clerkEvents, createClerkEventBus } from '@clerk/shared/clerkEventBus';
import { deprecated } from '@clerk/shared/deprecated';
import { ClerkRuntimeError, EmailLinkErrorCodeStatus, is4xxError, isClerkAPIResponseError } from '@clerk/shared/error';
import {
ClerkRuntimeError,
EmailLinkError,
EmailLinkErrorCodeStatus,
is4xxError,
isClerkAPIResponseError,
isClerkRuntimeError,
} from '@clerk/shared/error';
Comment on lines +4 to +11
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

🧩 Analysis chain

Import migration to @clerk/shared/error looks correct; verify all symbols exist (esp. is4xxError).

This decouples core from internal Error resources. Please double‑check no lingering imports remain from core/resources/Error and that @clerk/shared/error exports all referenced symbols.

Run:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Any lingering deep imports to core/resources/Error?"
rg -nP -C2 "['\"][^'\"]*core/resources/Error['\"]" --type=ts --type=tsx || true

echo
echo "2) Any error symbols still imported from resources/internal?"
rg -nP --type=ts --type=tsx -C2 "from\s+['\"][^'\"]*resources/internal['\"]" | rg -nP "(ClerkRuntimeError|ClerkAPIResponseError|EmailLinkError|EmailLinkErrorCode|EmailLinkErrorCodeStatus|isClerkAPIResponseError|isClerkRuntimeError|isEmailLinkError|isKnownError|isMetamaskError|isUserLockedError|MetamaskError)" || true

echo
echo "3) Confirm shared/error actually exports the migrated symbols"
rg -nP -C2 "export\s+(?:type\s+)?(?:class|function|const|let|var|interface|type)?\s*(ClerkRuntimeError|ClerkAPIResponseError|EmailLinkError|EmailLinkErrorCode|EmailLinkErrorCodeStatus|isClerkAPIResponseError|isClerkRuntimeError|isEmailLinkError|isKnownError|isMetamaskError|isUserLockedError|MetamaskError)" packages -g '!**/dist/**' -g '!**/build/**' || true

Length of output: 235


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Any lingering deep imports to core/resources/Error?"
rg -n -C2 "core/resources/Error" || echo "no matches"

echo
echo "2) Any imports from resources/internal that reference error symbols?"
rg -n -C2 "from\s+['\"][^'\"]*resources/internal['\"]" || echo "no imports from resources/internal"

echo
echo "Filter those imports for known error symbols (if any):"
rg -n -C2 "from\s+['\"][^'\"]*resources/internal['\"]" | rg -nP "(ClerkRuntimeError|ClerkAPIResponseError|EmailLinkError|EmailLinkErrorCode|EmailLinkErrorCodeStatus|isClerkAPIResponseError|isClerkRuntimeError|isEmailLinkError|isKnownError|isMetamaskError|isUserLockedError|MetamaskError|is4xxError)" || echo "no filtered matches"

echo
echo "3) Search repo for definitions/exports/usages of the migrated symbols (including is4xxError):"
symbols=(ClerkRuntimeError ClerkAPIResponseError EmailLinkError EmailLinkErrorCode EmailLinkErrorCodeStatus isClerkAPIResponseError isClerkRuntimeError isEmailLinkError isKnownError isMetamaskError isUserLockedError MetamaskError is4xxError)
for s in "${symbols[@]}"; do
  echo "---- ${s} ----"
  rg -n -S -g '!**/dist/**' -g '!**/build/**' "\b${s}\b" || echo "no matches for ${s}"
done

echo
echo "4) Any direct imports from '@clerk/shared/error' (sanity check)?"
rg -n -C2 "from\s+['\"]@clerk/shared/error['\"]" || echo "no direct imports from @clerk/shared/error"

Length of output: 35678


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "A) package.json entries with @clerk/shared in the name"
rg -nP '"name"\s*:\s*"(?:@clerk/shared(?:/error)?)"' packages || echo "no package.json matched"

echo
echo "B) find directories named 'shared' or 'error' under packages (depth 3)"
find packages -maxdepth 3 -type d \( -name shared -o -name error \) -print || true

echo
echo "C) show packages/shared/error if present"
if [ -d packages/shared/error ]; then
  echo "== packages/shared/error exists =="
  ls -la packages/shared/error || true
  if [ -f packages/shared/error/src/index.ts ]; then
    echo "=== packages/shared/error/src/index.ts ==="
    sed -n '1,240p' packages/shared/error/src/index.ts || true
  fi
fi

echo
echo "D) locate potential definitions of is4xxError"
rg -nP "^(export\s+)?(const|function)\s+is4xxError\b|is4xxError\s*=" packages || echo "no direct definition matches for is4xxError"

echo
echo "E) search for explicit exports of main error symbols (may be re-exports)"
symbols=(is4xxError ClerkAPIResponseError ClerkRuntimeError EmailLinkError EmailLinkErrorCodeStatus parseError parseErrors buildErrorThrower isNetworkError)
for s in "${symbols[@]}"; do
  echo "---- ${s} ----"
  rg -nP "export\s+(?:type\s+)?(?:class|function|const|let|var|interface|type)\s+${s}\b|export\s*\{[^}]*\b${s}\b[^}]*\}" packages || echo "no export match for ${s}"
done

Length of output: 2625


Import migration verified — shared exports present; fix leftover internal/deep imports

packages/shared exports all referenced symbols (is4xxError in packages/shared/src/errors/helpers.ts; re-exports in packages/shared/src/error.ts). Update remaining files that still import from core/resources/Error or resources/internal to import from '@clerk/shared/error':

  • packages/clerk-js/src/utils/tests/errors.spec.ts — imports ClerkAPIResponseError from '../../core/resources/Error'
  • packages/clerk-js/src/core/fraudProtection.spec.ts — imports ClerkAPIResponseError from './resources/internal'
  • packages/clerk-js/src/core/tests/clerk.test.ts — imports EmailLinkErrorCodeStatus from '../resources/internal'
🤖 Prompt for AI Agents
packages/clerk-js/src/core/clerk.ts (lines 4-11) and related files still use
deep/internal imports; update them to use the public shared export. Replace the
deep import paths in the following files so they import the listed symbols from
'@clerk/shared/error' instead of internal paths:
packages/clerk-js/src/utils/__tests__/errors.spec.ts — import
ClerkAPIResponseError from '@clerk/shared/error' instead of
'../../core/resources/Error'; packages/clerk-js/src/core/fraudProtection.spec.ts
— import ClerkAPIResponseError from '@clerk/shared/error' instead of
'./resources/internal'; packages/clerk-js/src/core/__tests__/clerk.test.ts —
import EmailLinkErrorCodeStatus (and any other error symbols) from
'@clerk/shared/error' instead of '../resources/internal'; run tests and adjust
named imports if any export names differ.

import { parsePublishableKey } from '@clerk/shared/keys';
import { LocalStorageBroadcastChannel } from '@clerk/shared/localStorageBroadcastChannel';
import { logger } from '@clerk/shared/logger';
Expand Down Expand Up @@ -149,15 +156,7 @@ import { createClientFromJwt } from './jwt-client';
import { APIKeys } from './modules/apiKeys';
import { Billing } from './modules/billing';
import { createCheckoutInstance } from './modules/checkout/instance';
import {
BaseResource,
Client,
EmailLinkError,
Environment,
isClerkRuntimeError,
Organization,
Waitlist,
} from './resources/internal';
import { BaseResource, Client, Environment, Organization, Waitlist } from './resources/internal';
import { getTaskEndpoint, navigateIfTaskExists, warnMissingPendingTaskHandlers } from './sessionTasks';
import { State } from './state';
import { warnings } from './warnings';
Expand Down
2 changes: 1 addition & 1 deletion packages/clerk-js/src/core/fraudProtection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ClerkAPIResponseError } from '@clerk/shared/error';
import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest';

import { FraudProtection } from './fraudProtection';
import type { Clerk, Client } from './resources/internal';
import { ClerkAPIResponseError } from './resources/internal';

describe('FraudProtectionService', () => {
let sut: FraudProtection;
Expand Down
4 changes: 3 additions & 1 deletion packages/clerk-js/src/core/fraudProtection.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ClerkRuntimeError, isClerkAPIResponseError } from '@clerk/shared/error';

import { CaptchaChallenge } from '../utils/captcha/CaptchaChallenge';
import type { Clerk } from './resources/internal';
import { ClerkRuntimeError, Client, isClerkAPIResponseError } from './resources/internal';
import { Client } from './resources/internal';

export class FraudProtection {
private static instance: FraudProtection;
Expand Down
3 changes: 2 additions & 1 deletion packages/clerk-js/src/core/modules/apiKeys/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ClerkRuntimeError } from '@clerk/shared/error';
import type {
ApiKeyJSON,
APIKeyResource,
Expand All @@ -9,7 +10,7 @@ import type {

import type { FapiRequestInit } from '@/core/fapiClient';

import { APIKey, BaseResource, ClerkRuntimeError } from '../../resources/internal';
import { APIKey, BaseResource } from '../../resources/internal';

export class APIKeys implements APIKeysNamespace {
/**
Expand Down
3 changes: 2 additions & 1 deletion packages/clerk-js/src/core/resources/Base.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { isValidBrowserOnline } from '@clerk/shared/browser';
import { ClerkAPIResponseError, ClerkRuntimeError } from '@clerk/shared/error';
import { isProductionFromPublishableKey } from '@clerk/shared/keys';
import type { ClerkAPIErrorJSON, ClerkResourceJSON, ClerkResourceReloadParams, DeletedObjectJSON } from '@clerk/types';

import { clerkMissingFapiClientInResources } from '../errors';
import type { FapiClient, FapiRequestInit, FapiResponse, FapiResponseJSON, HTTPMethod } from '../fapiClient';
import { FraudProtection } from '../fraudProtection';
import type { Clerk } from './internal';
import { ClerkAPIResponseError, ClerkRuntimeError, Client } from './internal';
import { Client } from './internal';

export type BaseFetchOptions = ClerkResourceReloadParams & {
forceUpdateClient?: boolean;
Expand Down
3 changes: 2 additions & 1 deletion packages/clerk-js/src/core/resources/BillingCheckout.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isClerkAPIResponseError } from '@clerk/shared/error';
import { retry } from '@clerk/shared/retry';
import type {
BillingCheckoutJSON,
Expand All @@ -12,7 +13,7 @@ import { unixEpochToDate } from '@/utils/date';

import { billingTotalsFromJSON } from '../../utils';
import { BillingPayer } from './BillingPayer';
import { BaseResource, BillingPaymentSource, BillingPlan, isClerkAPIResponseError } from './internal';
import { BaseResource, BillingPaymentSource, BillingPlan } from './internal';

export class BillingCheckout extends BaseResource implements BillingCheckoutResource {
id!: string;
Expand Down
14 changes: 0 additions & 14 deletions packages/clerk-js/src/core/resources/Error.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/clerk-js/src/core/resources/SignUp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isCaptchaError, isClerkAPIResponseError } from '@clerk/shared/error';
import { ClerkRuntimeError, isCaptchaError, isClerkAPIResponseError } from '@clerk/shared/error';
import { Poller } from '@clerk/shared/poller';
import type {
AttemptEmailAddressVerificationParams,
Expand Down Expand Up @@ -63,7 +63,7 @@ import {
clerkVerifyWeb3WalletCalledBeforeCreate,
} from '../errors';
import { eventBus } from '../events';
import { BaseResource, ClerkRuntimeError, SignUpVerifications } from './internal';
import { BaseResource, SignUpVerifications } from './internal';

declare global {
interface Window {
Expand Down
4 changes: 2 additions & 2 deletions packages/clerk-js/src/core/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export * from './DeletedObject';
export * from './DisplayConfig';
export * from './EmailAddress';
export * from './Environment';
export * from './Error';
export * from './ExternalAccount';
export * from './IdentificationLink';
export * from './Image';
Expand All @@ -17,5 +16,6 @@ export * from './SignUp';
export * from './Token';
export * from './User';
export * from './Verification';
export * from './Web3Wallet';
export * from './Waitlist';
export * from './Web3Wallet';

3 changes: 1 addition & 2 deletions packages/clerk-js/src/core/resources/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export * from './DeletedObject';
export * from './DisplayConfig';
export * from './EmailAddress';
export * from './Environment';
export * from './Error';
export * from './ExternalAccount';
export * from './EnterpriseAccount';
export * from './IdentificationLink';
Expand All @@ -40,6 +39,6 @@ export * from './TOTP';
export * from './User';
export * from './UserOrganizationInvitation';
export * from './Verification';
export * from './Web3Wallet';
export * from './Web3Wallet';
export * from './Waitlist';
export * from './APIKey';
15 changes: 14 additions & 1 deletion packages/clerk-js/src/index.headless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,20 @@ import 'regenerator-runtime/runtime';

import { Clerk } from './core/clerk';

export * from './core/resources/Error';
export {
ClerkAPIResponseError,
ClerkRuntimeError,
EmailLinkError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
isClerkAPIResponseError,
isClerkRuntimeError,
isEmailLinkError,
isKnownError,
isMetamaskError,
isUserLockedError,
type MetamaskError,
} from '@clerk/shared/error';

export { Clerk };

Expand Down
17 changes: 15 additions & 2 deletions packages/clerk-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,23 @@ import 'regenerator-runtime/runtime';
import { Clerk } from './core/clerk';
import { mountComponentRenderer } from './ui/Components';

export * from './core/resources/Error';
export {
ClerkAPIResponseError,
ClerkRuntimeError,
EmailLinkError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
isClerkAPIResponseError,
isClerkRuntimeError,
isEmailLinkError,
isKnownError,
isMetamaskError,
isUserLockedError,
type MetamaskError,
} from '@clerk/shared/error';
export { Clerk };

Clerk.mountComponentRenderer = mountComponentRenderer;
export { Clerk };

if (module.hot) {
module.hot.accept();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { ClerkAPIResponseError } from '@clerk/shared/error';
import type { OrganizationInvitationResource } from '@clerk/types';
import { describe } from '@jest/globals';
import { waitFor } from '@testing-library/dom';
import React from 'react';

import { ClerkAPIResponseError } from '../../../../core/resources';
import { render } from '../../../../testUtils';
import { Action } from '../../../elements/Action';
import { clearFetchCache } from '../../../hooks';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { parseError } from '@clerk/shared/error';
import { ClerkAPIResponseError, parseError } from '@clerk/shared/error';
import type { SignInResource } from '@clerk/types';
import { describe, it, jest } from '@jest/globals';
import { waitFor } from '@testing-library/dom';

import { ClerkAPIResponseError } from '../../../../core/resources';
import { act, mockWebAuthn, render, screen } from '../../../../testUtils';
import { bindCreateFixtures } from '../../../utils/test/createFixtures';
import { runFakeTimers } from '../../../utils/test/runFakeTimers';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { parseError } from '@clerk/shared/error';
import { ClerkAPIResponseError, parseError } from '@clerk/shared/error';
import type { SignInResource } from '@clerk/types';
import { describe, it, jest } from '@jest/globals';

import { ClerkAPIResponseError } from '../../../../core/resources';
import { render, screen, waitFor } from '../../../../testUtils';
import { bindCreateFixtures } from '../../../utils/test/createFixtures';
import { runFakeTimers } from '../../../utils/test/runFakeTimers';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ClerkAPIResponseError } from '@clerk/shared/error';
import { OAUTH_PROVIDERS } from '@clerk/shared/oauth';
import type { SignInResource } from '@clerk/types';
import { waitFor } from '@testing-library/react';

import { CardStateProvider } from '@/ui/elements/contexts';

import { ClerkAPIResponseError } from '../../../../core/resources';
import { fireEvent, mockWebAuthn, render, screen } from '../../../../testUtils';
import { OptionsProvider } from '../../../contexts';
import { AppearanceProvider } from '../../../customizables';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { EmailLinkError, EmailLinkErrorCodeStatus } from '@clerk/shared/error';

import { EmailLinkError, EmailLinkErrorCodeStatus } from '../../../../core/resources';
import { render, runFakeTimers, screen, waitFor } from '../../../../testUtils';
import { SignUpEmailLinkFlowComplete } from '../../../common/EmailLinkCompleteFlowCard';
import { bindCreateFixtures } from '../../../utils/test/createFixtures';
Expand Down
7 changes: 1 addition & 6 deletions packages/clerk-js/src/ui/utils/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { isClerkAPIResponseError, isClerkRuntimeError, isKnownError, isMetamaskError } from '@clerk/shared/error';
import { snakeToCamel } from '@clerk/shared/underscore';
import type { ClerkAPIError, ClerkRuntimeError } from '@clerk/types';

import {
isClerkAPIResponseError,
isClerkRuntimeError,
isKnownError,
isMetamaskError,
} from '../../core/resources/internal';
import type { FormControlState } from './useFormControl';

interface ParserErrors {
Expand Down
2 changes: 1 addition & 1 deletion packages/clerk-js/src/utils/__tests__/errors.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ClerkAPIResponseError } from '@clerk/shared/error';
import { describe, expect, it } from 'vitest';

import type { ClerkAPIResponseError } from '../../core/resources/Error';
import { isError } from '../errors';

describe('isError(err, code)', () => {
Expand Down
3 changes: 1 addition & 2 deletions packages/clerk-js/src/utils/errors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { ClerkAPIResponseError } from '@clerk/shared/error';
import type { ClerkAPIError } from '@clerk/types';

import type { ClerkAPIResponseError } from '../core/resources/internal';

export function isError(err: ClerkAPIResponseError, code = ''): boolean {
return err.errors && !!err.errors.find((e: ClerkAPIError) => e.code === code);
}
Loading