Skip to content

Commit 6f444eb

Browse files
feat(client): add withOptions helper
1 parent 442142c commit 6f444eb

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

src/client.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,24 @@ export class Hanzo {
500500
this.apiKey = apiKey;
501501
}
502502

503+
/**
504+
* Create a new client instance re-using the same options given to the current client with optional overriding.
505+
*/
506+
withOptions(options: Partial<ClientOptions>): this {
507+
return new (this.constructor as any as new (props: ClientOptions) => typeof this)({
508+
...this._options,
509+
environment: options.environment ? options.environment : undefined,
510+
baseURL: options.environment ? undefined : this.baseURL,
511+
maxRetries: this.maxRetries,
512+
timeout: this.timeout,
513+
logger: this.logger,
514+
logLevel: this.logLevel,
515+
fetchOptions: this.fetchOptions,
516+
apiKey: this.apiKey,
517+
...options,
518+
});
519+
}
520+
503521
/**
504522
* Home
505523
*/

tests/index.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,74 @@ describe('instantiate client', () => {
334334
expect(client2.maxRetries).toEqual(2);
335335
});
336336

337+
describe('withOptions', () => {
338+
test('creates a new client with overridden options', () => {
339+
const client = new Hanzo({ baseURL: 'http://localhost:5000/', maxRetries: 3, apiKey: 'My API Key' });
340+
341+
const newClient = client.withOptions({
342+
maxRetries: 5,
343+
baseURL: 'http://localhost:5001/',
344+
});
345+
346+
// Verify the new client has updated options
347+
expect(newClient.maxRetries).toEqual(5);
348+
expect(newClient.baseURL).toEqual('http://localhost:5001/');
349+
350+
// Verify the original client is unchanged
351+
expect(client.maxRetries).toEqual(3);
352+
expect(client.baseURL).toEqual('http://localhost:5000/');
353+
354+
// Verify it's a different instance
355+
expect(newClient).not.toBe(client);
356+
expect(newClient.constructor).toBe(client.constructor);
357+
});
358+
359+
test('inherits options from the parent client', () => {
360+
const client = new Hanzo({
361+
baseURL: 'http://localhost:5000/',
362+
defaultHeaders: { 'X-Test-Header': 'test-value' },
363+
defaultQuery: { 'test-param': 'test-value' },
364+
apiKey: 'My API Key',
365+
});
366+
367+
const newClient = client.withOptions({
368+
baseURL: 'http://localhost:5001/',
369+
});
370+
371+
// Test inherited options remain the same
372+
expect(newClient.buildURL('/foo', null)).toEqual('http://localhost:5001/foo?test-param=test-value');
373+
374+
const { req } = newClient.buildRequest({ path: '/foo', method: 'get' });
375+
expect(req.headers.get('x-test-header')).toEqual('test-value');
376+
});
377+
378+
test('respects runtime property changes when creating new client', () => {
379+
const client = new Hanzo({ baseURL: 'http://localhost:5000/', timeout: 1000, apiKey: 'My API Key' });
380+
381+
// Modify the client properties directly after creation
382+
client.baseURL = 'http://localhost:6000/';
383+
client.timeout = 2000;
384+
385+
// Create a new client with withOptions
386+
const newClient = client.withOptions({
387+
maxRetries: 10,
388+
});
389+
390+
// Verify the new client uses the updated properties, not the original ones
391+
expect(newClient.baseURL).toEqual('http://localhost:6000/');
392+
expect(newClient.timeout).toEqual(2000);
393+
expect(newClient.maxRetries).toEqual(10);
394+
395+
// Original client should still have its modified properties
396+
expect(client.baseURL).toEqual('http://localhost:6000/');
397+
expect(client.timeout).toEqual(2000);
398+
expect(client.maxRetries).not.toEqual(10);
399+
400+
// Verify URL building uses the updated baseURL
401+
expect(newClient.buildURL('/bar', null)).toEqual('http://localhost:6000/bar');
402+
});
403+
});
404+
337405
test('with environment variable arguments', () => {
338406
// set options via env var
339407
process.env['HANZO_API_KEY'] = 'My API Key';

0 commit comments

Comments
 (0)