Skip to content

Commit

Permalink
Merge pull request #368 from snyk-tech-services/fix/update-targets-api
Browse files Browse the repository at this point in the history
fix: update targetAPI pagination
  • Loading branch information
lili2311 authored Oct 14, 2022
2 parents 7daee99 + 26b0a20 commit 5ee8711
Show file tree
Hide file tree
Showing 3 changed files with 853 additions and 852 deletions.
263 changes: 131 additions & 132 deletions src/lib/api/org/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import 'source-map-support/register';
import { requestsManager } from 'snyk-request-manager';
import * as debugLib from 'debug';
import * as qs from 'querystring';
import { getApiToken } from '../../get-api-token';
import { getSnykHost } from '../../get-snyk-host';
import { SnykProject, SnykTarget, TargetsResponse, RESTProjectData } from '../../types';
import { StringNullableChain } from 'lodash';
import { Console } from 'console';
import { url } from 'inspector';
import {
SnykProject,
RESTTargetResponse,
RESTProjectData,
SnykTarget,
} from '../../types';

const debug = debugLib('snyk:api-group');

Expand Down Expand Up @@ -143,7 +146,6 @@ interface ProjectsResponse {
projects: SnykProject[];
}


interface RESTProjectsResponse {
data: RESTProjectData[];
jsonapi: {
Expand All @@ -160,13 +162,12 @@ interface RESTProjectsResponse {
}

interface ProjectsFilters {
name?: StringNullableChain; // If supplied, only projects that have a name that starts with this value will be returned
name?: string; // If supplied, only projects that have a name that starts with this value will be returned
origin?: string; //If supplied, only projects that exactly match this origin will be returned
type?: string; //If supplied, only projects that exactly match this type will be returned
isMonitored?: boolean; // If set to true, only include projects which are monitored, if set to false, only include projects which are not monitored
}


export async function listProjects(
requestManager: requestsManager,
orgId: string,
Expand All @@ -183,58 +184,63 @@ export async function listProjects(
);
}

const projects = await listAllProjects(requestManager, orgId, filters)
const projects = await listAllProjects(requestManager, orgId, filters);

const snykProjectData: ProjectsResponse = {
org: {
id: orgId,
},
projects: projects
}
projects: projects,
};

return snykProjectData;
}

