Skip to content
Snippets Groups Projects
Commit 6cc275f3 authored by michael.minelli's avatar michael.minelli
Browse files

Add base of the project

parent e3f01f39
No related branches found
No related tags found
No related merge requests found
Showing
with 4057 additions and 0 deletions
.env*
.flaskenv*
!.env.project
!.env.vault
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<content url="file://$MODULE_DIR$/../../../UI/DojoCLI/.gitlab-ci-local">
<excludeFolder url="file://$MODULE_DIR$/../../../UI/DojoCLI/.gitlab-ci-local" />
</content>
<content url="file://$MODULE_DIR$/../../../UI/DojoCLI/NodeApp/.gitlab-ci-local">
<excludeFolder url="file://$MODULE_DIR$/../../../UI/DojoCLI/NodeApp/.gitlab-ci-local" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
jetbrainsConfiguration/codeStyles/
\ No newline at end of file
jetbrainsConfiguration/inspectionProfiles/
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/AssignmentChecker.iml" filepath="$PROJECT_DIR$/.idea/AssignmentChecker.iml" />
</modules>
</component>
</project>
\ No newline at end of file
jetbrainsConfiguration/rootFiles/sqldialects.xml
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$/src/shared" vcs="Git" />
<mapping directory="$PROJECT_DIR$/src/sharedByClients" vcs="Git" />
</component>
</project>
\ No newline at end of file
This diff is collapsed.
{
"name" : "dojo_assignment_checker",
"description" : "App that check an assignment of the Dojo project",
"version" : "2.2.0",
"license" : "AGPLv3",
"author" : "Michaël Minelli <dojo@minelli.me>",
"main" : "dist/app.js",
"bin" : {
"dirmanager": "./dist/app.js"
},
"pkg" : {
"scripts": [],
"assets" : [
"node_modules/axios/dist/node/axios.cjs",
".env",
"assets/**/*"
],
"targets": [
"node18-linux-arm64",
"node18-linux-x64"
]
},
"scripts" : {
"dotenv:build": "npx dotenv-vault local build",
"genversion" : "npx genversion -s -e src/config/Version.ts",
"build" : "npm run genversion; npx tsc",
"start:dev" : "npm run genversion; npx ts-node src/app.ts",
"test" : "echo \"Error: no test specified\" && exit 1"
},
"dependencies" : {
"ajv" : "^8.12.0",
"axios" : "^1.4.0",
"boxen" : "^5.1.2",
"chalk" : "^4.1.2",
"dockerode" : "^3.3.5",
"dotenv" : "^16.3.1",
"fs-extra" : "^11.1.1",
"http-status-codes": "^2.2.0",
"json5" : "^2.2.3",
"ora" : "^5.4.1",
"tar-stream" : "^3.1.6",
"winston" : "^3.10.0"
},
"devDependencies": {
"@types/dockerode" : "^3.3.19",
"@types/fs-extra" : "^11.0.1",
"@types/js-yaml" : "^4.0.5",
"@types/node" : "^18.17.1",
"@types/tar-stream" : "^2.2.2",
"dotenv-vault" : "^1.25.0",
"genversion" : "^3.1.1",
"pkg" : "^5.8.1",
"tiny-typed-emitter": "^2.1.0",
"ts-node" : "^10.9.1",
"typescript" : "^5.1.6"
}
}
// Read from the .env file
// ATTENTION : This lines MUST be the first of this file (except for the path import)
const path = require('node:path');
require('dotenv').config({
path : path.join(__dirname, '../.env'),
DOTENV_KEY: 'dotenv://:key_f1778b6998874f6fd78c716ccef982c5595fa300f174b129eafc88ba7044d69b@dotenv.local/vault/.env.vault?environment=development'
});
require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be the second of this file
import Styles from './types/Style';
import { exec } from 'child_process';
import util from 'util';
import HttpManager from './managers/HttpManager';
import Config from './config/Config';
(async () => {
const execAsync = util.promisify(exec);
HttpManager.registerAxiosInterceptor();
console.log(Styles.APP_NAME(`${ Config.appName } (version {{VERSION}})`));
})();
\ No newline at end of file
import fs from 'fs-extra';
import path from 'path';
class Config {
public readonly appName: string;
public readonly folders: {
project: string; resultsVolume: string; resultsDojo: string; resultsExercise: string;
};
public readonly dockerhub: {
repositories: {
assignmentChecker: string
}
};
constructor() {
this.appName = process.env.APP_NAME || '';
this.folders = {
project : process.env.PROJECT_FOLDER?.convertWithEnvVars() ?? './',
resultsVolume : process.env.EXERCISE_RESULTS_VOLUME?.convertWithEnvVars() ?? '',
resultsDojo : path.join(process.env.EXERCISE_RESULTS_VOLUME?.convertWithEnvVars() ?? '', 'Dojo/'),
resultsExercise: path.join(process.env.EXERCISE_RESULTS_VOLUME?.convertWithEnvVars() ?? '', 'Exercise/')
};
this.resetResultsVolume();
this.dockerhub = {
repositories: {
assignmentChecker: process.env.DOCKERHUB_ASSIGNMENT_CHECKER_REPOSITORY || ''
}
};
}
private resetResultsVolume(): void {
fs.emptyDirSync(this.folders.resultsVolume);
fs.emptyDirSync(this.folders.resultsDojo);
fs.emptyDirSync(this.folders.resultsExercise);
}
}
export default new Config();
import ClientsSharedConfig from '../sharedByClients/config/ClientsSharedConfig';
import ApiRoute from '../sharedByClients/types/Dojo/ApiRoute';
class DojoBackendManager {
public getApiUrl(route: ApiRoute): string {
return `${ ClientsSharedConfig.apiURL }${ route }`;
}
}
export default new DojoBackendManager();
import axios, { AxiosRequestHeaders } from 'axios';
import FormData from 'form-data';
import ClientsSharedConfig from '../sharedByClients/config/ClientsSharedConfig';
import Config from '../config/Config';
import { version } from '../config/Version';
import boxen from 'boxen';
import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode';
import DojoBackendResponse from '../shared/types/Dojo/DojoBackendResponse';
import { StatusCodes } from 'http-status-codes';
class HttpManager {
registerAxiosInterceptor() {
this.registerRequestInterceptor();
this.registerResponseInterceptor();
}
private requestError(message: string) {
console.log(boxen(message, {
title : 'Request error',
titleAlignment: 'center',
borderColor : 'red',
borderStyle : 'bold',
margin : 1,
padding : 1,
textAlignment : 'left'
}));
process.exit(1);
}
private registerRequestInterceptor() {
axios.interceptors.request.use((config) => {
if ( config.data instanceof FormData ) {
config.headers = { ...config.headers, ...(config.data as FormData).getHeaders() } as AxiosRequestHeaders;
}
if ( config.url && (config.url.indexOf(ClientsSharedConfig.apiURL) !== -1) ) {
config.headers['Accept-Encoding'] = 'gzip';
if ( config.data && Object.keys(config.data).length > 0 ) {
config.headers['Content-Type'] = 'multipart/form-data';
}
//config.headers.Authorization = `ExerciseSecret ${ Config.exercise.secret }`;
config.headers['client'] = 'DojoAssignmentChecker';
config.headers['client-version'] = version;
}
return config;
});
}
private registerResponseInterceptor() {
axios.interceptors.response.use((response) => {
return response;
}, (error) => {
if ( error.response ) {
if ( error.response.status === StatusCodes.METHOD_NOT_ALLOWED && error.response.data ) {
const data: DojoBackendResponse<{}> = error.response.data;
switch ( data.code ) {
case DojoStatusCode.CLIENT_NOT_SUPPORTED:
this.requestError('Client not recognized by the server. Please contact the administrator.');
break;
case DojoStatusCode.CLIENT_VERSION_NOT_SUPPORTED:
this.requestError(`AssignmentChecker version not supported by the server.\nPlease check that the CI/CD pipeline use the "${ Config.dockerhub.repositories.assignmentChecker }:latest" image.\nIf yes, try again later and if the problem persists, please contact the administrator.`);
break;
default:
break;
}
}
} else {
this.requestError('Error connecting to the server. Please check your internet connection. If the problem persists, please contact the administrator.');
}
return Promise.reject(error);
});
}
}
export default new HttpManager();
import chalk from 'chalk';
class Style {
public readonly APP_NAME = chalk.bgBlue.black.bold;
public readonly INFO = chalk.blue;
public readonly ERROR = chalk.red;
public readonly SUCCESS = chalk.green;
public readonly FAILURE = chalk.red;
}
export default new Style();
\ No newline at end of file
{
"compilerOptions": {
"rootDir" : "src",
"outDir" : "dist",
"strict" : true,
"target" : "es6",
"module" : "commonjs",
"sourceMap" : true,
"esModuleInterop" : true,
"moduleResolution": "node",
"noImplicitAny" : true
},
"exclude" : [
"node_modules"
]
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment