diff --git a/config/SharedConfig.ts b/config/SharedConfig.ts
index 0f8f8b0397b4a855f9a761934e7a37f5a9e6b9a3..5bd7b65bddf9e0441d51bf269c37f0cbfb8fa80f 100644
--- a/config/SharedConfig.ts
+++ b/config/SharedConfig.ts
@@ -22,21 +22,21 @@ class SharedConfig {
     constructor() {
         this.production = process.env.NODE_ENV === 'production';
 
-        this.logsFolder = process.env.LOGS_FOLDER || '';
+        this.logsFolder = process.env.LOGS_FOLDER ?? '';
 
         this.gitlab = {
-            URL   : process.env.GITLAB_URL || '',
-            apiURL: process.env.GITLAB_API_URL || ''
+            URL   : process.env.GITLAB_URL ?? '',
+            apiURL: process.env.GITLAB_API_URL ?? ''
         };
 
         this.login = {
             gitlab: {
                 client: {
-                    id: process.env.LOGIN_GITLAB_CLIENT_ID || ''
+                    id: process.env.LOGIN_GITLAB_CLIENT_ID ?? ''
                 },
                 url   : {
-                    redirect: process.env.LOGIN_GITLAB_URL_REDIRECT || '',
-                    token   : process.env.LOGIN_GITLAB_URL_TOKEN || ''
+                    redirect: process.env.LOGIN_GITLAB_URL_REDIRECT ?? '',
+                    token   : process.env.LOGIN_GITLAB_URL_TOKEN ?? ''
                 }
             }
         };
diff --git a/helpers/ArchiveHelper.ts b/helpers/ArchiveHelper.ts
index f4449d6e8f4953227e0b422bb0a647a85432351c..b10ec6531bbd239509582a04fcf0b17e01f06e11 100644
--- a/helpers/ArchiveHelper.ts
+++ b/helpers/ArchiveHelper.ts
@@ -8,26 +8,26 @@ import zlib         from 'zlib';
 
 class ArchiveHelper {
     private async explore(absoluteBasePath: string, rootPath: string, pack: tar.Pack) {
-        for ( let file of await fs.promises.readdir(rootPath) ) {
-            if ( file === 'output.tar' ) {
-                continue;
-            }
-            file = path.join(rootPath, file);
-            const stat = await fs.promises.stat(file);
-            if ( stat.isDirectory() ) {
-                await this.explore(absoluteBasePath, file, pack);
-                continue;
-            }
-            const entry = pack.entry({
-                                         name: file.replace(absoluteBasePath, ''),
-                                         size: stat.size
-                                     }, (err) => {
-                if ( err ) {
-                    throw err;
+        for ( const file of await fs.promises.readdir(rootPath) ) {
+            let filename = file;
+            if ( filename !== 'output.tar' ) {
+                filename = path.join(rootPath, filename);
+                const stat = await fs.promises.stat(filename);
+                if ( stat.isDirectory() ) {
+                    await this.explore(absoluteBasePath, filename, pack);
+                } else {
+                    const entry = pack.entry({
+                                                 name: filename.replace(absoluteBasePath, ''),
+                                                 size: stat.size
+                                             }, err => {
+                        if ( err ) {
+                            throw err;
+                        }
+                    });
+                    const readStream = fs.createReadStream(filename);
+                    readStream.pipe(entry);
                 }
-            });
-            const stream = fs.createReadStream(file);
-            stream.pipe(entry);
+            }
         }
     }
 
@@ -55,7 +55,7 @@ class ArchiveHelper {
 
         await this.compress(folderPath, tarDataStream);
 
-        data = await (new Promise((resolve) => {
+        data = await (new Promise(resolve => {
             tarDataStream.on('close', () => {
                 resolve(data);
             });
diff --git a/helpers/Dojo/SharedAssignmentHelper.ts b/helpers/Dojo/SharedAssignmentHelper.ts
index b103f8cc526ed60a9aa6b7c5276557bcf1ab6635..d57caab79ec99384f09629c803cccb2dc2739950 100644
--- a/helpers/Dojo/SharedAssignmentHelper.ts
+++ b/helpers/Dojo/SharedAssignmentHelper.ts
@@ -1,30 +1,29 @@
-import AssignmentFile       from '../../types/Dojo/AssignmentFile';
-import GitlabPipelineStatus from '../../types/Gitlab/GitlabPipelineStatus';
-import DojoStatusCode       from '../../types/Dojo/DojoStatusCode';
-import GitlabPipeline       from '../../types/Gitlab/GitlabPipeline';
-import SharedGitlabManager  from '../../managers/SharedGitlabManager';
-import Json5FileValidator   from '../Json5FileValidator';
+import AssignmentFile       from '../../types/Dojo/AssignmentFile.js';
+import DojoStatusCode       from '../../types/Dojo/DojoStatusCode.js';
+import Json5FileValidator   from '../Json5FileValidator.js';
+import * as Gitlab          from '@gitbeaker/rest';
+import GitlabPipelineStatus from '../../types/Gitlab/GitlabPipelineStatus.js';
+import GitlabManager        from '../../../managers/GitlabManager.js';
 
 
 class SharedAssignmentHelper {
     validateDescriptionFile(filePathOrStr: string, isFile: boolean = true, version: number = 1): { content: AssignmentFile | undefined, isValid: boolean, error: string | null } {
-        switch ( version ) {
-            case 1:
-                return Json5FileValidator.validateFile(AssignmentFile, filePathOrStr, isFile);
-            default:
-                return {
-                    content: undefined,
-                    isValid: false,
-                    error  : `Version ${ version } not supported`
-                };
+        if ( version === 1 ) {
+            return Json5FileValidator.validateFile(AssignmentFile, filePathOrStr, isFile);
+        } else {
+            return {
+                content: undefined,
+                isValid: false,
+                error  : `Version ${ version } not supported`
+            };
         }
     }
 
-    async isPublishable(repositoryId: number): Promise<{ isPublishable: boolean, lastPipeline: GitlabPipeline | null, status?: { code: DojoStatusCode, message: string } }> {
-        const pipelines = await SharedGitlabManager.getRepositoryPipelines(repositoryId, 'main');
+    async isPublishable(repositoryId: number): Promise<{ isPublishable: boolean, lastPipeline: Gitlab.PipelineSchema | null, status?: { code: DojoStatusCode, message: string } }> {
+        const pipelines = await GitlabManager.getRepositoryPipelines(repositoryId, 'main');
         if ( pipelines.length > 0 ) {
             const lastPipeline = pipelines[0];
-            if ( lastPipeline.status != GitlabPipelineStatus.SUCCESS ) {
+            if ( lastPipeline.status !== GitlabPipelineStatus.SUCCESS.valueOf() ) {
                 return {
                     isPublishable: false,
                     lastPipeline : lastPipeline,
diff --git a/helpers/Dojo/SharedExerciseHelper.ts b/helpers/Dojo/SharedExerciseHelper.ts
deleted file mode 100644
index 97ccf7c9a39682ba8b14fa65b54a89d9898ebf3c..0000000000000000000000000000000000000000
--- a/helpers/Dojo/SharedExerciseHelper.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-class SharedExerciseHelper {}
-
-
-export default new SharedExerciseHelper();
\ No newline at end of file
diff --git a/helpers/LazyVal.ts b/helpers/LazyVal.ts
index 4613c4b535706f5853b060279ce46a957e3c3030..a06ba8b1a0cf8cb20ff87f7862a2e4c5d5f1b854 100644
--- a/helpers/LazyVal.ts
+++ b/helpers/LazyVal.ts
@@ -1,10 +1,13 @@
 class LazyVal<T> {
     private val: T | undefined = undefined;
+    private readonly valLoader: () => Promise<T> | T;
 
-    constructor(private valLoader: () => Promise<T> | T) {}
+    constructor(valLoader: () => Promise<T> | T) {
+        this.valLoader = valLoader;
+    }
 
     get value(): Promise<T> {
-        return new Promise<T>((resolve) => {
+        return new Promise<T>(resolve => {
             if ( this.val === undefined ) {
                 Promise.resolve(this.valLoader()).then((value: T) => {
                     this.val = value;
diff --git a/helpers/Toolbox.ts b/helpers/Toolbox.ts
index 8a76bebb202e6bcbe46944e562924effdeb26afe..d0fbfd5e26a97250a8232ba2b5f05ae9121be92e 100644
--- a/helpers/Toolbox.ts
+++ b/helpers/Toolbox.ts
@@ -14,8 +14,9 @@ class Toolbox {
         const files = await fs.readdir(dirPath);
 
         await Promise.all(files.map(async file => {
-            if ( (await fs.stat(dirPath + '/' + file)).isDirectory() ) {
-                arrayOfFiles = await this.getAllFiles(dirPath + '/' + file, arrayOfFiles);
+            const filePath = path.join(dirPath, file);
+            if ( (await fs.stat(filePath)).isDirectory() ) {
+                arrayOfFiles = await this.getAllFiles(filePath, arrayOfFiles);
             } else {
                 arrayOfFiles.push(path.join(dirPath, file));
             }
@@ -50,6 +51,10 @@ class Toolbox {
     public getKeysWithPrefix(obj: object, prefix: string): Array<string> {
         return Object.keys(obj).filter(key => key.startsWith(prefix));
     }
+
+    public isString(value: unknown): value is string {
+        return typeof value === 'string' || value instanceof String;
+    }
 }
 
 
diff --git a/helpers/TypeScriptExtensions.ts b/helpers/TypeScriptExtensions.ts
index fd730ad37daa50a1b6e855efaf3c48ce739faa05..0fc9c70f416cd51c3de2995e2b4e93df47092672 100644
--- a/helpers/TypeScriptExtensions.ts
+++ b/helpers/TypeScriptExtensions.ts
@@ -64,9 +64,7 @@ function registerStringCapitalizeName() {
 
 function registerStringConvertWithEnvVars() {
     String.prototype.convertWithEnvVars = function (this: string): string {
-        return this.replace(/\${?([a-zA-Z0-9_]+)}?/g, (_match: string, p1: string) => {
-            return process.env[p1] || '';
-        });
+        return this.replace(/\${?([a-zA-Z0-9_]+)}?/g, (_match: string, p1: string) => process.env[p1] || '');
     };
 }
 
diff --git a/helpers/recursiveFilesStats/RecursiveFilesStats.ts b/helpers/recursiveFilesStats/RecursiveFilesStats.ts
index a571aaac797de782ee6bc95d33ad9e75ee03b647..a71bffd40bdc53efee7b4a153f7e42a1cf8f9c02 100644
--- a/helpers/recursiveFilesStats/RecursiveFilesStats.ts
+++ b/helpers/recursiveFilesStats/RecursiveFilesStats.ts
@@ -51,32 +51,36 @@ class RecursiveFilesStats {
         return this.getFiles(`${ path.resolve(rootPath) }/`, rootPath, options, [], callback);
     }
 
-    private async getFiles(absoluteBasePath: string, rootPath: string, options: RecursiveReaddirFilesOptions = {}, files: IFileDirStat[] = [], callback?: Callback): Promise<IFileDirStat[]> {
-        const {
-                  ignored, include, exclude, filter
-              } = options;
+    private async getFilesDirsStat(rootPath: string, options: RecursiveReaddirFilesOptions): Promise<Array<IFileDirStat>> {
         const filesData = await fs.promises.readdir(rootPath);
-        const fileDir: IFileDirStat[] = filesData.map((file) => ({
-            name: file, path: path.join(rootPath, file)
-        })).filter((item) => {
-            if ( include && include.test(item.path) ) {
+        return filesData.map(file => ({
+            name: file,
+            path: path.join(rootPath, file)
+        })).filter(item => {
+            if ( options.include && options.include.test(item.path) ) {
                 return true;
             }
-            if ( exclude && exclude.test(item.path) ) {
+            if ( options.exclude && options.exclude.test(item.path) ) {
                 return false;
             }
-            if ( ignored ) {
-                return !ignored.test(item.path);
+            if ( options.ignored ) {
+                return !options.ignored.test(item.path);
             }
             return true;
         });
+    }
+
+    private async getFiles(absoluteBasePath: string, rootPath: string, options: RecursiveReaddirFilesOptions = {}, files: IFileDirStat[] = [], callback?: Callback): Promise<IFileDirStat[]> {
+        const fileDir: Array<IFileDirStat> = await this.getFilesDirsStat(rootPath, options);
+
         if ( callback ) {
-            fileDir.map(async (item: IFileDirStat) => {
-                const stat = await this.getStat(item.path, absoluteBasePath, options);
-                if ( stat.isDirectory!() ) {
-                    await this.getFiles(absoluteBasePath, item.path, options, [], callback);
-                }
-                callback(item.path, stat);
+            fileDir.forEach(item => {
+                this.getStat(item.path, absoluteBasePath, options).then(stat => {
+                    if ( stat.isDirectory!() ) {
+                        this.getFiles(absoluteBasePath, item.path, options, [], callback).then();
+                    }
+                    callback(item.path, stat);
+                });
             });
         } else {
             await Promise.all(fileDir.map(async (item: IFileDirStat) => {
@@ -89,9 +93,9 @@ class RecursiveFilesStats {
                 }
             }));
         }
-        return files.filter((item) => {
-            if ( filter && typeof filter === 'function' ) {
-                return filter(item);
+        return files.filter(item => {
+            if ( options.filter && typeof options.filter === 'function' ) {
+                return options.filter(item);
             }
             return true;
         });
@@ -124,10 +128,7 @@ class RecursiveFilesStats {
             delete stat.ctimeMs;
             delete stat.birthtimeMs;
             delete stat.atime;
-            //delete stat.mtime;
             delete stat.ctime;
-            //delete stat.birthtime;
-            //delete stat.mode;
         }
 
         return stat;
diff --git a/logging/WinstonLogger.ts b/logging/WinstonLogger.ts
index 941e5388ed95b1f281c21f5d2bf2c0c9217ae10a..a81f1edc4cc3f429ba1d27135cc890150014aea3 100644
--- a/logging/WinstonLogger.ts
+++ b/logging/WinstonLogger.ts
@@ -1,5 +1,5 @@
 import winston        from 'winston';
-import SharedConfig   from '../config/SharedConfig';
+import SharedConfig   from '../config/SharedConfig.js';
 import * as Transport from 'winston-transport';
 
 
@@ -23,7 +23,11 @@ winston.addColors(colors);
 const format = winston.format.combine(winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format(info => ({
     ...info,
     level: info.level.toUpperCase()
-}))(), SharedConfig.production ? winston.format.uncolorize() : winston.format.colorize({ all: true }), winston.format.prettyPrint(), winston.format.errors({ stack: true }), winston.format.align(), winston.format.printf((info) => `[${ info.timestamp }] (${ process.pid }) ${ info.level } ${ info.message } ${ info.metadata ? `\n${ JSON.stringify(info.metadata) }` : '' } ${ info.stack ? `\n${ info.stack }` : '' } `));
+}))(), SharedConfig.production ? winston.format.uncolorize() : winston.format.colorize({ all: true }), winston.format.prettyPrint(), winston.format.errors({ stack: true }), winston.format.align(), winston.format.printf(info => {
+    const metadata = info.metadata ? `\n${ JSON.stringify(info.metadata) }` : '';
+    const stack = info.stack ? `\n${ info.stack }` : '';
+    return `[${ info.timestamp }] (${ process.pid }) ${ info.level } ${ info.message } ${ metadata } ${ stack } `;
+}));
 
 const commonTransportOptions = {
     handleRejections: true,
@@ -54,11 +58,11 @@ if ( SharedConfig.production ) {
                                                                                                  }) ]);
 }
 
-const logger = winston.createLogger({
-                                        levels,
-                                        format,
-                                        transports,
-                                        exitOnError: false
-                                    });
+const WinstonLogger = winston.createLogger({
+                                               levels,
+                                               format,
+                                               transports,
+                                               exitOnError: false
+                                           });
 
-export default logger;
+export default WinstonLogger;
diff --git a/managers/SharedGitlabManager.ts b/managers/SharedGitlabManager.ts
index 68ff699a036044872cb7f33ead08782afbbdb830..abddde1b5ca0b38cc6bdc7039deca77f880a5d68 100644
--- a/managers/SharedGitlabManager.ts
+++ b/managers/SharedGitlabManager.ts
@@ -1,13 +1,38 @@
-import axios          from 'axios';
-import GitlabPipeline from '../types/Gitlab/GitlabPipeline';
-import GitlabRoute    from '../types/Gitlab/GitlabRoute';
-import SharedConfig   from '../config/SharedConfig';
-import GitlabToken    from '../types/Gitlab/GitlabToken';
+import axios                                                 from 'axios';
+import SharedConfig                                          from '../config/SharedConfig.js';
+import * as GitlabCore                                       from '@gitbeaker/core';
+import { GitbeakerRequestError }                             from '@gitbeaker/requester-utils';
+import { Gitlab, PipelineSchema, ProjectSchema, UserSchema } from '@gitbeaker/rest';
+import GitlabToken                                           from '../types/Gitlab/GitlabToken.js';
 
 
-class GitlabManager {
-    private getApiUrl(route: GitlabRoute): string {
-        return `${ SharedConfig.gitlab.apiURL }${ route }`;
+class SharedGitlabManager {
+    protected api!: GitlabCore.Gitlab<false>;
+    private readonly refreshTokenFunction?: () => Promise<string>;
+
+    setToken(token: string) {
+        this.api = new Gitlab(Object.assign({
+                                                host: SharedConfig.gitlab.URL
+                                            }, this.refreshTokenFunction ? { oauthToken: token } : { token: token }));
+    }
+
+    constructor(token: string, refreshTokenFunction?: () => Promise<string>) {
+        this.refreshTokenFunction = refreshTokenFunction;
+        this.setToken(token);
+    }
+
+    protected async executeGitlabRequest<T>(request: () => Promise<T>, refreshTokenIfNeeded: boolean = true): Promise<T> {
+        try {
+            return await request();
+        } catch ( error ) {
+            if ( this.refreshTokenFunction && refreshTokenIfNeeded && error instanceof GitbeakerRequestError ) {
+                this.setToken(await this.refreshTokenFunction());
+
+                return this.executeGitlabRequest(request, false);
+            } else {
+                throw error;
+            }
+        }
     }
 
     async getTokens(codeOrRefresh: string, isRefresh: boolean = false, clientSecret: string = ''): Promise<GitlabToken> {
@@ -23,16 +48,43 @@ class GitlabManager {
         return response.data;
     }
 
-    async getRepositoryPipelines(repoId: number, branch: string = 'main'): Promise<Array<GitlabPipeline>> {
-        const response = await axios.get<Array<GitlabPipeline>>(this.getApiUrl(GitlabRoute.REPOSITORY_PIPELINES).replace('{{id}}', String(repoId)), {
-            params: {
-                ref: branch
-            }
-        });
+    public async getUserById(id: number): Promise<UserSchema | undefined> {
+        try {
+            return await this.executeGitlabRequest(async () => {
+                const user = await this.api.Users.show(id);
 
-        return response.data;
+                return user.id === id ? user : undefined;
+            });
+        } catch ( e ) {
+            return undefined;
+        }
+    }
+
+    public async getUserByUsername(username: string): Promise<UserSchema | undefined> {
+        try {
+            return await this.executeGitlabRequest(async () => {
+                const user = await this.api.Users.all({
+                                                          username: username,
+                                                          maxPages: 1,
+                                                          perPage : 1
+                                                      });
+
+
+                return user.length > 0 && user[0].username === username ? user[0] : undefined;
+            });
+        } catch ( e ) {
+            return undefined;
+        }
+    }
+
+    async getRepository(projectIdOrNamespace: string): Promise<ProjectSchema> {
+        return this.executeGitlabRequest(() => this.api.Projects.show(projectIdOrNamespace));
+    }
+
+    async getRepositoryPipelines(repoId: number, branch: string = 'main'): Promise<Array<PipelineSchema>> {
+        return this.executeGitlabRequest(() => this.api.Pipelines.all(repoId, { ref: branch }));
     }
 }
 
 
-export default new GitlabManager();
+export default SharedGitlabManager;
diff --git a/types/Dojo/AssignmentFile.ts b/types/Dojo/AssignmentFile.ts
index df09d53ae249bf3614debd251630eb10e96a5c0b..91ec64d9fb422adad494b42575a1043788ce4d9d 100644
--- a/types/Dojo/AssignmentFile.ts
+++ b/types/Dojo/AssignmentFile.ts
@@ -1,11 +1,11 @@
-import ImmutableFileDescriptor from './ImmutableFileDescriptor';
+import ImmutableFileDescriptor from './ImmutableFileDescriptor.js';
 import { z }                   from 'zod';
 
 
 const AssignmentFile = z.object({
                                     dojoAssignmentVersion: z.number(),
                                     version              : z.number(),
-                                    immutable            : z.array(ImmutableFileDescriptor.transform(value => value as ImmutableFileDescriptor)),
+                                    immutable            : z.array(ImmutableFileDescriptor),
                                     result               : z.object({
                                                                         container: z.string(),
                                                                         volume   : z.string().optional()
diff --git a/types/Dojo/DojoStatusCode.ts b/types/Dojo/DojoStatusCode.ts
index 16f152daedf7a9f3b8154ea632dce404b8ccc8cf..76ed11746a292ccb238cead51f6f994885aa9bbd 100644
--- a/types/Dojo/DojoStatusCode.ts
+++ b/types/Dojo/DojoStatusCode.ts
@@ -1,19 +1,22 @@
 enum DojoStatusCode {
-    LOGIN_FAILED                        = 1,
-    REFRESH_TOKENS_FAILED               = 2,
-    CLIENT_NOT_SUPPORTED                = 100,
-    CLIENT_VERSION_NOT_SUPPORTED        = 110,
-    ASSIGNMENT_PUBLISH_NO_PIPELINE      = 200,
-    ASSIGNMENT_PUBLISH_PIPELINE_FAILED  = 201,
-    ASSIGNMENT_CREATION_GITLAB_ERROR    = 202,
-    ASSIGNMENT_CREATION_INTERNAL_ERROR  = 203,
-    ASSIGNMENT_EXERCISE_NOT_RELATED     = 204,
-    ASSIGNMENT_NOT_PUBLISHED            = 205,
-    EXERCISE_CORRECTION_NOT_EXIST       = 206,
-    EXERCISE_CORRECTION_ALREADY_EXIST   = 207,
-    EXERCISE_CREATION_GITLAB_ERROR      = 302,
-    EXERCISE_CREATION_INTERNAL_ERROR    = 303,
-    MAX_EXERCISE_PER_ASSIGNMENT_REACHED = 304
+    LOGIN_FAILED                        = 10001,
+    REFRESH_TOKENS_FAILED               = 10002,
+    CLIENT_NOT_SUPPORTED                = 10100,
+    CLIENT_VERSION_NOT_SUPPORTED        = 10110,
+    ASSIGNMENT_PUBLISH_NO_PIPELINE      = 10200,
+    ASSIGNMENT_PUBLISH_PIPELINE_FAILED  = 10201,
+    ASSIGNMENT_CREATION_GITLAB_ERROR    = 10202,
+    ASSIGNMENT_CREATION_INTERNAL_ERROR  = 10203,
+    ASSIGNMENT_EXERCISE_NOT_RELATED     = 10204,
+    ASSIGNMENT_NOT_PUBLISHED            = 10205,
+    EXERCISE_CORRECTION_NOT_EXIST       = 10206,
+    EXERCISE_CORRECTION_ALREADY_EXIST   = 10207,
+    ASSIGNMENT_NAME_CONFLICT            = 10208,
+    EXERCISE_CREATION_GITLAB_ERROR      = 10302,
+    EXERCISE_CREATION_INTERNAL_ERROR    = 10303,
+    MAX_EXERCISE_PER_ASSIGNMENT_REACHED = 10304,
+    GITLAB_TEMPLATE_NOT_FOUND           = 10401,
+    GITLAB_TEMPLATE_ACCESS_UNAUTHORIZED = 10402,
 }
 
 
diff --git a/types/Dojo/ExerciseResultsFile.ts b/types/Dojo/ExerciseResultsFile.ts
index 135a532d11623c74389f049ec83da16a2c5988f2..69c9825e6a2b661a180ca6b1db3387fcdce8a10c 100644
--- a/types/Dojo/ExerciseResultsFile.ts
+++ b/types/Dojo/ExerciseResultsFile.ts
@@ -1,4 +1,4 @@
-import Icon  from '../Icon';
+import Icon  from '../Icon.js';
 import { z } from 'zod';
 
 
@@ -19,7 +19,7 @@ const ExerciseResultsFile = z.object({
                                                                                  icon               : z.enum(Object.keys(Icon) as [ firstKey: string, ...otherKeys: Array<string> ]).optional(),
                                                                                  itemsOrInformations: z.union([ z.array(z.string()), z.string() ])
                                                                              }))
-                                         .optional()
+                                             .optional()
                                      }).strict().transform(value => {
     if ( value.successfulTests === undefined && value.successfulTestsList !== undefined ) {
         value.successfulTests = value.successfulTestsList.length;
diff --git a/types/Gitlab/GitlabAccessLevel.ts b/types/Gitlab/GitlabAccessLevel.ts
deleted file mode 100644
index be06ffd009103feb9f30a4e18250c2fcf978527b..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabAccessLevel.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-enum GitlabAccessLevel {
-    GUEST      = 10,
-    REPORTER   = 20,
-    DEVELOPER  = 30,
-    MAINTAINER = 40,
-    OWNER      = 50,
-    ADMIN      = 60
-}
-
-
-export default GitlabAccessLevel;
diff --git a/types/Gitlab/GitlabCommit.ts b/types/Gitlab/GitlabCommit.ts
deleted file mode 100644
index 5f94c2e431b220b4247e0dc3bf0222fba14f2a1c..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabCommit.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-interface GitlabCommit {
-    id: string;
-    short_id: string;
-    created_at: string;
-    parent_ids: Array<string>;
-    title: string;
-    message: string;
-    author_name: string;
-    author_email: string;
-    authored_date: string;
-    committer_name: string;
-    committer_email: string;
-    committed_date: string;
-}
-
-
-export default GitlabCommit;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabFile.ts b/types/Gitlab/GitlabFile.ts
deleted file mode 100644
index 05205d4f1e28d5d04e60ae304acb02f3ddcb0d02..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabFile.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-interface GitlabFile {
-    file_name: string,
-    file_path: string,
-    size: number,
-    encoding: string,
-    content_sha256: string,
-    ref: string,
-    blob_id: string,
-    commit_id: string,
-    last_commit_id: string,
-    execute_filemode: boolean,
-    content: string,
-}
-
-
-export default GitlabFile;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabGroup.ts b/types/Gitlab/GitlabGroup.ts
deleted file mode 100644
index 812f8838b5e00eb50cea0a282e3e26dc20344fef..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabGroup.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-interface GitlabGroup {
-    group_id: number,
-    group_name: string,
-    group_full_path: string,
-    group_access_level: number,
-    expires_at: string
-}
-
-
-export default GitlabGroup;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabMember.ts b/types/Gitlab/GitlabMember.ts
deleted file mode 100644
index 6c7c7163f73104221de918af4ceb09d4a55c98e2..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabMember.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import GitlabUser from './GitlabUser';
-
-
-interface GitlabMember extends GitlabUser {
-    access_level: number,
-    created_at: string,
-    created_by: GitlabUser,
-    expires_at: string | null
-}
-
-
-export default GitlabMember;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabMilestone.ts b/types/Gitlab/GitlabMilestone.ts
deleted file mode 100644
index a7285cd9ee3683aeaf4ebc1ea85ab778af1e970c..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabMilestone.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-interface GitlabMilestone {
-    id: number;
-    iid: number;
-    project_id: number;
-    title: string;
-    description: string;
-    state: string;
-    created_at: string;
-    updated_at: string;
-    due_date: string;
-    start_date: string;
-    web_url: string;
-    issue_stats: {
-        total: number; closed: number;
-    };
-}
-
-
-export default GitlabMilestone;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabNamespace.ts b/types/Gitlab/GitlabNamespace.ts
deleted file mode 100644
index 4d892afb58d81138a6b204124fc5b2ed6526eeca..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabNamespace.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-interface GitlabNamespace {
-    id: number,
-    name: string,
-    path: string,
-    kind: string,
-    full_path: string,
-    parent_id: number,
-    avatar_url: string,
-    web_url: string
-}
-
-
-export default GitlabNamespace;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabPipeline.ts b/types/Gitlab/GitlabPipeline.ts
deleted file mode 100644
index 1ee75b643b458b1f0c924f5d47f7ae0f0f88ddb0..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabPipeline.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import GitlabPipelineStatus from './GitlabPipelineStatus';
-import GitlabPipelineSource from './GitlabPipelineSource';
-import GitlabUser           from './GitlabUser';
-
-
-interface GitlabPipeline {
-    id: number,
-    iid: number,
-    project_id: number,
-    status: GitlabPipelineStatus,
-    source: GitlabPipelineSource,
-    ref: string,
-    sha: string,
-    before_sha: string,
-    tag: boolean,
-    name: string,
-    yaml_errors: string | null,
-    user: GitlabUser,
-    web_url: string,
-    created_at: string,
-    updated_at: string,
-    started_at: string | null,
-    finished_at: string | null,
-    committed_at: string | null,
-    duration: number | null,
-    queued_duration: number | null,
-    coverage: string | null,
-}
-
-
-export default GitlabPipeline;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabProfile.ts b/types/Gitlab/GitlabProfile.ts
deleted file mode 100644
index aa7506dbddcf7051a29c118d69fc26d1f7fb55bb..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabProfile.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import GitlabUser from './GitlabUser';
-
-
-interface GitlabProfile extends GitlabUser {
-    created_at: string,
-    bio: string,
-    location: string,
-    public_email: string,
-    skype: string,
-    linkedin: string,
-    twitter: string,
-    discord: string,
-    website_url: string,
-    organization: string,
-    job_title: string,
-    pronouns: string,
-    bot: boolean,
-    work_information: string,
-    local_time: string,
-    last_sign_in_at: string,
-    confirmed_at: string,
-    last_activity_on: string,
-    email: string,
-    theme_id: number,
-    color_scheme_id: number,
-    projects_limit: number,
-    current_sign_in_at: string,
-    identities: Array<{
-        provider: string, extern_uid: string
-    }>,
-    can_create_group: boolean,
-    can_create_project: boolean,
-    two_factor_enabled: boolean,
-    external: boolean,
-    private_profile: boolean,
-    commit_email: string
-}
-
-
-export default GitlabProfile;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabRelease.ts b/types/Gitlab/GitlabRelease.ts
deleted file mode 100644
index a7c68d770e4e88c7acd2f6f6eb1305329c42f61d..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabRelease.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import GitlabUser      from './GitlabUser';
-import GitlabCommit    from './GitlabCommit';
-import GitlabMilestone from './GitlabMilestone';
-
-
-interface GitlabRelease {
-    tag_name: string;
-    description: string;
-    created_at: string;
-    released_at: string;
-    author: GitlabUser;
-    commit: GitlabCommit;
-    milestones: Array<GitlabMilestone>;
-    commit_path: string;
-    tag_path: string;
-    assets: {
-        count: number; sources: Array<{
-            format: string; url: string;
-        }>; links: Array<{
-            id: number; name: string; url: string; link_type: string;
-        }>; evidence_file_path: string;
-    };
-    evidences: Array<{
-        sha: string; filepath: string; collected_at: string;
-    }>;
-}
-
-
-export default GitlabRelease; 
\ No newline at end of file
diff --git a/types/Gitlab/GitlabRepository.ts b/types/Gitlab/GitlabRepository.ts
deleted file mode 100644
index 0aa260287cc95030231761b2781a31a1b203f22b..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabRepository.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import GitlabGroup     from './GitlabGroup';
-import GitlabNamespace from './GitlabNamespace';
-
-
-interface GitlabRepository {
-    id: number,
-    description: string,
-    name: string,
-    name_with_namespace: string,
-    path: string,
-    path_with_namespace: string,
-    created_at: string,
-    default_branch: string,
-    tag_list: Array<string>,
-    topics: Array<string>,
-    ssh_url_to_repo: string,
-    http_url_to_repo: string,
-    web_url: string,
-    readme_url: string,
-    forks_count: number,
-    avatar_url: string,
-    star_count: number,
-    last_activity_at: string,
-    namespace: GitlabNamespace,
-    _links: {
-        self: string, issues: string, merge_requests: string, repo_branches: string, labels: string, events: string, members: string, cluster_agents: string
-    },
-    packages_enabled: boolean,
-    empty_repo: boolean,
-    archived: boolean,
-    visibility: string,
-    resolve_outdated_diff_discussions: boolean,
-    container_expiration_policy: {
-        cadence: string, enabled: boolean, keep_n: number, older_than: string, name_regex: string, name_regex_keep: string, next_run_at: string
-    },
-    issues_enabled: boolean,
-    merge_requests_enabled: boolean,
-    wiki_enabled: boolean,
-    jobs_enabled: boolean,
-    snippets_enabled: boolean,
-    container_registry_enabled: boolean,
-    service_desk_enabled: boolean,
-    service_desk_address: string,
-    can_create_merge_request_in: boolean,
-    issues_access_level: string,
-    repository_access_level: string,
-    merge_requests_access_level: string,
-    forking_access_level: string,
-    wiki_access_level: string,
-    builds_access_level: string,
-    snippets_access_level: string,
-    pages_access_level: string,
-    operations_access_level: string,
-    analytics_access_level: string,
-    container_registry_access_level: string,
-    security_and_compliance_access_level: string,
-    releases_access_level: string,
-    environments_access_level: string,
-    feature_flags_access_level: string,
-    infrastructure_access_level: string,
-    monitor_access_level: string,
-    emails_disabled: boolean,
-    shared_runners_enabled: boolean,
-    lfs_enabled: boolean,
-    creator_id: number,
-    import_url: string,
-    import_type: string,
-    import_status: string,
-    import_error: string,
-    open_issues_count: number,
-    runners_token: string,
-    ci_default_git_depth: number,
-    ci_forward_deployment_enabled: boolean,
-    ci_job_token_scope_enabled: boolean,
-    ci_separated_caches: boolean,
-    ci_opt_in_jwt: boolean,
-    ci_allow_fork_pipelines_to_run_in_parent_project: boolean,
-    public_jobs: boolean,
-    build_git_strategy: string,
-    build_timeout: number,
-    auto_cancel_pending_pipelines: string,
-    ci_config_path: string,
-    shared_with_groups: Array<GitlabGroup>,
-    only_allow_merge_if_pipeline_succeeds: boolean,
-    allow_merge_on_skipped_pipeline: boolean,
-    restrict_user_defined_variables: boolean,
-    request_access_enabled: boolean,
-    only_allow_merge_if_all_discussions_are_resolved: boolean,
-    remove_source_branch_after_merge: boolean,
-    printing_merge_request_link_enabled: boolean,
-    merge_method: string,
-    squash_option: string,
-    enforce_auth_checks_on_uploads: boolean,
-    suggestion_commit_message: string,
-    merge_commit_template: string,
-    squash_commit_template: string,
-    issue_branch_template: string,
-    auto_devops_enabled: boolean,
-    auto_devops_deploy_strategy: string,
-    autoclose_referenced_issues: boolean,
-    keep_latest_artifact: boolean,
-    runner_token_expiration_interval: number,
-}
-
-
-export default GitlabRepository;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabRoute.ts b/types/Gitlab/GitlabRoute.ts
deleted file mode 100644
index bdeccc68f582f5f477bd6fb9d8f3fe665680ca5d..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabRoute.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-enum GitlabRoute {
-    NOTIFICATION_SETTINGS       = '/notification_settings',
-    PROFILE_GET                 = '/user',
-    USERS_GET                   = '/users',
-    REPOSITORY_GET              = '/projects/{{id}}',
-    REPOSITORY_CREATE           = '/projects', // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
-    REPOSITORY_DELETE           = '/projects/{{id}}', // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
-    REPOSITORY_EDIT             = '/projects/{{id}}',
-    REPOSITORY_FORK             = '/projects/{{id}}/fork',
-    REPOSITORY_MEMBER_ADD       = '/projects/{{id}}/members',
-    REPOSITORY_MEMBERS_GET      = '/projects/{{id}}/members/all',
-    REPOSITORY_RELEASES_GET     = '/projects/{{id}}/releases',
-    REPOSITORY_BADGES_ADD       = '/projects/{{id}}/badges',
-    REPOSITORY_VARIABLES_ADD    = '/projects/{{id}}/variables',
-    REPOSITORY_BRANCHES_PROTECT = '/projects/{{id}}/protected_branches',
-    REPOSITORY_TREE             = '/projects/{{id}}/repository/tree',
-    REPOSITORY_FILE             = '/projects/{{id}}/repository/files/{{filePath}}',
-    REPOSITORY_PIPELINES        = '/projects/{{id}}/pipelines',
-}
-
-
-export default GitlabRoute;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabTreeFile.ts b/types/Gitlab/GitlabTreeFile.ts
deleted file mode 100644
index b2cf67ecb1d636838ff2e48cbc6ce62e11248476..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabTreeFile.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import GitlabTreeFileType from './GitlabTreeFileType';
-
-
-interface GitlabTreeFile {
-    id: number,
-    name: string,
-    type: GitlabTreeFileType,
-    path: string,
-    mode: string
-}
-
-
-export default GitlabTreeFile;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabUser.ts b/types/Gitlab/GitlabUser.ts
deleted file mode 100644
index bbb759264764020b1dd80cca050392371b8e87b7..0000000000000000000000000000000000000000
--- a/types/Gitlab/GitlabUser.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-interface GitlabUser {
-    id: number,
-    username: string,
-    name: string,
-    state: string,
-    avatar_url: string,
-    web_url: string,
-}
-
-
-export default GitlabUser;
\ No newline at end of file
diff --git a/types/Gitlab/GitlabVisibility.ts b/types/Gitlab/GitlabVisibility.ts
index 842ff168e274cb6cfb2a39ef7a952cdb5248c1b9..1eaf63640d08ae3c3bac00f74922ce7d0c2fcbbd 100644
--- a/types/Gitlab/GitlabVisibility.ts
+++ b/types/Gitlab/GitlabVisibility.ts
@@ -1,8 +1,4 @@
-enum GitlabVisibility {
-    PUBLIC   = 'public',
-    INTERNAL = 'internal',
-    PRIVATE  = 'private'
-}
+type GitlabVisibility = 'public' | 'internal' | 'private';
 
 
 export default GitlabVisibility;