fix(backend): Formatting + .env.development.example

npm run format uitgevoerd, .env.development.example toegevoegd.
This commit is contained in:
Gerald Schmittinger 2025-02-26 22:03:53 +01:00
parent 4e883a1a18
commit 48c8ce7c57
36 changed files with 499 additions and 331 deletions

View file

@ -0,0 +1,6 @@
PORT=3000
DWENGO_DB_HOST=localhost
DWENGO_DB_PORT=5431
DWENGO_DB_USERNAME=postgres
DWENGO_DB_PASSWORD=postgres
DWENGO_DB_UPDATE=true

View file

@ -1,15 +1,18 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Assignment} from "../../entities/assignments/assignment.entity"; import { Assignment } from '../../entities/assignments/assignment.entity';
import {Class} from "../../entities/classes/class.entity"; import { Class } from '../../entities/classes/class.entity';
export class AssignmentRepository extends DwengoEntityRepository<Assignment> { export class AssignmentRepository extends DwengoEntityRepository<Assignment> {
public findByClassAndId(within: Class, id: number): Promise<Assignment | null> { public findByClassAndId(
return this.findOne({within: within, id: id}); within: Class,
id: number
): Promise<Assignment | null> {
return this.findOne({ within: within, id: id });
} }
public findAllAssignmentsInClass(within: Class): Promise<Assignment[]> { public findAllAssignmentsInClass(within: Class): Promise<Assignment[]> {
return this.findAll({where: {within: within}}); return this.findAll({ where: { within: within } });
} }
public deleteByClassAndId(within: Class, id: number): Promise<void> { public deleteByClassAndId(within: Class, id: number): Promise<void> {
return this.deleteWhere({within: within, id: id}); return this.deleteWhere({ within: within, id: id });
} }
} }

View file

@ -1,15 +1,29 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Group} from "../../entities/assignments/group.entity"; import { Group } from '../../entities/assignments/group.entity';
import {Assignment} from "../../entities/assignments/assignment.entity"; import { Assignment } from '../../entities/assignments/assignment.entity';
export class GroupRepository extends DwengoEntityRepository<Group> { export class GroupRepository extends DwengoEntityRepository<Group> {
public findByAssignmentAndGroupNumber(assignment: Assignment, groupNumber: number): Promise<Group | null> { public findByAssignmentAndGroupNumber(
return this.findOne({assignment: assignment, groupNumber: groupNumber}); assignment: Assignment,
groupNumber: number
): Promise<Group | null> {
return this.findOne({
assignment: assignment,
groupNumber: groupNumber,
});
} }
public findAllGroupsForAssignment(assignment: Assignment): Promise<Group[]> { public findAllGroupsForAssignment(
return this.findAll({where: {assignment: assignment}}); assignment: Assignment
): Promise<Group[]> {
return this.findAll({ where: { assignment: assignment } });
} }
public deleteByAssignmentAndGroupNumber(assignment: Assignment, groupNumber: number) { public deleteByAssignmentAndGroupNumber(
return this.deleteWhere({assignment: assignment, groupNumber: groupNumber}); assignment: Assignment,
groupNumber: number
) {
return this.deleteWhere({
assignment: assignment,
groupNumber: groupNumber,
});
} }
} }

View file

@ -1,43 +1,61 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Group} from "../../entities/assignments/group.entity"; import { Group } from '../../entities/assignments/group.entity';
import {Submission} from "../../entities/assignments/submission.entity"; import { Submission } from '../../entities/assignments/submission.entity';
import {LearningObjectIdentifier} from "../../entities/content/learning-object-identifier"; import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier';
import {Student} from "../../entities/users/student.entity"; import { Student } from '../../entities/users/student.entity';
export class SubmissionRepository extends DwengoEntityRepository<Submission> { export class SubmissionRepository extends DwengoEntityRepository<Submission> {
public findSubmissionByLearningObjectAndSubmissionNumber(loId: LearningObjectIdentifier, submissionNumber: number): Promise<Submission | null> { public findSubmissionByLearningObjectAndSubmissionNumber(
loId: LearningObjectIdentifier,
submissionNumber: number
): Promise<Submission | null> {
return this.findOne({ return this.findOne({
learningObjectHruid: loId.hruid, learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language, learningObjectLanguage: loId.language,
learningObjectVersion: loId.version, learningObjectVersion: loId.version,
submissionNumber: submissionNumber submissionNumber: submissionNumber,
}); });
} }
public findMostRecentSubmissionForStudent(loId: LearningObjectIdentifier, submitter: Student): Promise<Submission | null> { public findMostRecentSubmissionForStudent(
return this.findOne({ loId: LearningObjectIdentifier,
learningObjectHruid: loId.hruid, submitter: Student
learningObjectLanguage: loId.language, ): Promise<Submission | null> {
learningObjectVersion: loId.version, return this.findOne(
submitter: submitter, {
}, {orderBy: {submissionNumber: "DESC"}}) learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language,
learningObjectVersion: loId.version,
submitter: submitter,
},
{ orderBy: { submissionNumber: 'DESC' } }
);
} }
public findMostRecentSubmissionForGroup(loId: LearningObjectIdentifier, group: Group): Promise<Submission | null> { public findMostRecentSubmissionForGroup(
return this.findOne({ loId: LearningObjectIdentifier,
learningObjectHruid: loId.hruid, group: Group
learningObjectLanguage: loId.language, ): Promise<Submission | null> {
learningObjectVersion: loId.version, return this.findOne(
onBehalfOf: group, {
}, {orderBy: {submissionNumber: "DESC"}}) learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language,
learningObjectVersion: loId.version,
onBehalfOf: group,
},
{ orderBy: { submissionNumber: 'DESC' } }
);
} }
public deleteSubmissionByLearningObjectAndSubmissionNumber(loId: LearningObjectIdentifier, submissionNumber: number): Promise<void> { public deleteSubmissionByLearningObjectAndSubmissionNumber(
loId: LearningObjectIdentifier,
submissionNumber: number
): Promise<void> {
return this.deleteWhere({ return this.deleteWhere({
learningObjectHruid: loId.hruid, learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language, learningObjectLanguage: loId.language,
learningObjectVersion: loId.version, learningObjectVersion: loId.version,
submissionNumber: submissionNumber submissionNumber: submissionNumber,
}) });
} }
} }

View file

