Skip to content

Commit

Permalink
feat(nextjs): Allow eager clerkClient() access
Browse files Browse the repository at this point in the history
  • Loading branch information
BRKalow committed Oct 25, 2024
1 parent abeb659 commit ad9cd98
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 17 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@clerk/shared": "2.10.1",
"@clerk/types": "4.28.0",
"crypto-js": "4.2.0",
"proxy-deep": "^4.0.1",
"server-only": "0.0.1",
"tslib": "2.4.1"
},
Expand Down
11 changes: 11 additions & 0 deletions packages/nextjs/src/server/__tests__/clerkClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,15 @@ describe('clerkClient', () => {
'User-Agent': '@clerk/[email protected]',
});
});

it('should allow client usage before client is initialized', async () => {
await clerkClient().users.getUser('user_test');

expect(global.fetch).toBeCalled();
expect((global.fetch as any).mock.calls[0][1].headers).toMatchObject({
Authorization: 'Bearer TEST_SECRET_KEY',
'Content-Type': 'application/json',
'User-Agent': '@clerk/[email protected]',
});
});
});
53 changes: 36 additions & 17 deletions packages/nextjs/src/server/clerkClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createClerkClient } from '@clerk/backend';
import { ClerkClient, createClerkClient } from '@clerk/backend';
import { constants } from '@clerk/backend/internal';
import { DeepProxy } from 'proxy-deep';

import { buildRequestLike, isPrerenderingBailout } from '../app-router/server/utils';
import { clerkMiddlewareRequestDataStorage } from './clerkMiddleware';
Expand Down Expand Up @@ -40,26 +41,44 @@ const createClerkClientWithOptions: typeof createClerkClient = options =>
* Constructs a BAPI client that accesses request data within the runtime.
* Necessary if middleware dynamic keys are used.
*/
const clerkClient = async () => {
let requestData;
const clerkClient = () => {
const promise = new Promise<ReturnType<typeof createClerkClient>>(async (resolve, reject) => {
let requestData;

try {
const request = await buildRequestLike();
const encryptedRequestData = getHeader(request, constants.Headers.ClerkRequestData);
requestData = decryptClerkRequestData(encryptedRequestData);
} catch (err) {
if (err && isPrerenderingBailout(err)) {
throw err;
try {
const request = await buildRequestLike();
const encryptedRequestData = getHeader(request, constants.Headers.ClerkRequestData);
requestData = decryptClerkRequestData(encryptedRequestData);
} catch (err) {
if (err && isPrerenderingBailout(err)) {
reject(err);
}
}
}

// Fallbacks between options from middleware runtime and `NextRequest` from application server
const options = clerkMiddlewareRequestDataStorage.getStore()?.get('requestData') ?? requestData;
if (options?.secretKey || options?.publishableKey) {
return createClerkClientWithOptions(options);
}
// Fallbacks between options from middleware runtime and `NextRequest` from application server
const options = clerkMiddlewareRequestDataStorage.getStore()?.get('requestData') ?? requestData;
if (options?.secretKey || options?.publishableKey) {
resolve(createClerkClientWithOptions(options));
return;
}

resolve(createClerkClientWithOptions({}));
});

return createClerkClientWithOptions({});
return new DeepProxy(promise, {
apply(_, __, argumentsList) {
return promise.then(client => {
const fn = this.path.reduce((result, key) => {
// @ts-expect-error -- because the public type is of ClerkClient, we should be able to assume that property access is accurate here.
return result[key];
}, client) as unknown as (...args: any) => any;

fn?.(...argumentsList);
});
},
}) as ThenableClerkClient;
};

type ThenableClerkClient = Promise<ClerkClient> & ClerkClient;

export { clerkClient };

0 comments on commit ad9cd98

Please sign in to comment.