async function listAllProjects(requestManager: requestsManager,
async function listAllProjects(
requestManager: requestsManager,
orgId: string,
filters?: ProjectsFilters,
): Promise<SnykProject[]> {

let lastPage = false;
let projectsList: SnykProject[] = [];
let pageCount = 1;
let nextPageLink: string | undefined = undefined;
while (!lastPage) {
try {
const {
projects,
next,
}: {
projects: SnykProject[];
next?: string;
} = await getProject(requestManager, orgId, filters, nextPageLink);

projectsList = projectsList.concat(projects);
next
? ((lastPage = false), (nextPageLink = next))
: ((lastPage = true), (nextPageLink = ''));
pageCount++;
} catch (e) {
debug('Failed to update notification settings for ', orgId, e);
throw e;
): Promise<SnykProject[]> {
let lastPage = false;
const projectsList: SnykProject[] = [];
let pageCount = 1;
let nextPageLink: string | undefined = undefined;
while (!lastPage) {
try {
debug(
`Fetching page ${pageCount} to list all projects for org ${orgId}\n`,
);
const {
projects,
next,
}: {
projects: SnykProject[];
next?: string;
} = await getProject(requestManager, orgId, filters, nextPageLink);

projectsList.push(...projects);
next
? ((lastPage = false), (nextPageLink = next))
: ((lastPage = true), (nextPageLink = ''));
pageCount++;
} catch (e) {
debug('Failed to update notification settings for ', orgId, e);
throw e;
}
}
return projectsList
return projectsList;
}

async function getProject(requestManager: requestsManager,
async function getProject(
requestManager: requestsManager,
orgId: string,
filters?: ProjectsFilters,
nextPageLink?: string,
): Promise< { projects: SnykProject[], next?: string } > {

const url = nextPageLink ? nextPageLink : `/orgs/${orgId.trim()}/projects?version=2022-06-08~beta`
const res = await requestManager.request({
): Promise<{ projects: SnykProject[]; next?: string }> {
const url = nextPageLink
? nextPageLink
: `/orgs/${orgId.trim()}/projects?version=2022-06-08~beta`;
const res = await requestManager.request({
verb: 'get',
url: url,
body: JSON.stringify(filters),
Expand All @@ -248,44 +254,45 @@ async function getProject(requestManager: requestsManager,
JSON.stringify({ data: res.data, status: statusCode }),
);
}

const RESTresponseData = res.data as RESTProjectsResponse

const projects = convertToSnykProject(RESTresponseData.data)
const next = RESTresponseData.links.next
const RESTresponseData = res.data as RESTProjectsResponse;

return { projects, next}
const projects = convertToSnykProject(RESTresponseData.data);
const next = RESTresponseData.links.next;

return { projects, next };
}

function convertToSnykProject(projectData: RESTProjectData[]) : SnykProject[] {

function convertToSnykProject(projectData: RESTProjectData[]): SnykProject[] {
const projects: SnykProject[] = [];

for (const project of projectData) {
for (const project of projectData) {
const projectTmp: SnykProject = {
id : project.id,
branch : project.attributes.targetReference ,
created : project.attributes.created,
origin : project.attributes.origin,
name : project.attributes.name,
type: project.attributes.type,
}
projects.push(projectTmp)
id: project.id,
branch: project.attributes.targetReference,
created: project.attributes.created,
origin: project.attributes.origin,
name: project.attributes.name,
type: project.attributes.type,
};
projects.push(projectTmp);
}

return projects
}

return projects;
}
interface TargetFilters {
remoteUrl?: string;
limit?: number;
isPrivate?: boolean;
origin?: string;
displayName?: string;
excludeEmpty?: boolean;
}
export async function listTargets(
requestManager: requestsManager,
orgId: string,
config?: {
limit?: number,
isEmpty?: boolean,
origin?: string,
}
): Promise<TargetsResponse> {
config?: TargetFilters,
): Promise<{ targets: SnykTarget[] }> {
getApiToken();
getSnykHost();
debug(`Listing all targets for org: ${orgId}`);
Expand All @@ -296,76 +303,69 @@ export async function listTargets(
\nFor more information see: https://apidocs.snyk.io/?version=2022-09-15%7Ebeta#get-/orgs/-org_id-/targets`,
);
}

const targets = await listAllSnykTarget(requestManager, orgId, config)

return {targets: targets};
const targets = await listAllSnykTarget(requestManager, orgId, config);

return { targets };
}

export async function listAllSnykTarget(requestManager: requestsManager,
export async function listAllSnykTarget(
requestManager: requestsManager,
orgId: string,
config?: {
limit?: number,
isEmpty?: boolean,
origin?: string,
}
): Promise<SnykTarget[]> {

let lastPage = false;
let SnykTargetList: SnykTarget[] = [];
let pageCount = 1;
let nextPageLink: string | undefined = undefined;
while (!lastPage) {
try {
debug(`Fetching page ${pageCount} of get target for ${orgId}\n`);
const {
SnykTarget,
next,
}: {
SnykTarget: SnykTarget[];
next?: string;
} = await getSnykTarget(requestManager, orgId, nextPageLink, config);

SnykTargetList = SnykTargetList.concat(SnykTarget);
next
? ((lastPage = false), (nextPageLink = next))
: ((lastPage = true), (nextPageLink = ''));
pageCount++;
} catch (e) {
debug('Failed to get targets for ', orgId, e);
throw e;
config?: TargetFilters,
): Promise<SnykTarget[]> {
let lastPage = false;
const targetsList: SnykTarget[] = [];
let pageCount = 1;
let nextPageLink: string | undefined = undefined;
while (!lastPage) {
try {
debug(`Fetching page ${pageCount} of get target for ${orgId}\n`);
const {
targets,
next,
}: { targets: SnykTarget[]; next?: string } = await getSnykTarget(
requestManager,
orgId,
nextPageLink,
config,
);

targetsList.push(...targets);
next
? ((lastPage = false), (nextPageLink = next))
: ((lastPage = true), (nextPageLink = undefined));
pageCount++;
} catch (e) {
debug('Failed to get targets for ', orgId, e);
throw e;
}
}
return SnykTargetList
return targetsList;
}

export async function getSnykTarget(requestManager: requestsManager,
export async function getSnykTarget(
requestManager: requestsManager,
orgId: string,
nextPageLink?: string,
config?: {
limit?: number,
isEmpty?: boolean,
origin?: string,
}): Promise< { SnykTarget: SnykTarget[], next?: string } > {

const link = nextPageLink ? nextPageLink : `https://api.dev.snyk.io/rest/orgs/${orgId.trim()}/targets?version=2022-09-15~beta`
const url = new URL(link)

if (config) {
if (config.isEmpty) {
url.searchParams.set('isEmpty', String(config.isEmpty))
}
if (config.limit) {
url.searchParams.set('limit', String(config.limit))
}
if (config.origin) {
url.searchParams.set('origin', config.origin)
}
}

const res = await requestManager.request({
nextPageLink?: string,
config: {
limit?: number;
excludeEmpty?: boolean;
origin?: string;
} = {
limit: 20,
excludeEmpty: true,
},
): Promise<{ targets: SnykTarget[]; next?: string }> {
const query = qs.stringify({
version: '2022-09-15~beta',
...config,
});
const url = nextPageLink ?? `/orgs/${orgId.trim()}/targets?${query}`;

const res = await requestManager.request({
verb: 'get',
url: url.toString(),
url: url,
body: undefined,
useRESTApi: true,
});
Expand All @@ -377,11 +377,10 @@ export async function getSnykTarget(requestManager: requestsManager,
JSON.stringify({ data: res.data, status: statusCode }),
);
}

const responseData = res.data
const SnykTarget = responseData.data
const next = responseData.links.next

return { SnykTarget, next }
const responseData = res.data as RESTTargetResponse;
const targets = responseData.data;
const { next } = responseData.links;

return { targets, next };
}
Loading

0 comments on commit 5ee8711

Please sign in to comment.