Skip to content

Commit e5a8c63

Browse files
committed
Embedding the request options normalization
1 parent 17f6a01 commit e5a8c63

File tree

6 files changed

+42
-43
lines changed

6 files changed

+42
-43
lines changed

packages/requester-utils/src/BaseResource.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { DefaultResourceOptions, RequesterType } from './RequesterUtils';
1+
import { RequesterType, ResourceOptions } from './RequesterUtils';
22

33
export interface RootResourceOptions<C> {
44
// TODO: Not actually optional - Need to fix wrapper typing in requestUtils.ts:
5-
requesterFn?: (resourceOptions: DefaultResourceOptions) => RequesterType;
5+
requesterFn?: (resourceOptions: ResourceOptions) => RequesterType;
66
host?: string;
77
prefixUrl?: string;
88
rejectUnauthorized?: boolean;

packages/requester-utils/src/RequesterUtils.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface Constructable<T = any> {
2323
new (...args: any[]): T;
2424
}
2525

26-
export type DefaultResourceOptions = {
26+
export type ResourceOptions = {
2727
headers: { [header: string]: string };
2828
authHeaders: { [authHeader: string]: () => Promise<string> };
2929
url: string;
@@ -82,23 +82,23 @@ export function formatQuery(params: Record<string, unknown> = {}): string {
8282
}
8383

8484
export type OptionsHandlerFn = (
85-
serviceOptions: DefaultResourceOptions,
86-
requestOptions: DefaultRequestOptions,
85+
serviceOptions: ResourceOptions,
86+
requestOptions: RequestOptions,
8787
) => Promise<RequestOptions>;
8888

8989
function isFormData(object: FormData | Record<string, unknown>) {
9090
return typeof object === 'object' && object.constructor.name === 'FormData';
9191
}
9292

9393
export async function defaultOptionsHandler(
94-
resourceOptions: DefaultResourceOptions,
94+
resourceOptions: ResourceOptions,
9595
{
9696
body,
9797
searchParams,
9898
sudo,
9999
signal,
100100
asStream = false,
101-
method = 'get',
101+
method = 'GET',
102102
}: DefaultRequestOptions = {},
103103
): Promise<RequestOptions> {
104104
const { headers: preconfiguredHeaders, authHeaders, url } = resourceOptions;
@@ -144,15 +144,19 @@ export type RequestHandlerFn<T extends ResponseBodyTypes = ResponseBodyTypes> =
144144
export function createRequesterFn(
145145
optionsHandler: OptionsHandlerFn,
146146
requestHandler: RequestHandlerFn,
147-
): (serviceOptions: DefaultResourceOptions) => RequesterType {
147+
): (serviceOptions: ResourceOptions) => RequesterType {
148148
const methods = ['get', 'post', 'put', 'patch', 'delete'];
149149

150150
return (serviceOptions) => {
151151
const requester: RequesterType = {} as RequesterType;
152152

153153
methods.forEach((m) => {
154154
requester[m] = async (endpoint: string, options: Record<string, unknown>) => {
155-
const requestOptions = await optionsHandler(serviceOptions, { ...options, method: m });
155+
const defaultRequestOptions = await defaultOptionsHandler(serviceOptions, {
156+
...options,
157+
method: m.toUpperCase(),
158+
});
159+
const requestOptions = await optionsHandler(serviceOptions, defaultRequestOptions);
156160

157161
return requestHandler(endpoint, requestOptions);
158162
};

packages/requester-utils/test/unit/BaseResource.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,22 +201,15 @@ describe('Creation of BaseResource instance', () => {
201201
it('should set the internal requester based on the required requesterFn parameter', async () => {
202202
const requestHandler = jest.fn();
203203
const optionsHandler = jest.fn();
204+
204205
const requesterFn = createRequesterFn(optionsHandler, requestHandler);
205206
const serviceA = new BaseResource({ token: '123', requesterFn, prefixUrl: 'test' });
206-
const serviceB = new BaseResource({ token: '123', requesterFn, prefixUrl: 'test2' });
207207

208208
await serviceA.requester.get('test');
209209

210210
expect(optionsHandler).toHaveBeenCalledWith(
211211
expect.objectContaining({ url: 'https://gitlab.com/api/v4/test' }),
212-
{ method: 'get' },
213-
);
214-
215-
await serviceB.requester.get('test');
216-
217-
expect(optionsHandler).toHaveBeenCalledWith(
218-
expect.objectContaining({ url: 'https://gitlab.com/api/v4/test2' }),
219-
{ method: 'get' },
212+
expect.objectContaining({ method: 'GET' }),
220213
);
221214
});
222215
});

packages/requester-utils/test/unit/RequesterUtils.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ describe('defaultOptionsHandler', () => {
2121
it('should not use default request options if not passed', async () => {
2222
const options = await defaultOptionsHandler(serviceOptions);
2323

24-
expect(options.method).toBe('get');
24+
expect(options.method).toBe('GET');
2525
});
2626

2727
it('should stringify body if it isnt of type FormData', async () => {
2828
const testBody = { test: 6 };
2929
const { body, headers } = await defaultOptionsHandler(serviceOptions, {
30-
method: 'post',
30+
method: 'POST',
3131
body: testBody,
3232
});
3333

@@ -39,7 +39,7 @@ describe('defaultOptionsHandler', () => {
3939
const testBody: globalThis.FormData = new FormData() as unknown as globalThis.FormData;
4040
const { body } = await defaultOptionsHandler(serviceOptions, {
4141
body: testBody,
42-
method: 'post',
42+
method: 'POST',
4343
});
4444

4545
expect(body).toBeInstanceOf(FormData);
@@ -48,7 +48,7 @@ describe('defaultOptionsHandler', () => {
4848
it('should not assign the sudo property if omitted', async () => {
4949
const { headers } = await defaultOptionsHandler(serviceOptions, {
5050
sudo: undefined,
51-
method: 'get',
51+
method: 'GET',
5252
});
5353

5454
expect(headers.sudo).toBeUndefined();
@@ -95,7 +95,7 @@ describe('defaultOptionsHandler', () => {
9595
it('should append dynamic authentication token headers', async () => {
9696
const { headers } = await defaultOptionsHandler(serviceOptions, {
9797
sudo: undefined,
98-
method: 'get',
98+
method: 'GET',
9999
});
100100

101101
expect(headers.token).toBe('1234');
@@ -137,7 +137,10 @@ describe('createInstance', () => {
137137
// eslint-disable-next-line
138138
await requester[m](testEndpoint, {});
139139

140-
expect(optionsHandler).toHaveBeenCalledWith(serviceOptions, { method: m });
140+
expect(optionsHandler).toHaveBeenCalledWith(
141+
serviceOptions,
142+
expect.objectContaining({ method: m.toUpperCase() }),
143+
);
141144
expect(requestHandler).toHaveBeenCalledWith(testEndpoint, {});
142145
}
143146
});
@@ -166,11 +169,17 @@ describe('createInstance', () => {
166169

167170
await requesterA.get('test');
168171

169-
expect(optionsHandler).toHaveBeenCalledWith(serviceOptions1, { method: 'get' });
172+
expect(optionsHandler).toHaveBeenCalledWith(
173+
serviceOptions1,
174+
expect.objectContaining({ method: 'GET' }),
175+
);
170176

171177
await requesterB.get('test');
172178

173-
expect(optionsHandler).toHaveBeenCalledWith(serviceOptions2, { method: 'get' });
179+
expect(optionsHandler).toHaveBeenCalledWith(
180+
serviceOptions2,
181+
expect.objectContaining({ method: 'GET' }),
182+
);
174183
});
175184
});
176185

packages/rest/src/Requester.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
import type {
2-
DefaultRequestOptions,
3-
DefaultResourceOptions,
42
RequestOptions,
3+
ResourceOptions,
54
ResponseBodyTypes,
65
} from '@gitbeaker/requester-utils';
7-
import {
8-
defaultOptionsHandler as baseOptionsHandler,
9-
createRequesterFn,
10-
} from '@gitbeaker/requester-utils';
6+
import { createRequesterFn } from '@gitbeaker/requester-utils';
117

128
export async function defaultOptionsHandler(
13-
resourceOptions: DefaultResourceOptions,
14-
requestOptions: DefaultRequestOptions = {},
9+
resourceOptions: ResourceOptions,
10+
requestOptions: RequestOptions,
1511
): Promise<RequestOptions & { agent?: unknown }> {
16-
const options: RequestOptions & { agent?: unknown } = await baseOptionsHandler(
17-
resourceOptions,
18-
requestOptions,
19-
);
12+
const options: RequestOptions & { agent?: unknown } = { ...requestOptions };
2013

2114
if (
2215
resourceOptions.url.includes('https') &&

packages/rest/test/unit/Requester.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ describe('defaultRequest', () => {
293293
it('should not assign the agent property if given https url and not rejectUnauthorized', async () => {
294294
const { agent } = await defaultOptionsHandler(
295295
{ ...service, url: 'https://test.com' },
296-
{ method: 'post' },
296+
{ method: 'POST' },
297297
);
298298

299299
expect(agent).toBeUndefined();
@@ -302,7 +302,7 @@ describe('defaultRequest', () => {
302302
it('should not assign the agent property if given http url and rejectUnauthorized', async () => {
303303
const { agent } = await defaultOptionsHandler(
304304
{ ...service, url: 'http://test.com' },
305-
{ method: 'post' },
305+
{ method: 'POST' },
306306
);
307307

308308
expect(agent).toBeUndefined();
@@ -311,21 +311,21 @@ describe('defaultRequest', () => {
311311
it('should assign the agent property if given https url and rejectUnauthorized is false', async () => {
312312
const { agent: agent1 } = await defaultOptionsHandler(
313313
{ ...service, url: 'https://test.com', rejectUnauthorized: false },
314-
{ method: 'post' },
314+
{ method: 'POST' },
315315
);
316316

317317
expect(agent1).toBeDefined();
318318

319319
const { agent: agent2 } = await defaultOptionsHandler(
320320
{ ...service, url: 'https://test.com', rejectUnauthorized: true },
321-
{ method: 'post' },
321+
{ method: 'POST' },
322322
);
323323

324324
expect(agent2).toBeUndefined();
325325

326326
const { agent: agent3 } = await defaultOptionsHandler(
327327
{ ...service, url: 'https://test.com' },
328-
{ method: 'post' },
328+
{ method: 'POST' },
329329
);
330330

331331
expect(agent3).toBeUndefined();

0 commit comments

Comments
 (0)