diff --git a/.changeset/pretty-crabs-scream.md b/.changeset/pretty-crabs-scream.md new file mode 100644 index 00000000000..530fa380c76 --- /dev/null +++ b/.changeset/pretty-crabs-scream.md @@ -0,0 +1,5 @@ +--- +"@clerk/nextjs": patch +--- + +Mark internal keyless header function async to comply with Server Actions async requirements diff --git a/packages/nextjs/src/__tests__/keyless-custom-headers.test.ts b/packages/nextjs/src/__tests__/keyless-custom-headers.test.ts index 48cc8cb896e..7be75419d7a 100644 --- a/packages/nextjs/src/__tests__/keyless-custom-headers.test.ts +++ b/packages/nextjs/src/__tests__/keyless-custom-headers.test.ts @@ -166,7 +166,7 @@ describe('keyless-custom-headers', () => { }); describe('formatMetadataHeaders', () => { - it('should format complete metadata object with all fields present', () => { + it('should format complete metadata object with all fields present', async () => { const metadata = { nodeVersion: 'v18.17.0', nextVersion: 'next-server (v15.4.5)', @@ -181,7 +181,7 @@ describe('keyless-custom-headers', () => { isCI: false, }; - const result = formatMetadataHeaders(metadata); + const result = await formatMetadataHeaders(metadata); // Test exact header casing and values expect(result.get('Clerk-Node-Version')).toBe('v18.17.0'); @@ -196,7 +196,7 @@ describe('keyless-custom-headers', () => { expect(result.get('Clerk-Auth-Status')).toBe('signed-out'); }); - it('should handle missing optional fields gracefully', () => { + it('should handle missing optional fields gracefully', async () => { const metadata = { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', host: 'localhost:3000', @@ -208,7 +208,7 @@ describe('keyless-custom-headers', () => { // Missing: nodeVersion, nextVersion, npmConfigUserAgent, port }; - const result = formatMetadataHeaders(metadata); + const result = await formatMetadataHeaders(metadata); // Test that only present fields are set expect(result.get('Clerk-Client-User-Agent')).toBe('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'); @@ -225,7 +225,7 @@ describe('keyless-custom-headers', () => { expect(result.get('Clerk-Node-Port')).toBeNull(); }); - it('should handle undefined values for optional fields', () => { + it('should handle undefined values for optional fields', async () => { const metadata = { nodeVersion: undefined, nextVersion: undefined, @@ -240,7 +240,7 @@ describe('keyless-custom-headers', () => { isCI: false, }; - const result = formatMetadataHeaders(metadata); + const result = await formatMetadataHeaders(metadata); // Test that undefined fields are not set expect(result.get('Clerk-Node-Version')).toBeNull(); @@ -257,7 +257,7 @@ describe('keyless-custom-headers', () => { expect(result.get('Clerk-Auth-Status')).toBe('test-auth-status'); }); - it('should handle empty string values', () => { + it('should handle empty string values', async () => { const metadata = { nodeVersion: '', nextVersion: '', @@ -272,7 +272,7 @@ describe('keyless-custom-headers', () => { isCI: false, }; - const result = formatMetadataHeaders(metadata); + const result = await formatMetadataHeaders(metadata); // Empty strings should not be set as headers expect(result.get('Clerk-Node-Version')).toBeNull(); @@ -513,7 +513,7 @@ describe('keyless-custom-headers', () => { // Collect metadata and format headers const metadata = await collectKeylessMetadata(); - const headers = formatMetadataHeaders(metadata); + const headers = await formatMetadataHeaders(metadata); // Verify the full pipeline works correctly expect(headers.get('Clerk-Client-User-Agent')).toBe('Integration-Test-Agent'); diff --git a/packages/nextjs/src/server/keyless-custom-headers.ts b/packages/nextjs/src/server/keyless-custom-headers.ts index 5e216933843..73ca03837b6 100644 --- a/packages/nextjs/src/server/keyless-custom-headers.ts +++ b/packages/nextjs/src/server/keyless-custom-headers.ts @@ -20,7 +20,7 @@ interface MetadataHeaders { * Collects metadata from the environment and request headers */ export async function collectKeylessMetadata(): Promise { - const headerStore = await headers(); // eslint-disable-line + const headerStore = await headers(); return { nodeVersion: process.version, @@ -99,7 +99,7 @@ function getNextVersion(): string | undefined { /** * Converts metadata to HTTP headers */ -export function formatMetadataHeaders(metadata: MetadataHeaders): Headers { +export async function formatMetadataHeaders(metadata: MetadataHeaders): Promise { const headers = new Headers(); if (metadata.nodeVersion) {