Skip to content

Commit 12e7473

Browse files
committed
merge main and resolve conflicts in packages/testing
2 parents 54779df + 829583a commit 12e7473

15 files changed

Lines changed: 380 additions & 33 deletions

File tree

.changeset/nuxt-derive-api-url.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@clerk/nuxt": patch
3+
---
4+
5+
Derive `apiUrl` from the publishable key using `apiUrlFromPublishableKey()`, matching the behavior of other Clerk SDKs (`@clerk/nextjs`, `@clerk/astro`, etc.). Staging publishable keys (with `.accountsstage.dev`) now automatically route to `https://api.clerkstage.dev` without requiring a manual `NUXT_PUBLIC_CLERK_API_URL` override. Explicit `apiUrl` configuration still takes priority.

.changeset/retry-testing-token.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@clerk/testing": patch
3+
---
4+
5+
Add retry logic with exponential backoff for testing token fetch on 429 and 5xx responses.

.changeset/silent-hotels-draw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/localizations': patch
3+
---
4+
5+
Added missing Bulgarian translations for `UserProfile` component

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,9 @@ jobs:
274274

275275
integration-tests:
276276
needs: [check-permissions, build-packages]
277-
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
277+
if: >-
278+
${{ (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
279+
&& (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
278280
name: Integration Tests (${{ matrix.test-name }}, ${{ matrix.test-project }}${{ matrix.next-version && format(', {0}', matrix.next-version) || '' }})
279281
permissions:
280282
contents: read

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
<a href="https://discord.com/invite/b5rXHjAg7A">
1818
<img alt="Discord" src="https://img.shields.io/discord/856971667393609759?color=7389D8&label&logo=discord&logoColor=ffffff" />
1919
</a>
20-
<a href="https://twitter.com/clerkdev">
21-
<img alt="Twitter" src="https://img.shields.io/twitter/url.svg?label=%40clerkdev&style=social&url=https%3A%2F%2Ftwitter.com%2Fclerkdev" />
20+
<a href="https://twitter.com/clerk">
21+
<img alt="Twitter" src="https://img.shields.io/twitter/url.svg?label=%40clerk&style=social&url=https%3A%2F%2Ftwitter.com%2Fclerk" />
2222
</a>
2323
<br />
2424
<br />

integration/testUtils/keylessHelpers.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,9 @@ export async function testClaimedAppWithMissingKeys({
8383
expect(await u.po.keylessPopover.isExpanded()).toBe(true);
8484
await expect(u.po.keylessPopover.promptToUseClaimedKeys()).toBeVisible();
8585

86-
const [newPage] = await Promise.all([
87-
context.waitForEvent('page'),
88-
u.po.keylessPopover.promptToUseClaimedKeys().click(),
89-
]);
90-
91-
await newPage.waitForLoadState();
92-
await newPage.waitForURL(url => {
93-
return url.href.startsWith(`${dashboardUrl}sign-in?redirect_url=${encodeURIComponent(dashboardUrl)}apps%2Fapp_`);
94-
});
86+
const href = await u.po.keylessPopover.promptToUseClaimedKeys().getAttribute('href');
87+
expect(href).toBeTruthy();
88+
expect(href).toContain(dashboardUrl);
9589
}
9690

9791
/**

integration/tests/next-quickstart-keyless.test.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,9 @@ test.describe('Keyless mode @quickstart', () => {
7272
expect(await u.po.keylessPopover.isExpanded()).toBe(true);
7373
await expect(u.po.keylessPopover.promptToUseClaimedKeys()).toBeVisible();
7474

75-
const [newPage] = await Promise.all([
76-
context.waitForEvent('page'),
77-
u.po.keylessPopover.promptToUseClaimedKeys().click(),
78-
]);
79-
80-
await newPage.waitForLoadState();
81-
await newPage.waitForURL(url => {
82-
return url.href.startsWith(`${dashboardUrl}sign-in?redirect_url=${encodeURIComponent(dashboardUrl)}apps%2Fapp_`);
83-
});
75+
const href = await u.po.keylessPopover.promptToUseClaimedKeys().getAttribute('href');
76+
expect(href).toBeTruthy();
77+
expect(href).toContain(dashboardUrl);
8478
});
8579

8680
test('Claimed application with keys inside .env, on dismiss, keyless prompt is removed.', async ({

packages/localizations/src/bg-BG.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,21 +1202,21 @@ export const bgBG: LocalizationResource = {
12021202
formButton: undefined,
12031203
formSubtitle: undefined,
12041204
},
1205-
formHint: undefined,
1205+
formHint: `Ще трябва да потвърдите този имейл адрес преди да бъде добавен към вашия профил.`,
12061206
removeResource: {
12071207
messageLine1: '{{identifier}} ще бъде премахнат от този профил.',
12081208
messageLine2: 'Няма да можете да влезете в профила си, използвайки този имейл адрес.',
12091209
successMessage: '{{emailAddress}} беше премахнат от вашия профил.',
12101210
title: 'Премахни имейл адрес',
12111211
},
12121212
title: 'Добави имейл адрес',
1213-
verifyTitle: 'Verify email address',
1213+
verifyTitle: 'Потвърди имейл адрес',
12141214
},
1215-
formButtonPrimary__add: 'Add',
1215+
formButtonPrimary__add: 'Добави',
12161216
formButtonPrimary__continue: 'Продължи',
12171217
formButtonPrimary__finish: 'Завърши',
1218-
formButtonPrimary__remove: 'Remove',
1219-
formButtonPrimary__save: 'Save',
1218+
formButtonPrimary__remove: 'Премахни',
1219+
formButtonPrimary__save: 'Запази',
12201220
formButtonReset: 'Откажи',
12211221
mfaPage: {
12221222
formHint: 'Изберете метод, който да добавите.',
@@ -1269,11 +1269,11 @@ export const bgBG: LocalizationResource = {
12691269
},
12701270
mobileButton__menu: 'Меню',
12711271
navbar: {
1272-
account: 'Profile',
1272+
account: 'Профил',
12731273
apiKeys: undefined,
12741274
billing: undefined,
12751275
description: 'Управлявайте информацията в профила си.',
1276-
security: 'Security',
1276+
security: 'Сигурност',
12771277
title: 'Профил',
12781278
},
12791279
passkeyScreen: {

packages/nuxt/src/module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export default defineNuxtModule<ModuleOptions>({
7474
// Backend specific variables that are safe to share.
7575
// We want them to be overridable like the other public keys (e.g NUXT_PUBLIC_CLERK_PROXY_URL)
7676
proxyUrl: options.proxyUrl,
77-
apiUrl: 'https://api.clerk.com',
77+
apiUrl: '',
7878
apiVersion: 'v1',
7979
},
8080
},
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { vi } from 'vitest';
2+
3+
// These globals are normally injected at build time by tsup.
4+
(globalThis as any).PACKAGE_NAME = '@clerk/nuxt';
5+
(globalThis as any).PACKAGE_VERSION = '0.0.0-test';
6+
7+
vi.mock('#imports', () => {
8+
return {
9+
useRuntimeConfig: vi.fn(),
10+
};
11+
});
12+
13+
vi.mock('@clerk/backend', () => {
14+
return {
15+
createClerkClient: vi.fn().mockReturnValue({}),
16+
};
17+
});
18+
19+
import { createClerkClient } from '@clerk/backend';
20+
21+
// @ts-expect-error: Nitro import. Handled by Nuxt.
22+
import { useRuntimeConfig } from '#imports';
23+
24+
import { clerkClient } from '../clerkClient';
25+
26+
const useRuntimeConfigMock = vi.mocked(useRuntimeConfig);
27+
const createClerkClientMock = vi.mocked(createClerkClient);
28+
29+
function mockRuntimeConfig(overrides: { publishableKey?: string; apiUrl?: string } = {}) {
30+
useRuntimeConfigMock.mockReturnValue({
31+
public: {
32+
clerk: {
33+
publishableKey: overrides.publishableKey ?? 'pk_test_Y2xlcmsuY2xlcmsuY29tJA',
34+
apiUrl: overrides.apiUrl ?? '',
35+
apiVersion: 'v1',
36+
proxyUrl: '',
37+
domain: '',
38+
isSatellite: false,
39+
telemetry: {},
40+
},
41+
},
42+
clerk: {
43+
secretKey: 'sk_test_xxx',
44+
machineSecretKey: '',
45+
jwtKey: '',
46+
},
47+
} as any);
48+
}
49+
50+
describe('clerkClient', () => {
51+
beforeEach(() => {
52+
vi.clearAllMocks();
53+
});
54+
55+
it('derives staging API URL from staging publishable key', () => {
56+
// pk_test_ + base64("safe-egret-46.clerk.accountsstage.dev$")
57+
const stagingPk = 'pk_test_c2FmZS1lZ3JldC00Ni5jbGVyay5hY2NvdW50c3N0YWdlLmRldiQ';
58+
mockRuntimeConfig({ publishableKey: stagingPk });
59+
60+
clerkClient({} as any);
61+
62+
expect(createClerkClientMock).toHaveBeenCalledWith(
63+
expect.objectContaining({
64+
apiUrl: 'https://api.clerkstage.dev',
65+
}),
66+
);
67+
});
68+
69+
it('uses production API URL for production publishable key', () => {
70+
const prodPk = 'pk_test_Y2xlcmsuY2xlcmsuY29tJA';
71+
mockRuntimeConfig({ publishableKey: prodPk });
72+
73+
clerkClient({} as any);
74+
75+
expect(createClerkClientMock).toHaveBeenCalledWith(
76+
expect.objectContaining({
77+
apiUrl: 'https://api.clerk.com',
78+
}),
79+
);
80+
});
81+
82+
it('prefers explicit apiUrl over derived value', () => {
83+
const stagingPk = 'pk_test_c2FmZS1lZ3JldC00Ni5jbGVyay5hY2NvdW50c3N0YWdlLmRldiQ';
84+
mockRuntimeConfig({ publishableKey: stagingPk, apiUrl: 'https://custom.api.example.com' });
85+
86+
clerkClient({} as any);
87+
88+
expect(createClerkClientMock).toHaveBeenCalledWith(
89+
expect.objectContaining({
90+
apiUrl: 'https://custom.api.example.com',
91+
}),
92+
);
93+
});
94+
});

0 commit comments

Comments
 (0)