@ -1,16 +1,16 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Class} from "../../entities/classes/class.entity"; import { Class } from '../../entities/classes/class.entity';
import {ClassJoinRequest} from "../../entities/classes/class-join-request.entity"; import { ClassJoinRequest } from '../../entities/classes/class-join-request.entity';
import {Student} from "../../entities/users/student.entity"; import { Student } from '../../entities/users/student.entity';
export class ClassJoinRequestRepository extends DwengoEntityRepository<ClassJoinRequest> { export class ClassJoinRequestRepository extends DwengoEntityRepository<ClassJoinRequest> {
public findAllRequestsBy(requester: Student): Promise<ClassJoinRequest[]> { public findAllRequestsBy(requester: Student): Promise<ClassJoinRequest[]> {
return this.findAll({where: {requester: requester}}); return this.findAll({ where: { requester: requester } });
} }
public findAllOpenRequestsTo(clazz: Class): Promise<ClassJoinRequest[]> { public findAllOpenRequestsTo(clazz: Class): Promise<ClassJoinRequest[]> {
return this.findAll({where: {class: clazz}}); return this.findAll({ where: { class: clazz } });
} }
public deleteBy(requester: Student, clazz: Class): Promise<void> { public deleteBy(requester: Student, clazz: Class): Promise<void> {
return this.deleteWhere({requester: requester, class: clazz}); return this.deleteWhere({ requester: requester, class: clazz });
} }
} }

View file

@ -1,11 +1,11 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Class} from "../../entities/classes/class.entity"; import { Class } from '../../entities/classes/class.entity';
export class ClassRepository extends DwengoEntityRepository<Class> { export class ClassRepository extends DwengoEntityRepository<Class> {
public findById(id: string): Promise<Class | null> { public findById(id: string): Promise<Class | null> {
return this.findOne({classId: id}); return this.findOne({ classId: id });
} }
public deleteById(id: string): Promise<void> { public deleteById(id: string): Promise<void> {
return this.deleteWhere({classId: id}); return this.deleteWhere({ classId: id });
} }
} }

View file

@ -1,19 +1,31 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Class} from "../../entities/classes/class.entity"; import { Class } from '../../entities/classes/class.entity';
import {TeacherInvitation} from "../../entities/classes/teacher-invitation.entity"; import { TeacherInvitation } from '../../entities/classes/teacher-invitation.entity';
import {Teacher} from "../../entities/users/teacher.entity"; import { Teacher } from '../../entities/users/teacher.entity';
export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherInvitation> { export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherInvitation> {
public findAllInvitationsForClass(clazz: Class): Promise<TeacherInvitation[]> { public findAllInvitationsForClass(
return this.findAll({where: {class: clazz}}) clazz: Class
): Promise<TeacherInvitation[]> {
return this.findAll({ where: { class: clazz } });
} }
public findAllInvitationsBy(sender: Teacher): Promise<TeacherInvitation[]> { public findAllInvitationsBy(sender: Teacher): Promise<TeacherInvitation[]> {
return this.findAll({where: {sender: sender}}) return this.findAll({ where: { sender: sender } });
} }
public findAllInvitationsFor(receiver: Teacher): Promise<TeacherInvitation[]> { public findAllInvitationsFor(
return this.findAll({where: {receiver: receiver}}) receiver: Teacher
): Promise<TeacherInvitation[]> {
return this.findAll({ where: { receiver: receiver } });
} }
public deleteBy(clazz: Class, sender: Teacher, receiver: Teacher): Promise<void> { public deleteBy(
return this.deleteWhere({sender: sender, receiver: receiver, class: clazz}); clazz: Class,
sender: Teacher,
receiver: Teacher
): Promise<void> {
return this.deleteWhere({
sender: sender,
receiver: receiver,
class: clazz,
});
} }
} }

View file

@ -1,10 +1,16 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Attachment} from "../../entities/content/attachment.entity"; import { Attachment } from '../../entities/content/attachment.entity';
import {LearningObject} from "../../entities/content/learning-object.entity"; import { LearningObject } from '../../entities/content/learning-object.entity';
export class AttachmentRepository extends DwengoEntityRepository<Attachment> { export class AttachmentRepository extends DwengoEntityRepository<Attachment> {
public findByLearningObjectAndNumber(learningObject: LearningObject, sequenceNumber: number) { public findByLearningObjectAndNumber(
return this.findOne({learningObject: learningObject, sequenceNumber: sequenceNumber}); learningObject: LearningObject,
sequenceNumber: number
) {
return this.findOne({
learningObject: learningObject,
sequenceNumber: sequenceNumber,
});
} }
// This repository is read-only for now since creating own learning object is an extension feature. // This repository is read-only for now since creating own learning object is an extension feature.
} }

View file

