Skip to content

Commit

Permalink
feat: add support for custom request options
Browse files Browse the repository at this point in the history
  • Loading branch information
Mila Votradovec committed Mar 16, 2021
1 parent 7919781 commit e46f2e3
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 101 deletions.
181 changes: 101 additions & 80 deletions src/analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,37 @@ import {
AnalyzeGitOptions,
GitOptions,
} from './interfaces/analysis-options.interface';

import { RequestOptions } from './interfaces/http-options.interface';

import { fromEntries } from './lib/utils';

const sleep = (duration: number) => new Promise(resolve => setTimeout(resolve, duration));

async function pollAnalysis({
baseURL,
sessionToken,
includeLint,
severity,
bundleId,
oAuthToken,
username,
limitToFiles,
source,
}: {
baseURL: string;
sessionToken: string;
includeLint: boolean;
severity: AnalysisSeverity;
bundleId: string;
oAuthToken?: string;
username?: string;
limitToFiles?: string[];
source: string;
}): Promise<IResult<AnalysisFailedResponse | AnalysisFinishedResponse, GetAnalysisErrorCodes>> {
async function pollAnalysis(
{
baseURL,
sessionToken,
includeLint,
severity,
bundleId,
oAuthToken,
username,
limitToFiles,
source,
}: {
baseURL: string;
sessionToken: string;
includeLint: boolean;
severity: AnalysisSeverity;
bundleId: string;
oAuthToken?: string;
username?: string;
limitToFiles?: string[];
source: string;
},
requestOptions?: RequestOptions,
): Promise<IResult<AnalysisFailedResponse | AnalysisFinishedResponse, GetAnalysisErrorCodes>> {
let analysisResponse: IResult<GetAnalysisResponseDto, GetAnalysisErrorCodes>;
let analysisData: GetAnalysisResponseDto;

Expand All @@ -73,17 +79,20 @@ async function pollAnalysis({
// eslint-disable-next-line no-constant-condition
while (true) {
// eslint-disable-next-line no-await-in-loop
analysisResponse = await getAnalysis({
baseURL,
sessionToken,
oAuthToken,
username,
bundleId,
includeLint,
severity,
limitToFiles,
source,
});
analysisResponse = await getAnalysis(
{
baseURL,
sessionToken,
oAuthToken,
username,
bundleId,
includeLint,
severity,
limitToFiles,
source,
},
requestOptions,
);

if (analysisResponse.type === 'error') {
return analysisResponse;
Expand Down Expand Up @@ -112,39 +121,45 @@ async function pollAnalysis({
}
}

export async function analyzeBundle({
baseURL = defaultBaseURL,
sessionToken = '',
includeLint = false,
severity = AnalysisSeverity.info,
bundleId,
oAuthToken,
username,
limitToFiles,
source,
}: {
baseURL: string;
sessionToken: string;
includeLint: boolean;
severity: AnalysisSeverity;
bundleId: string;
oAuthToken?: string;
username?: string;
limitToFiles?: string[];
source: string;
}): Promise<IBundleResult> {
// Call remote bundle for analysis results and emit intermediate progress
const analysisData = await pollAnalysis({
baseURL,
sessionToken,
export async function analyzeBundle(
{
baseURL = defaultBaseURL,
sessionToken = '',
includeLint = false,
severity = AnalysisSeverity.info,
bundleId,
oAuthToken,
username,
bundleId,
includeLint,
severity,
limitToFiles,
source,
});
}: {
baseURL: string;
sessionToken: string;
includeLint: boolean;
severity: AnalysisSeverity;
bundleId: string;
oAuthToken?: string;
username?: string;
limitToFiles?: string[];
source: string;
},
requestOptions?: RequestOptions,
): Promise<IBundleResult> {
// Call remote bundle for analysis results and emit intermediate progress
const analysisData = await pollAnalysis(
{
baseURL,
sessionToken,
oAuthToken,
username,
bundleId,
includeLint,
severity,
limitToFiles,
source,
},
requestOptions,
);

if (analysisData.type === 'error') {
throw analysisData.error;
Expand Down Expand Up @@ -393,31 +408,37 @@ const analyzeGitDefaults = {
source: '',
};

export async function analyzeGit(options: GitOptions): Promise<IGitBundle> {
export async function analyzeGit(options: GitOptions, requestOptions?: RequestOptions): Promise<IGitBundle> {
const analysisOptions: AnalyzeGitOptions = { ...analyzeGitDefaults, ...options };
const { baseURL, sessionToken, oAuthToken, username, includeLint, severity, gitUri, sarif, source } = analysisOptions;
const bundleResponse = await createGitBundle({
baseURL,
sessionToken,
oAuthToken,
username,
gitUri,
source,
});
const bundleResponse = await createGitBundle(
{
baseURL,
sessionToken,
oAuthToken,
username,
gitUri,
source,
},
requestOptions,
);
if (bundleResponse.type === 'error') {
throw bundleResponse.error;
}
const { bundleId } = bundleResponse.value;
const analysisData = await analyzeBundle({
baseURL,
sessionToken,
oAuthToken,
username,
includeLint,
severity,
bundleId,
source,
});
const analysisData = await analyzeBundle(
{
baseURL,
sessionToken,
oAuthToken,
username,
includeLint,
severity,
bundleId,
source,
},
requestOptions,
);

const result = {
baseURL,
Expand Down
49 changes: 28 additions & 21 deletions src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import axios from './axios';

import { IFiles, IFileContent, ISupportedFiles } from './interfaces/files.interface';
import { IAnalysisResult } from './interfaces/analysis-result.interface';
import { RequestOptions } from './interfaces/http-options.interface';

type ResultSuccess<T> = { type: 'success'; value: T };
type ResultError<E> = {
Expand Down Expand Up @@ -298,16 +299,19 @@ const CREATE_GIT_BUNDLE_ERROR_MESSAGES: { [P in CreateGitBundleErrorCodes]: stri
[ErrorCodes.notFound]: 'Unable to found requested repository or commit hash',
};

export async function createGitBundle(options: {
readonly baseURL: string;
readonly sessionToken: string;
readonly oAuthToken?: string;
readonly username?: string;
readonly gitUri: string;
readonly source: string;
}): Promise<IResult<RemoteBundle, CreateGitBundleErrorCodes>> {
export async function createGitBundle(
options: {
readonly baseURL: string;
readonly sessionToken: string;
readonly oAuthToken?: string;
readonly username?: string;
readonly gitUri: string;
readonly source: string;
},
requestOptions?: RequestOptions,
): Promise<IResult<RemoteBundle, CreateGitBundleErrorCodes>> {
const { baseURL, sessionToken, oAuthToken, username, gitUri, source } = options;
const headers = { 'Session-Token': sessionToken, source };
const headers = { ...requestOptions?.headers, 'Session-Token': sessionToken, source };
if (oAuthToken) {
headers['X-OAuthToken'] = oAuthToken;
}
Expand Down Expand Up @@ -409,17 +413,20 @@ const GET_ANALYSIS_ERROR_MESSAGES: { [P in GetAnalysisErrorCodes]: string } = {
[ErrorCodes.serverError]: 'Getting analysis failed',
};

export async function getAnalysis(options: {
readonly baseURL: string;
readonly sessionToken: string;
readonly bundleId: string;
readonly includeLint?: boolean;
readonly severity: number;
readonly limitToFiles?: string[];
readonly oAuthToken?: string;
readonly username?: string;
readonly source: string;
}): Promise<IResult<GetAnalysisResponseDto, GetAnalysisErrorCodes>> {
export async function getAnalysis(
options: {
readonly baseURL: string;
readonly sessionToken: string;
readonly bundleId: string;
readonly includeLint?: boolean;
readonly severity: number;
readonly limitToFiles?: string[];
readonly oAuthToken?: string;
readonly username?: string;
readonly source: string;
},
requestOptions?: RequestOptions,
): Promise<IResult<GetAnalysisResponseDto, GetAnalysisErrorCodes>> {
const {
baseURL,
sessionToken,
Expand All @@ -434,7 +441,7 @@ export async function getAnalysis(options: {
// ?linters=false is still a truthy query value, if(includeLint === false) we have to avoid sending the value altogether
const params = { severity, linters: includeLint || undefined };

const headers = { 'Session-Token': sessionToken, source };
const headers = { ...requestOptions?.headers, 'Session-Token': sessionToken, source };
if (oAuthToken) {
headers['X-OAuthToken'] = oAuthToken;
}
Expand Down
3 changes: 3 additions & 0 deletions src/interfaces/http-options.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface RequestOptions {
headers: { [key: string]: string };
}
34 changes: 34 additions & 0 deletions tests/git.analysis.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Log } from 'sarif';
import * as sarifSchema from './sarif-schema-2.1.0.json';
import { ErrorCodes } from '../src/constants';
import { IGitBundle } from '../src/interfaces/analysis-result.interface';
import axios from '../src/axios';

const oAuthToken = process.env.SNYK_OAUTH_KEY || '';
const sessionTokenNoRepoAccess = process.env.SNYK_API_KEY_NO_ACCESS || '';
Expand Down Expand Up @@ -191,6 +192,39 @@ describe('Functional test of analysis', () => {
});
});

describe('Custom request options', () => {
beforeAll(() => {
jest.mock('axios');
axios.request = jest.fn().mockRejectedValue({});
});

it(
'passes custom options correctly',
async () => {
try {
await analyzeGit(
{
baseURL,
sessionToken,
includeLint: false,
severity: 1,
gitUri: '[email protected]:DeepCodeAI/cli.git',
},
{ headers: { 'X-test-header': 'Snyk' } },
);
} catch (e) {
// expected to fail, we are interested in correct propagation of headers only
}
expect((axios.request as jest.Mock).mock.calls[0][0]).toMatchObject({headers: { 'X-test-header': 'Snyk' }});
},
TEST_TIMEOUT,
);

afterAll(() => {
jest.resetAllMocks();
});
});

function getNumOfIssues(bundle: IGitBundle): number {
let numberOfIssues = 0;

Expand Down

0 comments on commit e46f2e3

Please sign in to comment.