Skip to content

Commit

Permalink
feat(synchronizer): add synchronizer query to fetch all validation ne…
Browse files Browse the repository at this point in the history
…eded data
  • Loading branch information
f1ames committed Feb 2, 2024
1 parent 183c36b commit 7841156
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 0 deletions.
131 changes: 131 additions & 0 deletions packages/synchronizer/src/handlers/apiHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,79 @@ const getProjectQuery = `
}
`;

const getProjectPermissionsQuery = `
query getProjectPermissions($slug: String!) {
getProject(input: { slug: $slug }) {
permissions {
project {
view
update
delete
}
members {
view
update
delete
}
repositories {
read
write
}
}
}
}
`;

const getProjectDetailsQuery = `
query getProjectDetails($slug: String!, $owner: String!, $name: String!, $provider: String!) {
getProject(input: { slug: $slug }) {
id
name
slug
projectRepository: repository(input: { owner: $owner, name: $name, provider: $provider }) {
id
projectId
provider
owner
name
suppressions {
id
fingerprint
description
status
justification
expiresAt
isUnderReview
isAccepted
isRejected
isExpired
isDeleted
}
}
permissions {
project {
view
update
delete
}
members {
view
update
delete
}
repositories {
read
write
}
}
policy {
id
json
}
}
}
`;

const getPolicyQuery = `
query getPolicy($slug: String!) {
getProject(input: { slug: $slug }) {
Expand Down Expand Up @@ -183,6 +256,56 @@ export type ClientConfig = {
additionalData?: Record<string, string>;
};

export type ApiProjectPermissions = {
project: {
view: boolean,
update: boolean,
delete: boolean
},
members: {
view: boolean,
update: boolean,
delete: boolean
},
repositories: {
read: boolean,
write: boolean
}
};

export type ApiProjectPermissionsData = {
data: {
getProject: {
permissions: ApiProjectPermissions
}
}
};

export type ApiProjectDetailsData = {
data: {
getProject: {
id: number;
slug: string;
name: string;
projectRepository: ApiUserProjectRepo & {
suppressions: (ApiSuppression & {justification: string; expiresAt: string;})[];
};
permissions: ApiProjectPermissions;
policy: {
id: string;
json: any;
}
}
}
};

export type getProjectDetailsInput = {
slug: string;
owner: string;
name: string;
provider:string;
}

export class ApiHandler {
private _apiUrl: string;
private _clientConfig: ClientConfig;
Expand Down Expand Up @@ -229,6 +352,14 @@ export class ApiHandler {
return this.queryApi(getProjectQuery, tokenInfo, {slug});
}

async getProjectPermissions(slug: string, tokenInfo: TokenInfo): Promise<ApiProjectPermissionsData | undefined> {
return this.queryApi(getProjectPermissionsQuery, tokenInfo, {slug});
}

async getProjectDetails(input: getProjectDetailsInput, tokenInfo: TokenInfo): Promise<ApiProjectDetailsData | undefined>{
return this.queryApi(getProjectDetailsQuery, tokenInfo, input);
}

async getPolicy(slug: string, tokenInfo: TokenInfo): Promise<ApiPolicyData | undefined> {
return this.queryApi(getPolicyQuery, tokenInfo, {slug});
}
Expand Down
47 changes: 47 additions & 0 deletions packages/synchronizer/src/utils/synchronizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ export type ProjectInfo = {
slug: string;
};

export type ProjectRepoInputData = {
repoData: RepoRemoteInputData;
ownerProjectSlug: string;
};

export type ProjectRepoPathData = {
repoPath: string;
ownerProjectSlug: string;
};

export class Synchronizer extends EventEmitter {
private _pullPromise: Promise<PolicyData> | undefined;
private _projectDataCache: Record<string, ApiUserProject> = {};
Expand Down Expand Up @@ -91,6 +101,31 @@ export class Synchronizer extends EventEmitter {
};
}

async getProjectRepoDetails(projectRepoPath: ProjectRepoPathData, tokenInfo: TokenInfo): Promise<any>;
async getProjectRepoDetails(projectRepoData: ProjectRepoInputData, tokenInfo: TokenInfo): Promise<any>;
async getProjectRepoDetails(
projectRepoPathOrData: ProjectRepoPathData | ProjectRepoInputData,
tokenInfo: TokenInfo
) {
if (!tokenInfo || tokenInfo?.accessToken?.length === 0) {
throw new Error('Cannot fetch without access token.');
}

let projectRepoInput = projectRepoPathOrData as ProjectRepoInputData;
if (this.isProjectRepoPath(projectRepoPathOrData)) {
projectRepoInput = await this.getProjectRepoData(projectRepoPathOrData as ProjectRepoPathData);
}

const response = await this._apiHandler.getProjectDetails({
slug: projectRepoInput.ownerProjectSlug,
owner: projectRepoInput.repoData.owner,
name: projectRepoInput.repoData.name,
provider: projectRepoInput.repoData.provider,
}, tokenInfo);

return response?.data?.getProject;
}

async getPolicy(rootPath: string, forceRefetch?: boolean, tokenInfo?: TokenInfo): Promise<PolicyData>;
async getPolicy(
rootPathWithProject: RepoPathInputData,
Expand Down Expand Up @@ -452,6 +487,14 @@ export class Synchronizer extends EventEmitter {
return typeof inputData === 'string' ? await this.getRootGitData(inputData) : (inputData as RepoRemoteData);
}

private async getProjectRepoData(repoProjectPath: ProjectRepoPathData): Promise<ProjectRepoInputData> {
const gitData = await this.getRootGitData(repoProjectPath.repoPath);
return {
repoData: gitData,
ownerProjectSlug: repoProjectPath.ownerProjectSlug,
};
}

private isProjectData(projectData: any) {
return Object.keys(projectData).length === 1 && projectData.slug;
}
Expand All @@ -465,4 +508,8 @@ export class Synchronizer extends EventEmitter {
? input.slug ?? input.ownerProjectSlug
: undefined;
}

private isProjectRepoPath(repoData: any) {
return Object.keys(repoData).length === 2 && repoData.repoPath;
}
}

0 comments on commit 7841156

Please sign in to comment.