@ -1,13 +1,15 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {LearningObject} from "../../entities/content/learning-object.entity"; import { LearningObject } from '../../entities/content/learning-object.entity';
import {LearningObjectIdentifier} from "../../entities/content/learning-object-identifier"; import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier';
export class LearningObjectRepository extends DwengoEntityRepository<LearningObject> { export class LearningObjectRepository extends DwengoEntityRepository<LearningObject> {
public findByIdentifier(identifier: LearningObjectIdentifier): Promise<LearningObject | null> { public findByIdentifier(
identifier: LearningObjectIdentifier
): Promise<LearningObject | null> {
return this.findOne({ return this.findOne({
hruid: identifier.hruid, hruid: identifier.hruid,
language: identifier.language, language: identifier.language,
version: identifier.version version: identifier.version,
}); });
} }
// This repository is read-only for now since creating own learning object is an extension feature. // This repository is read-only for now since creating own learning object is an extension feature.

View file

@ -1,10 +1,13 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {LearningPath} from "../../entities/content/learning-path.entity"; import { LearningPath } from '../../entities/content/learning-path.entity';
import {Language} from "../../entities/content/language"; import { Language } from '../../entities/content/language';
export class LearningPathRepository extends DwengoEntityRepository<LearningPath> { export class LearningPathRepository extends DwengoEntityRepository<LearningPath> {
public findByHruidAndLanguage(hruid: string, language: Language): Promise<LearningPath | null> { public findByHruidAndLanguage(
return this.findOne({hruid: hruid, language: language}); hruid: string,
language: Language
): Promise<LearningPath | null> {
return this.findOne({ hruid: hruid, language: language });
} }
// This repository is read-only for now since creating own learning object is an extension feature. // This repository is read-only for now since creating own learning object is an extension feature.
} }

View file

@ -1,6 +1,8 @@
import {EntityRepository, FilterQuery} from "@mikro-orm/core"; import { EntityRepository, FilterQuery } from '@mikro-orm/core';
export abstract class DwengoEntityRepository<T extends object> extends EntityRepository<T> { export abstract class DwengoEntityRepository<
T extends object,
> extends EntityRepository<T> {
public async save(entity: T) { public async save(entity: T) {
let em = this.getEntityManager(); let em = this.getEntityManager();
em.persist(entity); em.persist(entity);

View file

@ -1,10 +1,14 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Answer} from "../../entities/questions/answer.entity"; import { Answer } from '../../entities/questions/answer.entity';
import {Question} from "../../entities/questions/question.entity"; import { Question } from '../../entities/questions/question.entity';
import {Teacher} from "../../entities/users/teacher.entity"; import { Teacher } from '../../entities/users/teacher.entity';
export class AnswerRepository extends DwengoEntityRepository<Answer> { export class AnswerRepository extends DwengoEntityRepository<Answer> {
public createAnswer(answer: {toQuestion: Question, author: Teacher, content: string}): Promise<Answer> { public createAnswer(answer: {
toQuestion: Question;
author: Teacher;
content: string;
}): Promise<Answer> {
let answerEntity = new Answer(); let answerEntity = new Answer();
answerEntity.toQuestion = answer.toQuestion; answerEntity.toQuestion = answer.toQuestion;
answerEntity.author = answer.author; answerEntity.author = answer.author;
@ -14,13 +18,16 @@ export class AnswerRepository extends DwengoEntityRepository<Answer> {
public findAllAnswersToQuestion(question: Question): Promise<Answer[]> { public findAllAnswersToQuestion(question: Question): Promise<Answer[]> {
return this.findAll({ return this.findAll({
where: { toQuestion: question }, where: { toQuestion: question },
orderBy: { sequenceNumber: "ASC" } orderBy: { sequenceNumber: 'ASC' },
}); });
} }
public removeAnswerByQuestionAndSequenceNumber(question: Question, sequenceNumber: number): Promise<void> { public removeAnswerByQuestionAndSequenceNumber(
question: Question,
sequenceNumber: number
): Promise<void> {
return this.deleteWhere({ return this.deleteWhere({
toQuestion: question, toQuestion: question,
sequenceNumber: sequenceNumber sequenceNumber: sequenceNumber,
}); });
} }
} }

View file

@ -1,10 +1,14 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Question} from "../../entities/questions/question.entity"; import { Question } from '../../entities/questions/question.entity';
import {LearningObjectIdentifier} from "../../entities/content/learning-object-identifier"; import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier';
import {Student} from "../../entities/users/student.entity"; import { Student } from '../../entities/users/student.entity';
export class QuestionRepository extends DwengoEntityRepository<Question> { export class QuestionRepository extends DwengoEntityRepository<Question> {
public createQuestion(question: {loId: LearningObjectIdentifier, author: Student, content: string}): Promise<Question> { public createQuestion(question: {
loId: LearningObjectIdentifier;
author: Student;
content: string;
}): Promise<Question> {
let questionEntity = new Question(); let questionEntity = new Question();
questionEntity.learningObjectHruid = question.loId.hruid; questionEntity.learningObjectHruid = question.loId.hruid;
questionEntity.learningObjectLanguage = question.loId.language; questionEntity.learningObjectLanguage = question.loId.language;
@ -13,24 +17,29 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
questionEntity.content = question.content; questionEntity.content = question.content;
return this.insert(questionEntity); return this.insert(questionEntity);
} }
public findAllQuestionsAboutLearningObject(loId: LearningObjectIdentifier): Promise<Question[]> { public findAllQuestionsAboutLearningObject(
loId: LearningObjectIdentifier
): Promise<Question[]> {
return this.findAll({ return this.findAll({
where: { where: {
learningObjectHruid: loId.hruid, learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language, learningObjectLanguage: loId.language,
learningObjectVersion: loId.version learningObjectVersion: loId.version,
}, },
orderBy: { orderBy: {
sequenceNumber: "ASC" sequenceNumber: 'ASC',
} },
}); });
} }
public removeQuestionByLearningObjectAndSequenceNumber(loId: LearningObjectIdentifier, sequenceNumber: number): Promise<void> { public removeQuestionByLearningObjectAndSequenceNumber(
loId: LearningObjectIdentifier,
sequenceNumber: number
): Promise<void> {
return this.deleteWhere({ return this.deleteWhere({
learningObjectHruid: loId.hruid, learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language, learningObjectLanguage: loId.language,
learningObjectVersion: loId.version, learningObjectVersion: loId.version,
sequenceNumber: sequenceNumber sequenceNumber: sequenceNumber,
}) });
} }
} }

View file

@ -1,33 +1,38 @@
import {AnyEntity, EntityManager, EntityName, EntityRepository} from "@mikro-orm/core"; import {
import {forkEntityManager} from "../orm"; AnyEntity,
import {StudentRepository} from "./users/student-repository"; EntityManager,
import {Student} from "../entities/users/student.entity"; EntityName,
import {User} from "../entities/users/user.entity"; EntityRepository,
import {UserRepository} from "./users/user-repository"; } from '@mikro-orm/core';
import {Teacher} from "../entities/users/teacher.entity"; import { forkEntityManager } from '../orm';
import {TeacherRepository} from "./users/teacher-repository"; import { StudentRepository } from './users/student-repository';
import {Class} from "../entities/classes/class.entity"; import { Student } from '../entities/users/student.entity';
import {ClassRepository} from "./classes/class-repository"; import { User } from '../entities/users/user.entity';
import {ClassJoinRequest} from "../entities/classes/class-join-request.entity"; import { UserRepository } from './users/user-repository';
import {ClassJoinRequestRepository} from "./classes/class-join-request-repository"; import { Teacher } from '../entities/users/teacher.entity';
import {TeacherInvitationRepository} from "./classes/teacher-invitation-repository"; import { TeacherRepository } from './users/teacher-repository';
import {TeacherInvitation} from "../entities/classes/teacher-invitation.entity"; import { Class } from '../entities/classes/class.entity';
import {Assignment} from "../entities/assignments/assignment.entity"; import { ClassRepository } from './classes/class-repository';
import {AssignmentRepository} from "./assignments/assignment-repository"; import { ClassJoinRequest } from '../entities/classes/class-join-request.entity';
import {GroupRepository} from "./assignments/group-repository"; import { ClassJoinRequestRepository } from './classes/class-join-request-repository';
import {Group} from "../entities/assignments/group.entity"; import { TeacherInvitationRepository } from './classes/teacher-invitation-repository';
import {Submission} from "../entities/assignments/submission.entity"; import { TeacherInvitation } from '../entities/classes/teacher-invitation.entity';
import {SubmissionRepository} from "./assignments/submission-repository"; import { Assignment } from '../entities/assignments/assignment.entity';
import {Question} from "../entities/questions/question.entity"; import { AssignmentRepository } from './assignments/assignment-repository';
import {QuestionRepository} from "./questions/question-repository"; import { GroupRepository } from './assignments/group-repository';
import {Answer} from "../entities/questions/answer.entity"; import { Group } from '../entities/assignments/group.entity';
import {AnswerRepository} from "./questions/answer-repository"; import { Submission } from '../entities/assignments/submission.entity';
import {LearningObject} from "../entities/content/learning-object.entity"; import { SubmissionRepository } from './assignments/submission-repository';
import {LearningObjectRepository} from "./content/learning-object-repository"; import { Question } from '../entities/questions/question.entity';
import {LearningPath} from "../entities/content/learning-path.entity"; import { QuestionRepository } from './questions/question-repository';
import {LearningPathRepository} from "./content/learning-path-repository"; import { Answer } from '../entities/questions/answer.entity';
import {AttachmentRepository} from "./content/attachment-repository"; import { AnswerRepository } from './questions/answer-repository';
import {Attachment} from "../entities/content/attachment.entity"; import { LearningObject } from '../entities/content/learning-object.entity';
import { LearningObjectRepository } from './content/learning-object-repository';
import { LearningPath } from '../entities/content/learning-path.entity';
import { LearningPathRepository } from './content/learning-path-repository';
import { AttachmentRepository } from './content/attachment-repository';
import { Attachment } from '../entities/content/attachment.entity';
let entityManager: EntityManager | undefined; let entityManager: EntityManager | undefined;
@ -38,7 +43,9 @@ export function transactional<T>(f: () => Promise<T>) {
entityManager?.transactional(f); entityManager?.transactional(f);
} }
function repositoryGetter<T extends AnyEntity, R extends EntityRepository<T>>(entity: EntityName<T>): () => R { function repositoryGetter<T extends AnyEntity, R extends EntityRepository<T>>(
entity: EntityName<T>
): () => R {
let cachedRepo: R | undefined; let cachedRepo: R | undefined;
return (): R => { return (): R => {
if (!cachedRepo) { if (!cachedRepo) {
@ -48,29 +55,65 @@ function repositoryGetter<T extends AnyEntity, R extends EntityRepository<T>>(en
cachedRepo = entityManager.getRepository(entity) as R; cachedRepo = entityManager.getRepository(entity) as R;
} }
return cachedRepo; return cachedRepo;
} };
} }
/* Users */ /* Users */
export const getUserRepository = repositoryGetter<User, UserRepository>(User) export const getUserRepository = repositoryGetter<User, UserRepository>(User);
export const getStudentRepository = repositoryGetter<Student, StudentRepository>(Student); export const getStudentRepository = repositoryGetter<
export const getTeacherRepository = repositoryGetter<Teacher, TeacherRepository>(Teacher); Student,
StudentRepository
>(Student);
export const getTeacherRepository = repositoryGetter<
Teacher,
TeacherRepository
>(Teacher);
/* Classes */ /* Classes */
export const getClassRepository = repositoryGetter<Class, ClassRepository>(Class); export const getClassRepository = repositoryGetter<Class, ClassRepository>(
export const getClassJoinRequestRepository = repositoryGetter<ClassJoinRequest, ClassJoinRequestRepository>(ClassJoinRequest); Class
export const getTeacherInvitationRepository = repositoryGetter<TeacherInvitation, TeacherInvitationRepository>(TeacherInvitationRepository); );
export const getClassJoinRequestRepository = repositoryGetter<
ClassJoinRequest,
ClassJoinRequestRepository
>(ClassJoinRequest);
export const getTeacherInvitationRepository = repositoryGetter<
TeacherInvitation,
TeacherInvitationRepository
>(TeacherInvitationRepository);
/* Assignments */ /* Assignments */
export const getAssignmentRepository = repositoryGetter<Assignment, AssignmentRepository>(Assignment); export const getAssignmentRepository = repositoryGetter<
export const getGroupRepository = repositoryGetter<Group, GroupRepository>(Group); Assignment,
export const getSubmissionRepository = repositoryGetter<Submission, SubmissionRepository>(Submission); AssignmentRepository
>(Assignment);
export const getGroupRepository = repositoryGetter<Group, GroupRepository>(
Group
);
export const getSubmissionRepository = repositoryGetter<
Submission,
SubmissionRepository
>(Submission);
/* Questions and answers */ /* Questions and answers */
export const getQuestionRepository = repositoryGetter<Question, QuestionRepository>(Question); export const getQuestionRepository = repositoryGetter<
export const getAnswerRepository = repositoryGetter<Answer, AnswerRepository>(Answer); Question,
QuestionRepository
>(Question);
export const getAnswerRepository = repositoryGetter<Answer, AnswerRepository>(
Answer
);
/* Learning content */ /* Learning content */
export const getLearningObjectRepository = repositoryGetter<LearningObject, LearningObjectRepository>(LearningObject); export const getLearningObjectRepository = repositoryGetter<
export const getLearningPathRepository = repositoryGetter<LearningPath, LearningPathRepository>(LearningPath); LearningObject,
export const getAttachmentRepository = repositoryGetter<Attachment, AttachmentRepository>(Assignment); LearningObjectRepository
>(LearningObject);
export const getLearningPathRepository = repositoryGetter<
LearningPath,
LearningPathRepository
>(LearningPath);
export const getAttachmentRepository = repositoryGetter<
Attachment,
AttachmentRepository
>(Assignment);

View file

@ -1,11 +1,11 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Student} from "../../entities/users/student.entity"; import { Student } from '../../entities/users/student.entity';
export class StudentRepository extends DwengoEntityRepository<Student> { export class StudentRepository extends DwengoEntityRepository<Student> {
public findByUsername(username: string): Promise<Student | null> { public findByUsername(username: string): Promise<Student | null> {
return this.findOne({username: username}); return this.findOne({ username: username });
} }
public deleteByUsername(username: string): Promise<void> { public deleteByUsername(username: string): Promise<void> {
return this.deleteWhere({username: username}); return this.deleteWhere({ username: username });
} }
} }

View file

@ -1,11 +1,11 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {Teacher} from "../../entities/users/teacher.entity"; import { Teacher } from '../../entities/users/teacher.entity';
export class TeacherRepository extends DwengoEntityRepository<Teacher> { export class TeacherRepository extends DwengoEntityRepository<Teacher> {
public findByUsername(username: string): Promise<Teacher | null> { public findByUsername(username: string): Promise<Teacher | null> {
return this.findOne({username: username}); return this.findOne({ username: username });
} }
public deleteByUsername(username: string): Promise<void> { public deleteByUsername(username: string): Promise<void> {
return this.deleteWhere({username: username}); return this.deleteWhere({ username: username });
} }
} }

View file

@ -1,11 +1,11 @@
import {DwengoEntityRepository} from "../dwengo-entity-repository"; import { DwengoEntityRepository } from '../dwengo-entity-repository';
import {User} from "../../entities/users/user.entity"; import { User } from '../../entities/users/user.entity';
export class UserRepository extends DwengoEntityRepository<User> { export class UserRepository extends DwengoEntityRepository<User> {
public findByUsername(username: string): Promise<User | null> { public findByUsername(username: string): Promise<User | null> {
return this.findOne({username: username}); return this.findOne({ username: username });
} }
public deleteByUsername(username: string): Promise<void> { public deleteByUsername(username: string): Promise<void> {
return this.deleteWhere({username: username}); return this.deleteWhere({ username: username });
} }
} }

View file

@ -1,28 +1,35 @@
import {Entity, Enum, ManyToOne, OneToMany, PrimaryKey, Property} from "@mikro-orm/core"; import {
import {Class} from "../classes/class.entity"; Entity,
import {Group} from "./group.entity" Enum,
import {Language} from "../content/language"; ManyToOne,
OneToMany,
PrimaryKey,
Property,
} from '@mikro-orm/core';
import { Class } from '../classes/class.entity';
import { Group } from './group.entity';
import { Language } from '../content/language';
@Entity() @Entity()
export class Assignment { export class Assignment {
@ManyToOne({entity: () => Class, primary: true}) @ManyToOne({ entity: () => Class, primary: true })
within!: Class; within!: Class;
@PrimaryKey({type: "number"}) @PrimaryKey({ type: 'number' })
id!: number; id!: number;
@Property({type: "string"}) @Property({ type: 'string' })
title!: string; title!: string;
@Property({type: "text"}) @Property({ type: 'text' })
description!: string; description!: string;
@Property({type: "string"}) @Property({ type: 'string' })
learningPathHruid!: string; learningPathHruid!: string;
@Enum({items: () => Language}) @Enum({ items: () => Language })
learningPathLanguage!: Language; learningPathLanguage!: Language;
@OneToMany({entity: () => Group, mappedBy: "assignment"}) @OneToMany({ entity: () => Group, mappedBy: 'assignment' })
groups!: Group[]; groups!: Group[];
} }

View file

@ -1,15 +1,15 @@
import {Entity, ManyToMany, ManyToOne, PrimaryKey} from "@mikro-orm/core"; import { Entity, ManyToMany, ManyToOne, PrimaryKey } from '@mikro-orm/core';
import {Assignment} from "./assignment.entity"; import { Assignment } from './assignment.entity';
import {Student} from "../users/student.entity"; import { Student } from '../users/student.entity';
@Entity() @Entity()
export class Group { export class Group {
@ManyToOne({entity: () => Assignment, primary: true}) @ManyToOne({ entity: () => Assignment, primary: true })
assignment!: Assignment; assignment!: Assignment;
@PrimaryKey({type: "integer"}) @PrimaryKey({ type: 'integer' })
groupNumber!: number; groupNumber!: number;
@ManyToMany({entity: () => Student}) @ManyToMany({ entity: () => Student })
members!: Student[]; members!: Student[];
} }

View file

@ -1,31 +1,31 @@
import {Student} from "../users/student.entity"; import { Student } from '../users/student.entity';
import {Group} from "./group.entity"; import { Group } from './group.entity';
import {Entity, Enum, ManyToOne, PrimaryKey, Property} from "@mikro-orm/core"; import { Entity, Enum, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import {Language} from "../content/language"; import { Language } from '../content/language';
@Entity() @Entity()
export class Submission { export class Submission {
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
learningObjectHruid!: string; learningObjectHruid!: string;
@Enum({items: () => Language, primary: true}) @Enum({ items: () => Language, primary: true })
learningObjectLanguage!: Language; learningObjectLanguage!: Language;
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
learningObjectVersion: string = "1"; learningObjectVersion: string = '1';
@PrimaryKey({type: "integer"}) @PrimaryKey({ type: 'integer' })
submissionNumber!: number; submissionNumber!: number;
@ManyToOne({entity: () => Student}) @ManyToOne({ entity: () => Student })
submitter!: Student; submitter!: Student;
@Property({type: "datetime"}) @Property({ type: 'datetime' })
submissionTime!: Date; submissionTime!: Date;
@ManyToOne({entity: () => Group, nullable: true}) @ManyToOne({ entity: () => Group, nullable: true })
onBehalfOf?: Group; onBehalfOf?: Group;
@Property({type: "json"}) @Property({ type: 'json' })
content!: string; content!: string;
} }

View file

@ -1,13 +1,13 @@
import {Entity, Enum, ManyToOne} from "@mikro-orm/core"; import { Entity, Enum, ManyToOne } from '@mikro-orm/core';
import {Student} from "../users/student.entity"; import { Student } from '../users/student.entity';
import {Class} from "./class.entity"; import { Class } from './class.entity';
@Entity() @Entity()
export class ClassJoinRequest { export class ClassJoinRequest {
@ManyToOne({entity: () => Student, primary: true}) @ManyToOne({ entity: () => Student, primary: true })
requester!: Student; requester!: Student;
@ManyToOne({entity: () => Class, primary: true}) @ManyToOne({ entity: () => Class, primary: true })
class!: Class; class!: Class;
@Enum(() => ClassJoinRequestStatus) @Enum(() => ClassJoinRequestStatus)
@ -15,7 +15,7 @@ export class ClassJoinRequest {
} }
export enum ClassJoinRequestStatus { export enum ClassJoinRequestStatus {
Open = "open", Open = 'open',
Accepted = "accepted", Accepted = 'accepted',
Declined = "declined" Declined = 'declined',
} }

View file

@ -1,14 +1,20 @@
import {Collection, Entity, ManyToMany, PrimaryKey, Property} from "@mikro-orm/core"; import {
Collection,
Entity,
ManyToMany,
PrimaryKey,
Property,
} from '@mikro-orm/core';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import {Teacher} from "../users/teacher.entity"; import { Teacher } from '../users/teacher.entity';
import {Student} from "../users/student.entity"; import { Student } from '../users/student.entity';
@Entity() @Entity()
export class Class { export class Class {
@PrimaryKey() @PrimaryKey()
classId = v4(); classId = v4();
@Property({type: "string"}) @Property({ type: 'string' })
displayName!: string; displayName!: string;
@ManyToMany(() => Teacher) @ManyToMany(() => Teacher)

View file

@ -1,18 +1,18 @@
import {Entity, ManyToOne} from "@mikro-orm/core"; import { Entity, ManyToOne } from '@mikro-orm/core';
import {Teacher} from "../users/teacher.entity"; import { Teacher } from '../users/teacher.entity';
import {Class} from "./class.entity"; import { Class } from './class.entity';
/** /**
* Invitation of a teacher into a class (in order to teach it). * Invitation of a teacher into a class (in order to teach it).
*/ */
@Entity() @Entity()
export class TeacherInvitation { export class TeacherInvitation {
@ManyToOne({entity: () => Teacher, primary: true}) @ManyToOne({ entity: () => Teacher, primary: true })
sender!: Teacher; sender!: Teacher;
@ManyToOne({entity: () => Teacher, primary: true}) @ManyToOne({ entity: () => Teacher, primary: true })
receiver!: Teacher; receiver!: Teacher;
@ManyToOne({entity: () => Class, primary: true}) @ManyToOne({ entity: () => Class, primary: true })
class!: Class; class!: Class;
} }

View file

@ -1,17 +1,17 @@
import {Entity, ManyToOne, PrimaryKey, Property} from "@mikro-orm/core"; import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import {LearningObject} from "./learning-object.entity"; import { LearningObject } from './learning-object.entity';
@Entity() @Entity()
export class Attachment { export class Attachment {
@ManyToOne({entity: () => LearningObject, primary: true}) @ManyToOne({ entity: () => LearningObject, primary: true })
learningObject!: LearningObject; learningObject!: LearningObject;
@PrimaryKey({type: "integer"}) @PrimaryKey({ type: 'integer' })
sequenceNumber!: number; sequenceNumber!: number;
@Property({type: "string"}) @Property({ type: 'string' })
mimeType!: string; mimeType!: string;
@Property({type: "blob"}) @Property({ type: 'blob' })
content!: Buffer; content!: Buffer;
} }

View file

@ -1,6 +1,6 @@
export enum Language { export enum Language {
Dutch = "nl", Dutch = 'nl',
French = "fr", French = 'fr',
English = "en", English = 'en',
Germany = "de" Germany = 'de',
} }

View file

@ -1,7 +1,9 @@
import {Language} from "./language"; import { Language } from './language';
export class LearningObjectIdentifier { export class LearningObjectIdentifier {
constructor(public hruid: string, public language: Language, public version: string) { constructor(
public hruid: string,
} public language: Language,
public version: string
) {}
} }

View file

@ -1,97 +1,106 @@
import {Embeddable, Embedded, Entity, Enum, ManyToMany, OneToMany, PrimaryKey, Property} from "@mikro-orm/core"; import {
import {Language} from "./language"; Embeddable,
import {Attachment} from "./attachment.entity"; Embedded,
import {Teacher} from "../users/teacher.entity"; Entity,
Enum,
ManyToMany,
OneToMany,
PrimaryKey,
Property,
} from '@mikro-orm/core';
import { Language } from './language';
import { Attachment } from './attachment.entity';
import { Teacher } from '../users/teacher.entity';
@Entity() @Entity()
export class LearningObject { export class LearningObject {
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
hruid!: string; hruid!: string;
@Enum({items: () => Language, primary: true}) @Enum({ items: () => Language, primary: true })
language!: Language; language!: Language;
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
version: string = "1"; version: string = '1';
@ManyToMany({entity: () => Teacher}) @ManyToMany({ entity: () => Teacher })
admins!: Teacher[]; admins!: Teacher[];
@Property({type: "string"}) @Property({ type: 'string' })
title!: string; title!: string;
@Property({type: "text"}) @Property({ type: 'text' })
description!: string; description!: string;
@Property({type: "string"}) @Property({ type: 'string' })
contentType!: string; contentType!: string;
@Property({type: "array"}) @Property({ type: 'array' })
keywords: string[] = []; keywords: string[] = [];
@Property({type: "array", nullable: true}) @Property({ type: 'array', nullable: true })
targetAges?: number[]; targetAges?: number[];
@Property({type: "bool"}) @Property({ type: 'bool' })
teacherExclusive: boolean = false; teacherExclusive: boolean = false;
@Property({type: "array"}) @Property({ type: 'array' })
skosConcepts!: string[]; skosConcepts!: string[];
@Embedded({entity: () => EducationalGoal, array: true}) @Embedded({ entity: () => EducationalGoal, array: true })
educationalGoals: EducationalGoal[] = []; educationalGoals: EducationalGoal[] = [];
@Property({type: "string"}) @Property({ type: 'string' })
copyright: string = "" copyright: string = '';
@Property({type: "string"}) @Property({ type: 'string' })
license: string = "" license: string = '';
@Property({type: "smallint", nullable: true}) @Property({ type: 'smallint', nullable: true })
difficulty?: number; difficulty?: number;
@Property({type: "integer"}) @Property({ type: 'integer' })
estimatedTime!: number; estimatedTime!: number;
@Embedded({entity: () => ReturnValue}) @Embedded({ entity: () => ReturnValue })
returnValue!: ReturnValue; returnValue!: ReturnValue;
@Property({type: "bool"}) @Property({ type: 'bool' })
available: boolean = true; available: boolean = true;
@Property({type: "string", nullable: true}) @Property({ type: 'string', nullable: true })
contentLocation?: string; contentLocation?: string;
@OneToMany({entity: () => Attachment, mappedBy: "learningObject"}) @OneToMany({ entity: () => Attachment, mappedBy: 'learningObject' })
attachments: Attachment[] = []; attachments: Attachment[] = [];
@Property({type: "blob"}) @Property({ type: 'blob' })
content!: Buffer; content!: Buffer;
} }
@Embeddable() @Embeddable()
export class EducationalGoal { export class EducationalGoal {
@Property({type: "string"}) @Property({ type: 'string' })
source!: string; source!: string;
@Property({type: "string"}) @Property({ type: 'string' })
id!: string; id!: string;
} }
@Embeddable() @Embeddable()
export class ReturnValue { export class ReturnValue {
@Property({type: "string"}) @Property({ type: 'string' })
callbackUrl!: string; callbackUrl!: string;
@Property({type: "json"}) @Property({ type: 'json' })
callbackSchema!: string; callbackSchema!: string;
} }
export enum ContentType { export enum ContentType {
Markdown = "text/markdown", Markdown = 'text/markdown',
Image = "image/image", Image = 'image/image',
Mpeg = "audio/mpeg", Mpeg = 'audio/mpeg',
Pdf = "application/pdf", Pdf = 'application/pdf',
Extern = "extern", Extern = 'extern',
Blockly = "Blockly" Blockly = 'Blockly',
} }

View file

@ -1,57 +1,66 @@
import {Embeddable, Embedded, Entity, Enum, ManyToMany, OneToOne, PrimaryKey, Property} from "@mikro-orm/core"; import {
import {Language} from "./language"; Embeddable,
import {Teacher} from "../users/teacher.entity"; Embedded,
Entity,
Enum,
ManyToMany,
OneToOne,
PrimaryKey,
Property,
} from '@mikro-orm/core';
import { Language } from './language';
import { Teacher } from '../users/teacher.entity';
@Entity() @Entity()
export class LearningPath { export class LearningPath {
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
hruid!: string; hruid!: string;
@Enum({items: () => Language, primary: true}) @Enum({ items: () => Language, primary: true })
language!: Language; language!: Language;
@ManyToMany({entity: () => Teacher}) @ManyToMany({ entity: () => Teacher })
admins!: Teacher[]; admins!: Teacher[];
@Property({type: "string"}) @Property({ type: 'string' })
title!: string; title!: string;
@Property({type: "text"}) @Property({ type: 'text' })
description!: string; description!: string;
@Property({type: "blob"}) @Property({ type: 'blob' })
image!: string; image!: string;
@Embedded({entity: () => LearningPathNode, array: true}) @Embedded({ entity: () => LearningPathNode, array: true })
nodes: LearningPathNode[] = []; nodes: LearningPathNode[] = [];
} }
@Embeddable() @Embeddable()
export class LearningPathNode { export class LearningPathNode {
@Property({type: "string"}) @Property({ type: 'string' })
learningObjectHruid!: string; learningObjectHruid!: string;
@Enum({items: () => Language}) @Enum({ items: () => Language })
language!: Language; language!: Language;
@Property({type: "string"}) @Property({ type: 'string' })
version!: string; version!: string;
@Property({type: "longtext"}) @Property({ type: 'longtext' })
instruction!: string; instruction!: string;
@Property({type: "bool"}) @Property({ type: 'bool' })
startNode!: boolean; startNode!: boolean;
@Embedded({entity: () => LearningPathTransition, array: true}) @Embedded({ entity: () => LearningPathTransition, array: true })
transitions!: LearningPathTransition[]; transitions!: LearningPathTransition[];
} }
@Embeddable() @Embeddable()
export class LearningPathTransition { export class LearningPathTransition {
@Property({type: "string"}) @Property({ type: 'string' })
condition!: string; condition!: string;
@OneToOne({entity: () => LearningPathNode}) @OneToOne({ entity: () => LearningPathNode })
next!: LearningPathNode; next!: LearningPathNode;
} }

View file

@ -1,22 +1,21 @@
import {Entity, ManyToOne, PrimaryKey, Property} from "@mikro-orm/core"; import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import {Question} from "./question.entity"; import { Question } from './question.entity';
import {Teacher} from "../users/teacher.entity"; import { Teacher } from '../users/teacher.entity';
@Entity() @Entity()
export class Answer { export class Answer {
@ManyToOne({ entity: () => Teacher, primary: true })
@ManyToOne({entity: () => Teacher, primary: true})
author!: Teacher; author!: Teacher;
@ManyToOne({entity: () => Question, primary: true}) @ManyToOne({ entity: () => Question, primary: true })
toQuestion!: Question; toQuestion!: Question;
@PrimaryKey({type: "integer"}) @PrimaryKey({ type: 'integer' })
sequenceNumber!: number; sequenceNumber!: number;
@Property({type: "datetime"}) @Property({ type: 'datetime' })
timestamp: Date = new Date(); timestamp: Date = new Date();
@Property({type: "text"}) @Property({ type: 'text' })
content!: string; content!: string;
} }

View file

@ -1,27 +1,27 @@
import {Entity, Enum, ManyToOne, PrimaryKey, Property} from "@mikro-orm/core"; import { Entity, Enum, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import {Language} from "../content/language"; import { Language } from '../content/language';
import {Student} from "../users/student.entity"; import { Student } from '../users/student.entity';
@Entity() @Entity()
export class Question { export class Question {
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
learningObjectHruid!: string; learningObjectHruid!: string;
@Enum({items: () => Language, primary: true}) @Enum({ items: () => Language, primary: true })
learningObjectLanguage!: Language; learningObjectLanguage!: Language;
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
learningObjectVersion: string = "1"; learningObjectVersion: string = '1';
@PrimaryKey({type: "integer"}) @PrimaryKey({ type: 'integer' })
sequenceNumber!: number; sequenceNumber!: number;
@ManyToOne({entity: () => Student}) @ManyToOne({ entity: () => Student })
author!: Student; author!: Student;
@Property({type: "datetime"}) @Property({ type: 'datetime' })
timestamp: Date = new Date(); timestamp: Date = new Date();
@Property({type: "text"}) @Property({ type: 'text' })
content!: string; content!: string;
} }

View file

@ -1,10 +1,10 @@
import {User} from "./user.entity"; import { User } from './user.entity';
import {Collection, Entity, ManyToMany} from '@mikro-orm/core'; import { Collection, Entity, ManyToMany } from '@mikro-orm/core';
import {Class} from "../classes/class.entity"; import { Class } from '../classes/class.entity';
import {Group} from "../assignments/group.entity"; import { Group } from '../assignments/group.entity';
import {StudentRepository} from "../../data/users/student-repository"; import { StudentRepository } from '../../data/users/student-repository';
@Entity({repository: () => StudentRepository}) @Entity({ repository: () => StudentRepository })
export class Student extends User { export class Student extends User {
@ManyToMany(() => Class) @ManyToMany(() => Class)
classes!: Collection<Class>; classes!: Collection<Class>;
@ -12,7 +12,11 @@ export class Student extends User {
@ManyToMany(() => Group) @ManyToMany(() => Group)
groups!: Collection<Group>; groups!: Collection<Group>;
constructor(public username: string, public firstName: string, public lastName: string) { constructor(
public username: string,
public firstName: string,
public lastName: string
) {
super(); super();
} }
} }

View file

@ -1,6 +1,6 @@
import {Collection, Entity, ManyToMany} from '@mikro-orm/core'; import { Collection, Entity, ManyToMany } from '@mikro-orm/core';
import {User} from "./user.entity"; import { User } from './user.entity';
import {Class} from "../classes/class.entity"; import { Class } from '../classes/class.entity';
@Entity() @Entity()
export class Teacher extends User { export class Teacher extends User {

View file

@ -1,8 +1,8 @@
import { Entity, PrimaryKey, Property } from '@mikro-orm/core'; import { Entity, PrimaryKey, Property } from '@mikro-orm/core';
@Entity({abstract: true}) @Entity({ abstract: true })
export abstract class User { export abstract class User {
@PrimaryKey({type: "string"}) @PrimaryKey({ type: 'string' })
username!: string; username!: string;
@Property() @Property()

View file

@ -1,7 +1,7 @@
import {Options} from '@mikro-orm/core'; import { Options } from '@mikro-orm/core';
import {PostgreSqlDriver} from "@mikro-orm/postgresql"; import { PostgreSqlDriver } from '@mikro-orm/postgresql';
import {EnvVars, getEnvVar, getNumericEnvVar} from "./util/envvars"; import { EnvVars, getEnvVar, getNumericEnvVar } from './util/envvars';
import {SqliteDriver} from "@mikro-orm/sqlite"; import { SqliteDriver } from '@mikro-orm/sqlite';
const entities = ['dist/**/*.entity.js']; const entities = ['dist/**/*.entity.js'];
const entitiesTs = ['src/**/*.entity.ts']; const entitiesTs = ['src/**/*.entity.ts'];
@ -15,7 +15,7 @@ function config(testingMode: boolean = false): Options {
// Workaround: vitest: `TypeError: Unknown file extension ".ts"` (ERR_UNKNOWN_FILE_EXTENSION) // Workaround: vitest: `TypeError: Unknown file extension ".ts"` (ERR_UNKNOWN_FILE_EXTENSION)
// (see https://mikro-orm.io/docs/guide/project-setup#testing-the-endpoint) // (see https://mikro-orm.io/docs/guide/project-setup#testing-the-endpoint)
dynamicImportProvider: id => import(id) dynamicImportProvider: (id) => import(id),
}; };
} else { } else {
return { return {
@ -27,7 +27,7 @@ function config(testingMode: boolean = false): Options {
password: getEnvVar(EnvVars.DbPassword), password: getEnvVar(EnvVars.DbPassword),
entities: entities, entities: entities,
entitiesTs: entitiesTs, entitiesTs: entitiesTs,
debug: true debug: true,
}; };
} }
} }

View file

@ -1,6 +1,6 @@
import { EntityManager, MikroORM} from '@mikro-orm/core'; import { EntityManager, MikroORM } from '@mikro-orm/core';
import config from './mikro-orm.config.js'; import config from './mikro-orm.config.js';
import {EnvVars, getEnvVar} from "./util/envvars"; import { EnvVars, getEnvVar } from './util/envvars';
let orm: MikroORM | undefined; let orm: MikroORM | undefined;
export async function initORM(testingMode: boolean = false) { export async function initORM(testingMode: boolean = false) {
@ -11,15 +11,20 @@ export async function initORM(testingMode: boolean = false) {
} else { } else {
const diff = await orm.schema.getUpdateSchemaSQL(); const diff = await orm.schema.getUpdateSchemaSQL();
if (diff) { if (diff) {
throw Error("The database structure needs to be updated in order to fit the new database structure " + throw Error(
"of the app. In order to do so automatically, set the environment variable DWENGO_DB_UPDATE to true. " + 'The database structure needs to be updated in order to fit the new database structure ' +
"The following queries will then be executed:\n" + diff) 'of the app. In order to do so automatically, set the environment variable DWENGO_DB_UPDATE to true. ' +
'The following queries will then be executed:\n' +
diff
);
} }
} }
} }
export function forkEntityManager(): EntityManager { export function forkEntityManager(): EntityManager {
if (!orm) { if (!orm) {
throw Error("Accessing the Entity Manager before the ORM is fully initialized.") throw Error(
'Accessing the Entity Manager before the ORM is fully initialized.'
);
} }
return orm.em.fork(); return orm.em.fork();
} }

View file

@ -1,15 +1,15 @@
const PREFIX = "DWENGO_"; const PREFIX = 'DWENGO_';
const DB_PREFIX = PREFIX + "DB_"; const DB_PREFIX = PREFIX + 'DB_';
type EnvVar = {key: string, required?: boolean, defaultValue?: any} type EnvVar = { key: string; required?: boolean; defaultValue?: any };
export const EnvVars: {[key: string]: EnvVar} = { export const EnvVars: { [key: string]: EnvVar } = {
"DbHost": {key: DB_PREFIX + "HOST", required: true}, DbHost: { key: DB_PREFIX + 'HOST', required: true },
"DbPort": {key: DB_PREFIX + "PORT", defaultValue: 5432}, DbPort: { key: DB_PREFIX + 'PORT', defaultValue: 5432 },
"DbName": {key: DB_PREFIX + "NAME", defaultValue: "dwengo"}, DbName: { key: DB_PREFIX + 'NAME', defaultValue: 'dwengo' },
"DbUsername": {key: DB_PREFIX + "USERNAME", required: true}, DbUsername: { key: DB_PREFIX + 'USERNAME', required: true },
"DbPassword": {key: DB_PREFIX + "PASSWORD", required: true}, DbPassword: { key: DB_PREFIX + 'PASSWORD', required: true },
"DbUpdate": {key: DB_PREFIX + "UPDATE", defaultValue: false}, DbUpdate: { key: DB_PREFIX + 'UPDATE', defaultValue: false },
} as const; } as const;
/** /**
@ -27,7 +27,7 @@ export function getEnvVar(envVar: EnvVar): string {
} else if (envVar.required) { } else if (envVar.required) {
throw new Error(`Missing environment variable: ${envVar.key}`); throw new Error(`Missing environment variable: ${envVar.key}`);
} else { } else {
return envVar.defaultValue || ""; return envVar.defaultValue || '';
} }
} }
@ -35,7 +35,9 @@ export function getNumericEnvVar(envVar: EnvVar): number {
const valueString = getEnvVar(envVar); const valueString = getEnvVar(envVar);
const value = parseInt(valueString); const value = parseInt(valueString);
if (isNaN(value)) { if (isNaN(value)) {
throw new Error(`Invalid value for environment variable ${envVar.key}: ${valueString}. Expected a number.`) throw new Error(
`Invalid value for environment variable ${envVar.key}: ${valueString}. Expected a number.`
);
} else { } else {
return value; return value;
} }