Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unauthed http option #171

Merged
merged 7 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions http/__tests__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,5 +255,31 @@ describe('http/index', () => {
},
});
});

it('supports making unauthed requests', async () => {
await http.getUnauthed({
url: 'some/endpoint/path',
env: 'qa',
});

expect(mockedAxios).toHaveBeenCalledWith({
baseURL: `https://api.hubapiqa.com`,
url: 'some/endpoint/path',
headers: {
'User-Agent': `HubSpot Local Dev Lib/${version}`,
},
timeout: 15000,
params: {},
transitional: {
clarifyTimeoutError: true,
},
httpAgent: {
options: { keepAlive: true, maxSockets: 5, maxTotalSockets: 25 },
},
httpsAgent: {
options: { keepAlive: true, maxSockets: 6, maxTotalSockets: 26 },
},
});
});
});
});
24 changes: 16 additions & 8 deletions http/getAxiosConfig.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { version } from '../package.json';
import { getAndLoadConfigIfNeeded } from '../config';
import { getHubSpotApiOrigin } from '../lib/urls';
import { AxiosConfigOptions } from '../types/Http';
import { CLIConfig } from '../types/Config';
import { HttpOptions } from '../types/Http';
import { AxiosRequestConfig } from 'axios';
import https from 'https';
import http from 'http';
Expand Down Expand Up @@ -47,12 +46,21 @@ const DEFAULT_TRANSITIONAL = {
clarifyTimeoutError: true,
};

