Skip to content

Commit 826d290

Browse files
feat(client): add withOptions helper
1 parent e21900d commit 826d290

2 files changed

Lines changed: 85 additions & 0 deletions

File tree

src/client.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,23 @@ export class Grid {
178178
this.apiKey = apiKey;
179179
}
180180

181+
/**
182+
* Create a new client instance re-using the same options given to the current client with optional overriding.
183+
*/
184+
withOptions(options: Partial<ClientOptions>): this {
185+
return new (this.constructor as any as new (props: ClientOptions) => typeof this)({
186+
...this._options,
187+
baseURL: this.baseURL,
188+
maxRetries: this.maxRetries,
189+
timeout: this.timeout,
190+
logger: this.logger,
191+
logLevel: this.logLevel,
192+
fetchOptions: this.fetchOptions,
193+
apiKey: this.apiKey,
194+
...options,
195+
});
196+
}
197+
181198
protected defaultQuery(): Record<string, string | undefined> | undefined {
182199
return this._options.defaultQuery;
183200
}

tests/index.test.ts

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

320+
describe('withOptions', () => {
321+
test('creates a new client with overridden options', () => {
322+
const client = new Grid({ baseURL: 'http://localhost:5000/', maxRetries: 3, apiKey: 'My API Key' });
323+
324+
const newClient = client.withOptions({
325+
maxRetries: 5,
326+
baseURL: 'http://localhost:5001/',
327+
});
328+
329+
// Verify the new client has updated options
330+
expect(newClient.maxRetries).toEqual(5);
331+
expect(newClient.baseURL).toEqual('http://localhost:5001/');
332+
333+
// Verify the original client is unchanged
334+
expect(client.maxRetries).toEqual(3);
335+
expect(client.baseURL).toEqual('http://localhost:5000/');
336+
337+
// Verify it's a different instance
338+
expect(newClient).not.toBe(client);
339+
expect(newClient.constructor).toBe(client.constructor);
340+
});
341+
342+
test('inherits options from the parent client', () => {
343+
const client = new Grid({
344+
baseURL: 'http://localhost:5000/',
345+
defaultHeaders: { 'X-Test-Header': 'test-value' },
346+
defaultQuery: { 'test-param': 'test-value' },
347+
apiKey: 'My API Key',
348+
});
349+
350+
const newClient = client.withOptions({
351+
baseURL: 'http://localhost:5001/',
352+
});
353+
354+
// Test inherited options remain the same
355+
expect(newClient.buildURL('/foo', null)).toEqual('http://localhost:5001/foo?test-param=test-value');
356+
357+
const { req } = newClient.buildRequest({ path: '/foo', method: 'get' });
358+
expect(req.headers.get('x-test-header')).toEqual('test-value');
359+
});
360+
361+
test('respects runtime property changes when creating new client', () => {
362+
const client = new Grid({ baseURL: 'http://localhost:5000/', timeout: 1000, apiKey: 'My API Key' });
363+
364+
// Modify the client properties directly after creation
365+
client.baseURL = 'http://localhost:6000/';
366+
client.timeout = 2000;
367+
368+
// Create a new client with withOptions
369+
const newClient = client.withOptions({
370+
maxRetries: 10,
371+
});
372+
373+
// Verify the new client uses the updated properties, not the original ones
374+
expect(newClient.baseURL).toEqual('http://localhost:6000/');
375+
expect(newClient.timeout).toEqual(2000);
376+
expect(newClient.maxRetries).toEqual(10);
377+
378+
// Original client should still have its modified properties
379+
expect(client.baseURL).toEqual('http://localhost:6000/');
380+
expect(client.timeout).toEqual(2000);
381+
expect(client.maxRetries).not.toEqual(10);
382+
383+
// Verify URL building uses the updated baseURL
384+
expect(newClient.buildURL('/bar', null)).toEqual('http://localhost:6000/bar');
385+
});
386+
});
387+
320388
test('with environment variable arguments', () => {
321389
// set options via env var
322390
process.env['GRID_API_TOKEN'] = 'My API Key';

0 commit comments

Comments
 (0)