import axios, { AxiosError } from 'axios'; import Config from '../config/Config'; import ora from 'ora'; import ApiRoutes from '../sharedByClients/types/ApiRoutes'; import { StatusCodes } from 'http-status-codes'; import Enonce from '../sharedByClients/models/Enonce'; import GitlabUser from '../shared/types/Gitlab/GitlabUser'; import Exercice from '../sharedByClients/models/Exercice'; import DojoResponse from '../shared/types/DojoResponse'; class DojoBackendManager { public getApiUrl(route: ApiRoutes): string { return `${ Config.apiURL }${ route }`; } public async getEnonce(nameOrUrl: string): Promise<Enonce | undefined> { try { return (await axios.get<DojoResponse<Enonce>>(this.getApiUrl(ApiRoutes.ENONCE_GET).replace('{{nameOrUrl}}', encodeURIComponent(nameOrUrl)))).data.data; } catch ( error ) { return undefined; } } public async checkTemplateAccess(idOrNamespace: string, verbose: boolean = true): Promise<boolean> { const spinner: ora.Ora = ora('Checking template access'); if ( verbose ) { spinner.start(); } try { await axios.get(this.getApiUrl(ApiRoutes.GITLAB_CHECK_TEMPLATE_ACCESS).replace('{{id}}', idOrNamespace)); if ( verbose ) { spinner.succeed('Template access granted'); } return true; } catch ( error ) { if ( verbose ) { if ( error instanceof AxiosError ) { if ( error.response ) { if ( error.response.status === StatusCodes.NOT_FOUND ) { spinner.fail(`Template not found or access denied. Please check the template ID or url. Also, please check that the template have public/internal visibility or that your and Dojo account (${ Config.gitlab.dojoAccount.username }) have at least reporter role to the template (if private).`); } else if ( error.response.status === StatusCodes.UNAUTHORIZED ) { spinner.fail(`Please check that the template have public/internal visibility or that your and Dojo account (${ Config.gitlab.dojoAccount.username }) have at least reporter role to the template (if private).`); } else { spinner.fail(`Template error: ${ error.response.statusText }`); } } } else { spinner.fail(`Template error: ${ error }`); } } return false; } } public async createEnonce(name: string, members: Array<GitlabUser>, templateIdOrNamespace: string | null, verbose: boolean = true): Promise<Enonce> { const spinner: ora.Ora = ora('Creating enonce...'); if ( verbose ) { spinner.start(); } try { const response = await axios.post<DojoResponse<Enonce>>(this.getApiUrl(ApiRoutes.ENONCE_CREATE), Object.assign({ name : name, members: JSON.stringify(members) }, templateIdOrNamespace ? { template: templateIdOrNamespace } : {})); if ( verbose ) { spinner.succeed(`Enonce successfully created`); } return response.data.data; } catch ( error ) { if ( verbose ) { if ( error instanceof AxiosError ) { if ( error.response ) { if ( error.response.status === StatusCodes.CONFLICT ) { spinner.fail(`The enonce name is already used. Please choose another one.`); } else { spinner.fail(`Enonce creation error: ${ error.response.statusText }`); } } } else { spinner.fail(`Enonce creation error: unknown error`); } } throw error; } } public async createExercice(enonceName: string, members: Array<GitlabUser>, verbose: boolean = true): Promise<Exercice> { const spinner: ora.Ora = ora('Creating exercice...'); if ( verbose ) { spinner.start(); } try { const response = await axios.post<DojoResponse<Exercice>>(this.getApiUrl(ApiRoutes.EXERCICE_CREATE).replace('{{nameOrUrl}}', encodeURIComponent(enonceName)), { members: JSON.stringify(members) }); if ( verbose ) { spinner.succeed(`Exercice successfully created`); } return response.data.data; } catch ( error ) { if ( verbose ) { if ( error instanceof AxiosError ) { if ( error.response ) { if ( error.response.status === StatusCodes.CONFLICT ) { spinner.fail(`You've reached the max number of exercice of this enonce.`); } else { spinner.fail(`Exercice creation error: ${ error.response.statusText }`); } } } else { spinner.fail(`Exercice creation error: unknown error`); } } throw error; } } public async changeEnoncePublishedStatus(enonce: Enonce, publish: boolean, verbose: boolean = true) { const spinner: ora.Ora = ora('Changing published status...'); if ( verbose ) { spinner.start(); } try { await axios.patch<DojoResponse<null>>(this.getApiUrl(publish ? ApiRoutes.ENONCE_PUBLISH : ApiRoutes.ENONCE_UNPUBLISH).replace('{{nameOrUrl}}', encodeURIComponent(enonce.name)), {}); if ( verbose ) { spinner.succeed(`Enonce ${ enonce.name } successfully ${ publish ? 'published' : 'unpublished' }`); } return; } catch ( error ) { if ( verbose ) { if ( error instanceof AxiosError && error.response ) { spinner.fail(`Enonce visibility change error: ${ error.response.statusText }`); } else { spinner.fail(`Enonce visibility change error: unknown error`); } } throw error; } } } export default new DojoBackendManager();