export function getAxiosConfig(
options: AxiosConfigOptions
): AxiosRequestConfig {
export function getAxiosConfig(options: HttpOptions): AxiosRequestConfig {
const { env, localHostOverride, headers, ...rest } = options;
const { httpTimeout, httpUseLocalhost } =
getAndLoadConfigIfNeeded() as CLIConfig;
const config = getAndLoadConfigIfNeeded();

let httpTimeout = 15000;
let httpUseLocalhost = false;

if (config && config.httpTimeout) {
httpTimeout = config.httpTimeout;
}

if (config && config.httpUseLocalhost) {
httpUseLocalhost = config.httpUseLocalhost;
}

return {
baseURL: getHubSpotApiOrigin(
env,
Expand All @@ -62,7 +70,7 @@ export function getAxiosConfig(
...getDefaultUserAgentHeader(),
...(headers || {}),
},
timeout: httpTimeout || 15000,
timeout: httpTimeout,
transitional: DEFAULT_TRANSITIONAL,
httpAgent,
httpsAgent,
Expand Down
62 changes: 47 additions & 15 deletions http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { USER_AGENTS, getAxiosConfig } from './getAxiosConfig';
import { accessTokenForPersonalAccessKey } from '../lib/personalAccessKey';
import { getOauthManager } from '../lib/oauth';
import { FlatAccountFields } from '../types/Accounts';
import { AxiosConfigOptions, HttpOptions, QueryParams } from '../types/Http';
import { HttpOptions, QueryParams } from '../types/Http';
import { logger } from '../lib/logger';
import { i18n } from '../utils/lang';
import { HubSpotHttpError } from '../models/HubSpotHttpError';
Expand Down Expand Up @@ -79,7 +79,7 @@ function withPortalId(

async function withAuth(
accountId: number,
options: AxiosConfigOptions
options: HttpOptions
): Promise<AxiosRequestConfig> {
const accountConfig = getAccountConfig(accountId);

Expand Down Expand Up @@ -112,9 +112,9 @@ async function withAuth(
}

function addQueryParams(
configOptions: AxiosConfigOptions,
configOptions: HttpOptions,
queryParams: QueryParams = {}
): AxiosConfigOptions {
): HttpOptions {
const { params } = configOptions;
return {
...configOptions,
Expand All @@ -130,43 +130,70 @@ async function getRequest<T>(
options: HttpOptions
): AxiosPromise<T> {
const { params, ...rest } = options;
const axiosConfig = addQueryParams(rest, params);
const configWithAuth = await withAuth(accountId, axiosConfig);
const optionsWithParams = addQueryParams(rest, params);
const requestConfig = await withAuth(accountId, optionsWithParams);

return axios<T>(requestConfig);
}

async function unauthedGetRequest<T>(options: HttpOptions): AxiosPromise<T> {
const { params, ...rest } = options;
const optionsWithParams = addQueryParams(rest, params);
const requestConfig = await getAxiosConfig(optionsWithParams);

return axios<T>(configWithAuth);
return axios<T>(requestConfig);
}

async function postRequest<T>(
accountId: number,
options: HttpOptions
): AxiosPromise<T> {
const configWithAuth = await withAuth(accountId, options);
const requestConfig = await withAuth(accountId, options);
return axios({ ...requestConfig, method: 'post' });
}

return axios({ ...configWithAuth, method: 'post' });
async function unauthedPostRequest<T>(options: HttpOptions): AxiosPromise<T> {
const requestConfig = await getAxiosConfig(options);
return axios({ ...requestConfig, method: 'post' });
}
joe-yeager marked this conversation as resolved.
Show resolved Hide resolved

async function putRequest<T>(
accountId: number,
options: HttpOptions
): AxiosPromise<T> {
const configWithAuth = await withAuth(accountId, options);
return axios({ ...configWithAuth, method: 'put' });
const requestConfig = await withAuth(accountId, options);
return axios({ ...requestConfig, method: 'put' });
}

async function unauthedPutRequest<T>(options: HttpOptions): AxiosPromise<T> {
const requestConfig = await getAxiosConfig(options);
return axios({ ...requestConfig, method: 'put' });
}

async function patchRequest<T>(
accountId: number,
options: HttpOptions
): AxiosPromise<T> {
const configWithAuth = await withAuth(accountId, options);
return axios({ ...configWithAuth, method: 'patch' });
const requestConfig = await withAuth(accountId, options);
return axios({ ...requestConfig, method: 'patch' });
}

async function unauthedPatchRequest<T>(options: HttpOptions): AxiosPromise<T> {
const requestConfig = await getAxiosConfig(options);
return axios({ ...requestConfig, method: 'patch' });
}

async function deleteRequest<T>(
accountId: number,
options: HttpOptions
): AxiosPromise<T> {
const configWithAuth = await withAuth(accountId, options);
return axios({ ...configWithAuth, method: 'delete' });
const requestConfig = await withAuth(accountId, options);
return axios({ ...requestConfig, method: 'delete' });
}

async function unauthedDeleteRequest<T>(options: HttpOptions): AxiosPromise<T> {
const requestConfig = await getAxiosConfig(options);
return axios({ ...requestConfig, method: 'delete' });
}

function createGetRequestStream(contentType: string) {
Expand Down Expand Up @@ -238,9 +265,14 @@ const getOctetStream = createGetRequestStream('application/octet-stream');

export const http = {
get: getRequest,
getUnauthed: unauthedGetRequest,
post: postRequest,
postUnauthed: unauthedPostRequest,
put: putRequest,
putUnauthed: unauthedPutRequest,
patch: patchRequest,
patchUnauthed: unauthedPatchRequest,
delete: deleteRequest,
deleteUnauthed: unauthedDeleteRequest,
getOctetStream,
};
19 changes: 7 additions & 12 deletions types/Http.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ResponseType } from 'axios';
import { ReadStream } from 'fs';
import { Stream } from 'stream';

Expand All @@ -10,12 +11,15 @@ export type QueryParams = {
[key: string]: string | number | boolean | undefined;
};

export type AxiosConfigOptions = {
export type FormData = {
[key: string]: string | ReadStream;
};

export type HttpOptions = {
baseURL?: string;
url: string;
env?: string;
localHostOverride?: boolean;
params?: QueryParams;
data?:
| Data
| string
Expand All @@ -25,17 +29,8 @@ export type AxiosConfigOptions = {
| Stream
| Buffer;
resolveWithFullResponse?: boolean;
timeout?: number;
headers?: Data;
};

export type FormData = {
[key: string]: string | ReadStream;
};

export type HttpOptions = AxiosConfigOptions & {
params?: QueryParams;
timeout?: number;
responseType?: string;
responseType?: ResponseType;
headers?: { [header: string]: string | string[] | undefined };
};