diff --git a/packages/vercel-flags-core/src/index.default.ts b/packages/vercel-flags-core/src/index.default.ts index 00e5796f..3431da97 100644 --- a/packages/vercel-flags-core/src/index.default.ts +++ b/packages/vercel-flags-core/src/index.default.ts @@ -29,7 +29,7 @@ export const { */ resetDefaultFlagsClient, /** - * Create a flags client based on an SDK Key + * Create a flags client using an SDK key, connection string, or Vercel OIDC. */ createClient, } = make(createCreateRawClient(fns)); diff --git a/packages/vercel-flags-core/src/index.make.test.ts b/packages/vercel-flags-core/src/index.make.test.ts index 89e70e9c..52e533ac 100644 --- a/packages/vercel-flags-core/src/index.make.test.ts +++ b/packages/vercel-flags-core/src/index.make.test.ts @@ -83,6 +83,24 @@ describe('make', () => { expect(client).toBeDefined(); }); + it('should create an OIDC-authenticated client with options as the first argument', () => { + const createRawClient = createMockCreateRawClient(); + const { createClient } = make(createRawClient); + + const client = createClient({ stream: false, polling: false }); + + expect(Controller).toHaveBeenCalledWith({ + auth: expect.objectContaining({ sdkKey: undefined }), + stream: false, + polling: false, + }); + expect(createRawClient).toHaveBeenCalledWith({ + controller: expect.any(Object), + origin: { provider: 'vercel', sdkKey: undefined }, + }); + expect(client).toBeDefined(); + }); + it('should throw for empty SDK key', () => { const createRawClient = createMockCreateRawClient(); const { createClient } = make(createRawClient); diff --git a/packages/vercel-flags-core/src/index.make.ts b/packages/vercel-flags-core/src/index.make.ts index 1c5aaa5a..f058ab77 100644 --- a/packages/vercel-flags-core/src/index.make.ts +++ b/packages/vercel-flags-core/src/index.make.ts @@ -12,29 +12,52 @@ import type { FlagsClient } from './types'; */ export type CreateClientOptions = Omit; +type CreateClient = { + >( + options: CreateClientOptions, + ): FlagsClient; + >( + sdkKeyOrConnectionString?: string, + options?: CreateClientOptions, + ): FlagsClient; +}; + export function make( createRawClient: ReturnType, ): { flagsClient: FlagsClient; resetDefaultFlagsClient: () => void; - createClient: >( - sdkKeyOrConnectionString?: string, - options?: CreateClientOptions, - ) => FlagsClient; + createClient: CreateClient; } { let _defaultFlagsClient: FlagsClient | null = null; // Insights // - data source must specify the environment & projectId as sdkKey has that info // - "reuse" functionality relies on the data source having the data for all envs + function createClient>( + options: CreateClientOptions, + ): FlagsClient; function createClient>( sdkKeyOrConnectionString?: string, options?: CreateClientOptions, + ): FlagsClient; + function createClient>( + sdkKeyOrConnectionStringOrOptions?: string | CreateClientOptions, + options?: CreateClientOptions, ): FlagsClient { + const optionsOnly = + typeof sdkKeyOrConnectionStringOrOptions === 'object' && + sdkKeyOrConnectionStringOrOptions !== null; + const sdkKeyOrConnectionString = optionsOnly + ? undefined + : sdkKeyOrConnectionStringOrOptions; + const createClientOptions = optionsOnly + ? sdkKeyOrConnectionStringOrOptions + : options; const auth = new Authentication(sdkKeyOrConnectionString); // sdk key contains the environment - const controller = new Controller({ auth, ...options }); + const controller = new Controller({ auth, ...createClientOptions }); return createRawClient({ controller, origin: { provider: 'vercel', sdkKey: auth.sdkKey },