diff --git a/backend/src/config.ts b/backend/src/config.ts
index 848eb07e..df8fa133 100644
--- a/backend/src/config.ts
+++ b/backend/src/config.ts
@@ -1,4 +1,4 @@
-import {EnvVars, getEnvVar} from "./util/envvars";
+import { EnvVars, getEnvVar } from './util/envvars';
// API
export const DWENGO_API_BASE = getEnvVar(EnvVars.LearningContentRepoApiBaseUrl);
diff --git a/backend/src/controllers/learning-objects.ts b/backend/src/controllers/learning-objects.ts
index ece16057..cb4862e9 100644
--- a/backend/src/controllers/learning-objects.ts
+++ b/backend/src/controllers/learning-objects.ts
@@ -1,38 +1,35 @@
import { Request, Response } from 'express';
import { FALLBACK_LANG } from '../config.js';
-import {FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier} from '../interfaces/learning-content';
-import learningObjectService from "../services/learning-objects/learning-object-service";
-import {EnvVars, getEnvVar} from "../util/envvars";
-import {Language} from "../entities/content/language";
-import {BadRequestException} from "../exceptions";
-import attachmentService from "../services/learning-objects/attachment-service";
-import {NotFoundError} from "@mikro-orm/core";
+import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../interfaces/learning-content';
+import learningObjectService from '../services/learning-objects/learning-object-service';
+import { EnvVars, getEnvVar } from '../util/envvars';
+import { Language } from '../entities/content/language';
+import { BadRequestException } from '../exceptions';
+import attachmentService from '../services/learning-objects/attachment-service';
+import { NotFoundError } from '@mikro-orm/core';
function getLearningObjectIdentifierFromRequest(req: Request): LearningObjectIdentifier {
if (!req.params.hruid) {
- throw new BadRequestException("HRUID is required.");
+ throw new BadRequestException('HRUID is required.');
}
return {
hruid: req.params.hruid as string,
language: (req.query.language || getEnvVar(EnvVars.FallbackLanguage)) as Language,
- version: parseInt(req.query.version as string)
+ version: parseInt(req.query.version as string),
};
}
function getLearningPathIdentifierFromRequest(req: Request): LearningPathIdentifier {
if (!req.query.hruid) {
- throw new BadRequestException("HRUID is required.");
+ throw new BadRequestException('HRUID is required.');
}
return {
hruid: req.params.hruid as string,
- language: (req.query.language as Language) || FALLBACK_LANG
- }
+ language: (req.query.language as Language) || FALLBACK_LANG,
+ };
}
-export async function getAllLearningObjects(
- req: Request,
- res: Response
-): Promise {
+export async function getAllLearningObjects(req: Request, res: Response): Promise {
const learningPathId = getLearningPathIdentifierFromRequest(req);
const full = req.query.full;
@@ -46,10 +43,7 @@ export async function getAllLearningObjects(
res.json(learningObjects);
}
-export async function getLearningObject(
- req: Request,
- res: Response
-): Promise {
+export async function getLearningObject(req: Request, res: Response): Promise {
const learningObjectId = getLearningObjectIdentifierFromRequest(req);
const learningObject = await learningObjectService.getLearningObjectById(learningObjectId);
@@ -71,5 +65,5 @@ export async function getAttachment(req: Request, res: Response): Promise
if (!attachment) {
throw new NotFoundError(`Attachment ${name} not found`);
}
- res.setHeader("Content-Type", attachment.mimeType).send(attachment.content)
+ res.setHeader('Content-Type', attachment.mimeType).send(attachment.content);
}
diff --git a/backend/src/controllers/learning-paths.ts b/backend/src/controllers/learning-paths.ts
index cb5ae07e..8e654d02 100644
--- a/backend/src/controllers/learning-paths.ts
+++ b/backend/src/controllers/learning-paths.ts
@@ -1,16 +1,13 @@
import { Request, Response } from 'express';
import { themes } from '../data/themes.js';
import { FALLBACK_LANG } from '../config.js';
-import learningPathService from "../services/learning-paths/learning-path-service";
-import {NotFoundException} from "../exceptions";
+import learningPathService from '../services/learning-paths/learning-path-service';
+import { NotFoundException } from '../exceptions';
/**
* Fetch learning paths based on query parameters.
*/
-export async function getLearningPaths(
- req: Request,
- res: Response
-): Promise {
+export async function getLearningPaths(req: Request, res: Response): Promise {
const hruids = req.query.hruid;
const themeKey = req.query.theme as string;
const searchQuery = req.query.search as string;
@@ -19,35 +16,22 @@ export async function getLearningPaths(
let hruidList;
if (hruids) {
- hruidList = Array.isArray(hruids)
- ? hruids.map(String)
- : [String(hruids)];
+ hruidList = Array.isArray(hruids) ? hruids.map(String) : [String(hruids)];
} else if (themeKey) {
- const theme = themes.find((t) => {
- return t.title === themeKey;
- });
+ const theme = themes.find((t) => t.title === themeKey);
if (theme) {
hruidList = theme.hruids;
} else {
throw new NotFoundException(`Theme "${themeKey}" not found.`);
}
} else if (searchQuery) {
- const searchResults = await learningPathService.searchLearningPaths(
- searchQuery,
- language
- );
+ const searchResults = await learningPathService.searchLearningPaths(searchQuery, language);
res.json(searchResults);
return;
} else {
- hruidList = themes.flatMap((theme) => {
- return theme.hruids;
- });
+ hruidList = themes.flatMap((theme) => theme.hruids);
}
- const learningPaths = await learningPathService.fetchLearningPaths(
- hruidList,
- language,
- `HRUIDs: ${hruidList.join(', ')}`
- );
+ const learningPaths = await learningPathService.fetchLearningPaths(hruidList, language, `HRUIDs: ${hruidList.join(', ')}`);
res.json(learningPaths.data);
}
diff --git a/backend/src/controllers/learningPaths.ts b/backend/src/controllers/learningPaths.ts
index 707334b7..50299d0f 100644
--- a/backend/src/controllers/learningPaths.ts
+++ b/backend/src/controllers/learningPaths.ts
@@ -1,4 +1,3 @@
-
import { Request, Response } from 'express';
import { themes } from '../data/themes.js';
import { FALLBACK_LANG } from '../config.js';
diff --git a/backend/src/data/content/attachment-repository.ts b/backend/src/data/content/attachment-repository.ts
index c7a53c86..95c5ab1c 100644
--- a/backend/src/data/content/attachment-repository.ts
+++ b/backend/src/data/content/attachment-repository.ts
@@ -1,13 +1,10 @@
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
import { Attachment } from '../../entities/content/attachment.entity.js';
-import {Language} from "../../entities/content/language";
-import {LearningObjectIdentifier} from "../../entities/content/learning-object-identifier";
+import { Language } from '../../entities/content/language';
+import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier';
export class AttachmentRepository extends DwengoEntityRepository {
- public findByLearningObjectIdAndName(
- learningObjectId: LearningObjectIdentifier,
- name: string
- ): Promise {
+ public findByLearningObjectIdAndName(learningObjectId: LearningObjectIdentifier, name: string): Promise {
return this.findOne({
learningObject: {
hruid: learningObjectId.hruid,
@@ -18,24 +15,23 @@ export class AttachmentRepository extends DwengoEntityRepository {
});
}
- public findByMostRecentVersionOfLearningObjectAndName(
- hruid: string,
- language: Language,
- attachmentName: string
- ): Promise {
- return this.findOne({
- learningObject: {
- hruid: hruid,
- language: language
- },
- name: attachmentName
- }, {
- orderBy: {
+ public findByMostRecentVersionOfLearningObjectAndName(hruid: string, language: Language, attachmentName: string): Promise {
+ return this.findOne(
+ {
learningObject: {
- version: 'DESC'
- }
+ hruid: hruid,
+ language: language,
+ },
+ name: attachmentName,
+ },
+ {
+ orderBy: {
+ learningObject: {
+ version: 'DESC',
+ },
+ },
}
- });
+ );
}
// This repository is read-only for now since creating own learning object is an extension feature.
}
diff --git a/backend/src/data/content/learning-object-repository.ts b/backend/src/data/content/learning-object-repository.ts
index 8fdf18fe..f9b6bfcb 100644
--- a/backend/src/data/content/learning-object-repository.ts
+++ b/backend/src/data/content/learning-object-repository.ts
@@ -1,12 +1,10 @@
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
import { LearningObject } from '../../entities/content/learning-object.entity.js';
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
-import {Language} from "../../entities/content/language";
+import { Language } from '../../entities/content/language';
export class LearningObjectRepository extends DwengoEntityRepository {
- public findByIdentifier(
- identifier: LearningObjectIdentifier
- ): Promise {
+ public findByIdentifier(identifier: LearningObjectIdentifier): Promise {
return this.findOne(
{
hruid: identifier.hruid,
@@ -14,7 +12,7 @@ export class LearningObjectRepository extends DwengoEntityRepository {
- public findByHruidAndLanguage(
- hruid: string,
- language: Language
- ): Promise {
- return this.findOne(
- { hruid: hruid, language: language },
- { populate: ["nodes", "nodes.transitions"] }
- );
+ public findByHruidAndLanguage(hruid: string, language: Language): Promise {
+ return this.findOne({ hruid: hruid, language: language }, { populate: ['nodes', 'nodes.transitions'] });
}
/**
@@ -24,12 +18,9 @@ export class LearningPathRepository extends DwengoEntityRepository
return this.findAll({
where: {
language: language,
- $or: [
- { title: { $like: `%${query}%`} },
- { description: { $like: `%${query}%`} }
- ]
+ $or: [{ title: { $like: `%${query}%` } }, { description: { $like: `%${query}%` } }],
},
- populate: ["nodes", "nodes.transitions"]
+ populate: ['nodes', 'nodes.transitions'],
});
}
}
diff --git a/backend/src/data/repositories.ts b/backend/src/data/repositories.ts
index 543de6e5..7901d928 100644
--- a/backend/src/data/repositories.ts
+++ b/backend/src/data/repositories.ts
@@ -28,8 +28,8 @@ import { LearningPath } from '../entities/content/learning-path.entity.js';
import { LearningPathRepository } from './content/learning-path-repository.js';
import { AttachmentRepository } from './content/attachment-repository.js';
import { Attachment } from '../entities/content/attachment.entity.js';
-import {LearningPathNode} from "../entities/content/learning-path-node.entity";
-import {LearningPathTransition} from "../entities/content/learning-path-transition.entity";
+import { LearningPathNode } from '../entities/content/learning-path-node.entity';
+import { LearningPathTransition } from '../entities/content/learning-path-transition.entity';
let entityManager: EntityManager | undefined;
@@ -73,17 +73,8 @@ export const getQuestionRepository = repositoryGetter(Answer);
/* Learning content */
-export const getLearningObjectRepository = repositoryGetter<
- LearningObject,
- LearningObjectRepository
->(LearningObject);
-export const getLearningPathRepository = repositoryGetter<
- LearningPath,
- LearningPathRepository
->(LearningPath);
+export const getLearningObjectRepository = repositoryGetter(LearningObject);
+export const getLearningPathRepository = repositoryGetter(LearningPath);
export const getLearningPathNodeRepository = repositoryGetter(LearningPathNode);
export const getLearningPathTransitionRepository = repositoryGetter(LearningPathTransition);
-export const getAttachmentRepository = repositoryGetter<
- Attachment,
- AttachmentRepository
->(Attachment);
+export const getAttachmentRepository = repositoryGetter(Attachment);
diff --git a/backend/src/entities/assignments/assignment.entity.ts b/backend/src/entities/assignments/assignment.entity.ts
index 44bb6810..9e3f3b03 100644
--- a/backend/src/entities/assignments/assignment.entity.ts
+++ b/backend/src/entities/assignments/assignment.entity.ts
@@ -2,9 +2,9 @@ import { Entity, Enum, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro
import { Class } from '../classes/class.entity.js';
import { Group } from './group.entity.js';
import { Language } from '../content/language.js';
-import {AssignmentRepository} from "../../data/assignments/assignment-repository";
+import { AssignmentRepository } from '../../data/assignments/assignment-repository';
-@Entity({repository: () => AssignmentRepository})
+@Entity({ repository: () => AssignmentRepository })
export class Assignment {
@ManyToOne({ entity: () => Class, primary: true })
within!: Class;
diff --git a/backend/src/entities/assignments/group.entity.ts b/backend/src/entities/assignments/group.entity.ts
index 0915b31b..7e01cf62 100644
--- a/backend/src/entities/assignments/group.entity.ts
+++ b/backend/src/entities/assignments/group.entity.ts
@@ -1,9 +1,9 @@
import { Entity, ManyToMany, ManyToOne, PrimaryKey } from '@mikro-orm/core';
import { Assignment } from './assignment.entity.js';
import { Student } from '../users/student.entity.js';
-import {GroupRepository} from "../../data/assignments/group-repository";
+import { GroupRepository } from '../../data/assignments/group-repository';
-@Entity({repository: () => GroupRepository})
+@Entity({ repository: () => GroupRepository })
export class Group {
@ManyToOne({
entity: () => Assignment,
diff --git a/backend/src/entities/assignments/submission.entity.ts b/backend/src/entities/assignments/submission.entity.ts
index a5c2238b..34e0c1f6 100644
--- a/backend/src/entities/assignments/submission.entity.ts
+++ b/backend/src/entities/assignments/submission.entity.ts
@@ -2,9 +2,9 @@ import { Student } from '../users/student.entity.js';
import { Group } from './group.entity.js';
import { Entity, Enum, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import { Language } from '../content/language.js';
-import {SubmissionRepository} from "../../data/assignments/submission-repository";
+import { SubmissionRepository } from '../../data/assignments/submission-repository';
-@Entity({repository: () => SubmissionRepository})
+@Entity({ repository: () => SubmissionRepository })
export class Submission {
@PrimaryKey({ type: 'string' })
learningObjectHruid!: string;
diff --git a/backend/src/entities/classes/class-join-request.entity.ts b/backend/src/entities/classes/class-join-request.entity.ts
index 5d9ef571..01197193 100644
--- a/backend/src/entities/classes/class-join-request.entity.ts
+++ b/backend/src/entities/classes/class-join-request.entity.ts
@@ -1,9 +1,9 @@
import { Entity, Enum, ManyToOne } from '@mikro-orm/core';
import { Student } from '../users/student.entity.js';
import { Class } from './class.entity.js';
-import {ClassJoinRequestRepository} from "../../data/classes/class-join-request-repository";
+import { ClassJoinRequestRepository } from '../../data/classes/class-join-request-repository';
-@Entity({repository: () => ClassJoinRequestRepository})
+@Entity({ repository: () => ClassJoinRequestRepository })
export class ClassJoinRequest {
@ManyToOne({
entity: () => Student,
diff --git a/backend/src/entities/classes/class.entity.ts b/backend/src/entities/classes/class.entity.ts
index c430c9dc..610622cc 100644
--- a/backend/src/entities/classes/class.entity.ts
+++ b/backend/src/entities/classes/class.entity.ts
@@ -2,9 +2,9 @@ import { Collection, Entity, ManyToMany, PrimaryKey, Property } from '@mikro-orm
import { v4 } from 'uuid';
import { Teacher } from '../users/teacher.entity.js';
import { Student } from '../users/student.entity.js';
-import {ClassRepository} from "../../data/classes/class-repository";
+import { ClassRepository } from '../../data/classes/class-repository';
-@Entity({repository: () => ClassRepository})
+@Entity({ repository: () => ClassRepository })
export class Class {
@PrimaryKey()
classId = v4();
diff --git a/backend/src/entities/classes/teacher-invitation.entity.ts b/backend/src/entities/classes/teacher-invitation.entity.ts
index 597b6a41..e8bb8d01 100644
--- a/backend/src/entities/classes/teacher-invitation.entity.ts
+++ b/backend/src/entities/classes/teacher-invitation.entity.ts
@@ -1,12 +1,12 @@
import { Entity, ManyToOne } from '@mikro-orm/core';
import { Teacher } from '../users/teacher.entity.js';
import { Class } from './class.entity.js';
-import {TeacherInvitationRepository} from "../../data/classes/teacher-invitation-repository";
+import { TeacherInvitationRepository } from '../../data/classes/teacher-invitation-repository';
/**
* Invitation of a teacher into a class (in order to teach it).
*/
-@Entity({repository: () => TeacherInvitationRepository})
+@Entity({ repository: () => TeacherInvitationRepository })
export class TeacherInvitation {
@ManyToOne({
entity: () => Teacher,
diff --git a/backend/src/entities/content/attachment.entity.ts b/backend/src/entities/content/attachment.entity.ts
index 5e7000cf..f0a1b181 100644
--- a/backend/src/entities/content/attachment.entity.ts
+++ b/backend/src/entities/content/attachment.entity.ts
@@ -1,8 +1,8 @@
import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import { LearningObject } from './learning-object.entity.js';
-import {AttachmentRepository} from "../../data/content/attachment-repository";
+import { AttachmentRepository } from '../../data/content/attachment-repository';
-@Entity({repository: () => AttachmentRepository})
+@Entity({ repository: () => AttachmentRepository })
export class Attachment {
@ManyToOne({
entity: () => LearningObject,
diff --git a/backend/src/entities/content/language.ts b/backend/src/entities/content/language.ts
index 7a106762..d7687331 100644
--- a/backend/src/entities/content/language.ts
+++ b/backend/src/entities/content/language.ts
@@ -182,5 +182,5 @@ export enum Language {
Yiddish = 'yi',
Yoruba = 'yo',
Zhuang = 'za',
- Zulu = 'zu'
+ Zulu = 'zu',
}
diff --git a/backend/src/entities/content/learning-object.entity.ts b/backend/src/entities/content/learning-object.entity.ts
index 8f3672be..55c4a808 100644
--- a/backend/src/entities/content/learning-object.entity.ts
+++ b/backend/src/entities/content/learning-object.entity.ts
@@ -2,11 +2,11 @@ import { Embeddable, Embedded, Entity, Enum, ManyToMany, OneToMany, PrimaryKey,
import { Language } from './language.js';
import { Attachment } from './attachment.entity.js';
import { Teacher } from '../users/teacher.entity.js';
-import {DwengoContentType} from "../../services/learning-objects/processing/content-type";
-import {v4} from "uuid";
-import {LearningObjectRepository} from "../../data/content/learning-object-repository";
+import { DwengoContentType } from '../../services/learning-objects/processing/content-type';
+import { v4 } from 'uuid';
+import { LearningObjectRepository } from '../../data/content/learning-object-repository';
-@Entity({repository: () => LearningObjectRepository})
+@Entity({ repository: () => LearningObjectRepository })
export class LearningObject {
@PrimaryKey({ type: 'string' })
hruid!: string;
@@ -20,7 +20,7 @@ export class LearningObject {
@PrimaryKey({ type: 'number' })
version: number = 1;
- @Property({type: 'uuid', unique: true})
+ @Property({ type: 'uuid', unique: true })
uuid = v4();
@ManyToMany({
diff --git a/backend/src/entities/content/learning-path-node.entity.ts b/backend/src/entities/content/learning-path-node.entity.ts
index e2fbdbb3..9dbb47b4 100644
--- a/backend/src/entities/content/learning-path-node.entity.ts
+++ b/backend/src/entities/content/learning-path-node.entity.ts
@@ -1,15 +1,14 @@
-import {Entity, Enum, ManyToOne, OneToMany, PrimaryKey, Property} from "@mikro-orm/core";
-import {Language} from "./language";
-import {LearningPath} from "./learning-path.entity";
-import {LearningPathTransition} from "./learning-path-transition.entity";
+import { Entity, Enum, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core';
+import { Language } from './language';
+import { LearningPath } from './learning-path.entity';
+import { LearningPathTransition } from './learning-path-transition.entity';
@Entity()
export class LearningPathNode {
-
@ManyToOne({ entity: () => LearningPath, primary: true })
learningPath!: LearningPath;
- @PrimaryKey({ type: "integer", autoincrement: true })
+ @PrimaryKey({ type: 'integer', autoincrement: true })
nodeNumber!: number;
@Property({ type: 'string' })
@@ -27,7 +26,7 @@ export class LearningPathNode {
@Property({ type: 'bool' })
startNode!: boolean;
- @OneToMany({ entity: () => LearningPathTransition, mappedBy: "node" })
+ @OneToMany({ entity: () => LearningPathTransition, mappedBy: 'node' })
transitions: LearningPathTransition[] = [];
@Property({ length: 3 })
diff --git a/backend/src/entities/content/learning-path-transition.entity.ts b/backend/src/entities/content/learning-path-transition.entity.ts
index dfbe110e..97bfc65f 100644
--- a/backend/src/entities/content/learning-path-transition.entity.ts
+++ b/backend/src/entities/content/learning-path-transition.entity.ts
@@ -1,9 +1,9 @@
-import {Entity, ManyToOne, PrimaryKey, Property} from "@mikro-orm/core";
-import {LearningPathNode} from "./learning-path-node.entity";
+import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
+import { LearningPathNode } from './learning-path-node.entity';
@Entity()
export class LearningPathTransition {
- @ManyToOne({entity: () => LearningPathNode, primary: true })
+ @ManyToOne({ entity: () => LearningPathNode, primary: true })
node!: LearningPathNode;
@PrimaryKey({ type: 'numeric' })
diff --git a/backend/src/entities/content/learning-path.entity.ts b/backend/src/entities/content/learning-path.entity.ts
index 3bb839a0..e74388aa 100644
--- a/backend/src/entities/content/learning-path.entity.ts
+++ b/backend/src/entities/content/learning-path.entity.ts
@@ -1,16 +1,10 @@
-import {
- Entity,
- Enum,
- ManyToMany, OneToMany,
- PrimaryKey,
- Property,
-} from '@mikro-orm/core';
+import { Entity, Enum, ManyToMany, OneToMany, PrimaryKey, Property } from '@mikro-orm/core';
import { Language } from './language.js';
import { Teacher } from '../users/teacher.entity.js';
-import {LearningPathRepository} from "../../data/content/learning-path-repository";
-import {LearningPathNode} from "./learning-path-node.entity";
+import { LearningPathRepository } from '../../data/content/learning-path-repository';
+import { LearningPathNode } from './learning-path-node.entity';
-@Entity({repository: () => LearningPathRepository})
+@Entity({ repository: () => LearningPathRepository })
export class LearningPath {
@PrimaryKey({ type: 'string' })
hruid!: string;
@@ -30,6 +24,6 @@ export class LearningPath {
@Property({ type: 'blob', nullable: true })
image: Buffer | null = null;
- @OneToMany({ entity: () => LearningPathNode, mappedBy: "learningPath" })
+ @OneToMany({ entity: () => LearningPathNode, mappedBy: 'learningPath' })
nodes: LearningPathNode[] = [];
}
diff --git a/backend/src/entities/questions/answer.entity.ts b/backend/src/entities/questions/answer.entity.ts
index 81974943..2c975cc5 100644
--- a/backend/src/entities/questions/answer.entity.ts
+++ b/backend/src/entities/questions/answer.entity.ts
@@ -1,9 +1,9 @@
import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import { Question } from './question.entity.js';
import { Teacher } from '../users/teacher.entity.js';
-import {AnswerRepository} from "../../data/questions/answer-repository";
+import { AnswerRepository } from '../../data/questions/answer-repository';
-@Entity({repository: () => AnswerRepository})
+@Entity({ repository: () => AnswerRepository })
export class Answer {
@ManyToOne({
entity: () => Teacher,
diff --git a/backend/src/entities/questions/question.entity.ts b/backend/src/entities/questions/question.entity.ts
index c03b0e8f..bfa0d7bb 100644
--- a/backend/src/entities/questions/question.entity.ts
+++ b/backend/src/entities/questions/question.entity.ts
@@ -1,9 +1,9 @@
import { Entity, Enum, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
import { Language } from '../content/language.js';
import { Student } from '../users/student.entity.js';
-import {QuestionRepository} from "../../data/questions/question-repository";
+import { QuestionRepository } from '../../data/questions/question-repository';
-@Entity({repository: () => QuestionRepository})
+@Entity({ repository: () => QuestionRepository })
export class Question {
@PrimaryKey({ type: 'string' })
learningObjectHruid!: string;
diff --git a/backend/src/entities/users/teacher.entity.ts b/backend/src/entities/users/teacher.entity.ts
index ca3290bf..8af72c37 100644
--- a/backend/src/entities/users/teacher.entity.ts
+++ b/backend/src/entities/users/teacher.entity.ts
@@ -1,9 +1,9 @@
import { Collection, Entity, ManyToMany } from '@mikro-orm/core';
import { User } from './user.entity.js';
import { Class } from '../classes/class.entity.js';
-import {TeacherRepository} from "../../data/users/teacher-repository";
+import { TeacherRepository } from '../../data/users/teacher-repository';
-@Entity({repository: () => TeacherRepository})
+@Entity({ repository: () => TeacherRepository })
export class Teacher extends User {
@ManyToMany(() => Class)
classes!: Collection;
diff --git a/backend/src/interfaces/learning-content.ts b/backend/src/interfaces/learning-content.ts
index 5d11d6b2..970796a2 100644
--- a/backend/src/interfaces/learning-content.ts
+++ b/backend/src/interfaces/learning-content.ts
@@ -1,4 +1,4 @@
-import {Language} from "../entities/content/language";
+import { Language } from '../entities/content/language';
export interface Transition {
default: boolean;
diff --git a/backend/src/routes/learning-objects.ts b/backend/src/routes/learning-objects.ts
index 421a5f19..b731fe69 100644
--- a/backend/src/routes/learning-objects.ts
+++ b/backend/src/routes/learning-objects.ts
@@ -1,8 +1,5 @@
import express from 'express';
-import {
- getAllLearningObjects, getAttachment,
- getLearningObject, getLearningObjectHTML,
-} from '../controllers/learning-objects.js';
+import { getAllLearningObjects, getAttachment, getLearningObject, getLearningObjectHTML } from '../controllers/learning-objects.js';
const router = express.Router();
diff --git a/backend/src/services/learning-objects/attachment-service.ts b/backend/src/services/learning-objects/attachment-service.ts
index 2285ddfe..7791ac04 100644
--- a/backend/src/services/learning-objects/attachment-service.ts
+++ b/backend/src/services/learning-objects/attachment-service.ts
@@ -1,21 +1,23 @@
-import {getAttachmentRepository} from "../../data/repositories";
-import {Attachment} from "../../entities/content/attachment.entity";
-import {LearningObjectIdentifier} from "../../interfaces/learning-content";
+import { getAttachmentRepository } from '../../data/repositories';
+import { Attachment } from '../../entities/content/attachment.entity';
+import { LearningObjectIdentifier } from '../../interfaces/learning-content';
const attachmentService = {
getAttachment(learningObjectId: LearningObjectIdentifier, attachmentName: string): Promise {
const attachmentRepo = getAttachmentRepository();
if (learningObjectId.version) {
- return attachmentRepo.findByLearningObjectIdAndName({
- hruid: learningObjectId.hruid,
- language: learningObjectId.language,
- version: learningObjectId.version,
- }, attachmentName);
- } else {
- return attachmentRepo.findByMostRecentVersionOfLearningObjectAndName(learningObjectId.hruid, learningObjectId.language, attachmentName);
+ return attachmentRepo.findByLearningObjectIdAndName(
+ {
+ hruid: learningObjectId.hruid,
+ language: learningObjectId.language,
+ version: learningObjectId.version,
+ },
+ attachmentName
+ );
}
- }
-}
+ return attachmentRepo.findByMostRecentVersionOfLearningObjectAndName(learningObjectId.hruid, learningObjectId.language, attachmentName);
+ },
+};
export default attachmentService;
diff --git a/backend/src/services/learning-objects/database-learning-object-provider.ts b/backend/src/services/learning-objects/database-learning-object-provider.ts
index 56aa3a99..57ef37bb 100644
--- a/backend/src/services/learning-objects/database-learning-object-provider.ts
+++ b/backend/src/services/learning-objects/database-learning-object-provider.ts
@@ -35,20 +35,18 @@ function convertLearningObject(learningObject: LearningObject | null): FilteredL
educationalGoals: learningObject.educationalGoals,
returnValue: {
callback_url: learningObject.returnValue.callbackUrl,
- callback_schema: JSON.parse(learningObject.returnValue.callbackSchema)
+ callback_schema: JSON.parse(learningObject.returnValue.callbackSchema),
},
skosConcepts: learningObject.skosConcepts,
targetAges: learningObject.targetAges || [],
- teacherExclusive: learningObject.teacherExclusive
- }
+ teacherExclusive: learningObject.teacherExclusive,
+ };
}
function findLearningObjectEntityById(id: LearningObjectIdentifier): Promise {
const learningObjectRepo = getLearningObjectRepository();
- return learningObjectRepo.findLatestByHruidAndLanguage(
- id.hruid, id.language as Language
- );
+ return learningObjectRepo.findLatestByHruidAndLanguage(id.hruid, id.language as Language);
}
/**
@@ -69,16 +67,11 @@ const databaseLearningObjectProvider: LearningObjectProvider = {
async getLearningObjectHTML(id: LearningObjectIdentifier): Promise {
const learningObjectRepo = getLearningObjectRepository();
- const learningObject = await learningObjectRepo.findLatestByHruidAndLanguage(
- id.hruid, id.language as Language
- );
+ const learningObject = await learningObjectRepo.findLatestByHruidAndLanguage(id.hruid, id.language as Language);
if (!learningObject) {
return null;
}
- return await processingService.render(
- learningObject,
- (id) => findLearningObjectEntityById(id)
- );
+ return await processingService.render(learningObject, (id) => findLearningObjectEntityById(id));
},
/**
@@ -89,9 +82,9 @@ const databaseLearningObjectProvider: LearningObjectProvider = {
const learningPath = await learningPathRepo.findByHruidAndLanguage(id.hruid, id.language);
if (!learningPath) {
- throw new NotFoundError("The learning path with the given ID could not be found.");
+ throw new NotFoundError('The learning path with the given ID could not be found.');
}
- return learningPath.nodes.map(it => it.learningObjectHruid);
+ return learningPath.nodes.map((it) => it.learningObjectHruid); // TODO: Determine this based on the submissions of the user.
},
/**
@@ -102,15 +95,15 @@ const databaseLearningObjectProvider: LearningObjectProvider = {
const learningPath = await learningPathRepo.findByHruidAndLanguage(id.hruid, id.language);
if (!learningPath) {
- throw new NotFoundError("The learning path with the given ID could not be found.");
+ throw new NotFoundError('The learning path with the given ID could not be found.');
}
const learningObjects = await Promise.all(
- learningPath.nodes.map(it => {
+ learningPath.nodes.map((it) => {
const learningObject = learningObjectService.getLearningObjectById({
hruid: it.learningObjectHruid,
language: it.language,
- version: it.version
- })
+ version: it.version,
+ });
if (learningObject === null) {
console.log(`WARN: Learning object corresponding with node ${it} not found!`);
}
@@ -119,6 +112,6 @@ const databaseLearningObjectProvider: LearningObjectProvider = {
);
return learningObjects.filter(it => it !== null);
}
-}
+};
export default databaseLearningObjectProvider;
diff --git a/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts b/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts
index 628f616c..c59a3616 100644
--- a/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts
+++ b/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts
@@ -1,22 +1,22 @@
import { DWENGO_API_BASE } from '../../config.js';
import { fetchWithLogging } from '../../util/apiHelper.js';
import {
- FilteredLearningObject, LearningObjectIdentifier,
+ FilteredLearningObject,
+ LearningObjectIdentifier,
LearningObjectMetadata,
- LearningObjectNode, LearningPathIdentifier,
+ LearningObjectNode,
+ LearningPathIdentifier,
LearningPathResponse,
} from '../../interfaces/learning-content.js';
import dwengoApiLearningPathProvider from '../learning-paths/dwengo-api-learning-path-provider.js';
-import {LearningObjectProvider} from "./learning-object-provider";
+import { LearningObjectProvider } from './learning-object-provider';
/**
* Helper function to convert the learning object metadata retrieved from the API to a FilteredLearningObject which
* our API should return.
* @param data
*/
-function filterData(
- data: LearningObjectMetadata
-): FilteredLearningObject {
+function filterData(data: LearningObjectMetadata): FilteredLearningObject {
return {
key: data.hruid, // Hruid learningObject (not path)
_id: data._id,
@@ -43,48 +43,33 @@ function filterData(
/**
* Generic helper function to fetch all learning objects from a given path (full data or just HRUIDs)
*/
-async function fetchLearningObjects(
- learningPathId: LearningPathIdentifier,
- full: boolean
-): Promise {
+async function fetchLearningObjects(learningPathId: LearningPathIdentifier, full: boolean): Promise {
try {
- const learningPathResponse: LearningPathResponse =
- await dwengoApiLearningPathProvider.fetchLearningPaths(
- [learningPathId.hruid],
- learningPathId.language,
- `Learning path for HRUID "${learningPathId.hruid}"`
- );
+ const learningPathResponse: LearningPathResponse = await dwengoApiLearningPathProvider.fetchLearningPaths(
+ [learningPathId.hruid],
+ learningPathId.language,
+ `Learning path for HRUID "${learningPathId.hruid}"`
+ );
- if (
- !learningPathResponse.success ||
- !learningPathResponse.data?.length
- ) {
- console.error(
- `⚠️ WARNING: Learning path "${learningPathId.hruid}" exists but contains no learning objects.`
- );
+ if (!learningPathResponse.success || !learningPathResponse.data?.length) {
+ console.error(`⚠️ WARNING: Learning path "${learningPathId.hruid}" exists but contains no learning objects.`);
return [];
}
const nodes: LearningObjectNode[] = learningPathResponse.data[0].nodes;
if (!full) {
- return nodes.map((node) => {
- return node.learningobject_hruid;
- });
+ return nodes.map((node) => node.learningobject_hruid);
}
return await Promise.all(
- nodes.map(async (node) => {
- return dwengoApiLearningObjectProvider.getLearningObjectById({
+ nodes.map(async (node) =>
+ dwengoApiLearningObjectProvider.getLearningObjectById({
hruid: node.learningobject_hruid,
- language: learningPathId.language
- });
- })
- ).then((objects) => {
- return objects.filter((obj): obj is FilteredLearningObject => {
- return obj !== null;
- });
- });
+ language: learningPathId.language,
+ })
+ )
+ ).then((objects) => objects.filter((obj): obj is FilteredLearningObject => obj !== null));
} catch (error) {
console.error('❌ Error fetching learning objects:', error);
return [];
@@ -95,19 +80,17 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = {
/**
* Fetches a single learning object by its HRUID
*/
- async getLearningObjectById(
- id: LearningObjectIdentifier
- ): Promise {
- let metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata`;
+ async getLearningObjectById(id: LearningObjectIdentifier): Promise {
+ const metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata`;
const metadata = await fetchWithLogging(
metadataUrl,
`Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`,
{
- params: id
+ params: id,
}
);
- if (!metadata || typeof metadata !== "object") {
+ if (!metadata || typeof metadata !== 'object') {
console.error(`⚠️ WARNING: Learning object "${id.hruid}" not found.`);
return null;
}
@@ -119,10 +102,7 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = {
* Fetch full learning object data (metadata)
*/
async getLearningObjectsFromPath(id: LearningPathIdentifier): Promise {
- return (await fetchLearningObjects(
- id,
- true,
- )) as FilteredLearningObject[];
+ return (await fetchLearningObjects(id, true)) as FilteredLearningObject[];
},
/**
@@ -138,13 +118,9 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = {
*/
async getLearningObjectHTML(id: LearningObjectIdentifier): Promise {
const htmlUrl = `${DWENGO_API_BASE}/learningObject/getRaw`;
- const html = await fetchWithLogging(
- htmlUrl,
- `Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`,
- {
- params: id
- }
- );
+ const html = await fetchWithLogging(htmlUrl, `Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`, {
+ params: id,
+ });
if (!html) {
console.error(`⚠️ WARNING: Learning object "${id.hruid}" not found.`);
@@ -152,7 +128,7 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = {
}
return html;
- }
+ },
};
export default dwengoApiLearningObjectProvider;
diff --git a/backend/src/services/learning-objects/learning-object-provider.ts b/backend/src/services/learning-objects/learning-object-provider.ts
index 70190a1a..4d443ca0 100644
--- a/backend/src/services/learning-objects/learning-object-provider.ts
+++ b/backend/src/services/learning-objects/learning-object-provider.ts
@@ -1,8 +1,4 @@
-import {
- FilteredLearningObject,
- LearningObjectIdentifier,
- LearningPathIdentifier
-} from "../../interfaces/learning-content";
+import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content';
export interface LearningObjectProvider {
/**
diff --git a/backend/src/services/learning-objects/learning-object-service.ts b/backend/src/services/learning-objects/learning-object-service.ts
index 51152ec8..b207d3dc 100644
--- a/backend/src/services/learning-objects/learning-object-service.ts
+++ b/backend/src/services/learning-objects/learning-object-service.ts
@@ -1,19 +1,14 @@
-import {
- FilteredLearningObject,
- LearningObjectIdentifier,
- LearningPathIdentifier
-} from "../../interfaces/learning-content";
-import dwengoApiLearningObjectProvider from "./dwengo-api-learning-object-provider";
-import {LearningObjectProvider} from "./learning-object-provider";
-import {EnvVars, getEnvVar} from "../../util/envvars";
-import databaseLearningObjectProvider from "./database-learning-object-provider";
+import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content';
+import dwengoApiLearningObjectProvider from './dwengo-api-learning-object-provider';
+import { LearningObjectProvider } from './learning-object-provider';
+import { EnvVars, getEnvVar } from '../../util/envvars';
+import databaseLearningObjectProvider from './database-learning-object-provider';
function getProvider(id: LearningObjectIdentifier): LearningObjectProvider {
if (id.hruid.startsWith(getEnvVar(EnvVars.UserContentPrefix))) {
return databaseLearningObjectProvider;
- } else {
- return dwengoApiLearningObjectProvider;
}
+ return dwengoApiLearningObjectProvider;
}
/**
@@ -46,7 +41,7 @@ const learningObjectService = {
*/
getLearningObjectHTML(id: LearningObjectIdentifier): Promise {
return getProvider(id).getLearningObjectHTML(id);
- }
+ },
};
export default learningObjectService;
diff --git a/backend/src/services/learning-objects/processing/audio/audio-processor.ts b/backend/src/services/learning-objects/processing/audio/audio-processor.ts
index 0c4dd75e..3f7a8837 100644
--- a/backend/src/services/learning-objects/processing/audio/audio-processor.ts
+++ b/backend/src/services/learning-objects/processing/audio/audio-processor.ts
@@ -5,12 +5,11 @@
*/
import DOMPurify from 'isomorphic-dompurify';
-import {type} from "node:os";
-import {DwengoContentType} from "../content-type";
-import {StringProcessor} from "../string-processor";
+import { type } from 'node:os';
+import { DwengoContentType } from '../content-type';
+import { StringProcessor } from '../string-processor';
class AudioProcessor extends StringProcessor {
-
constructor() {
super(DwengoContentType.AUDIO_MPEG);
}
diff --git a/backend/src/services/learning-objects/processing/content-type.ts b/backend/src/services/learning-objects/processing/content-type.ts
index d71c97b4..2ea44246 100644
--- a/backend/src/services/learning-objects/processing/content-type.ts
+++ b/backend/src/services/learning-objects/processing/content-type.ts
@@ -3,16 +3,16 @@
*/
enum DwengoContentType {
- TEXT_PLAIN = "text/plain",
- TEXT_MARKDOWN = "text/markdown",
- IMAGE_BLOCK = "image/image-block",
- IMAGE_INLINE = "image/image",
- AUDIO_MPEG = "audio/mpeg",
- APPLICATION_PDF = "application/pdf",
- EXTERN = "extern",
- BLOCKLY = "blockly",
- GIFT = "text/gift",
- CT_SCHEMA = "text/ct-schema"
+ TEXT_PLAIN = 'text/plain',
+ TEXT_MARKDOWN = 'text/markdown',
+ IMAGE_BLOCK = 'image/image-block',
+ IMAGE_INLINE = 'image/image',
+ AUDIO_MPEG = 'audio/mpeg',
+ APPLICATION_PDF = 'application/pdf',
+ EXTERN = 'extern',
+ BLOCKLY = 'blockly',
+ GIFT = 'text/gift',
+ CT_SCHEMA = 'text/ct-schema',
}
-export { DwengoContentType }
+export { DwengoContentType };
diff --git a/backend/src/services/learning-objects/processing/extern/extern-processor.ts b/backend/src/services/learning-objects/processing/extern/extern-processor.ts
index aff26d45..d16445dc 100644
--- a/backend/src/services/learning-objects/processing/extern/extern-processor.ts
+++ b/backend/src/services/learning-objects/processing/extern/extern-processor.ts
@@ -5,10 +5,10 @@
*/
import DOMPurify from 'isomorphic-dompurify';
-import {ProcessingError} from "../processing-error";
-import {isValidHttpUrl} from "../../../../util/links";
-import {DwengoContentType} from "../content-type";
-import {StringProcessor} from "../string-processor";
+import { ProcessingError } from '../processing-error';
+import { isValidHttpUrl } from '../../../../util/links';
+import { DwengoContentType } from '../content-type';
+import { StringProcessor } from '../string-processor';
class ExternProcessor extends StringProcessor {
constructor() {
@@ -17,23 +17,23 @@ class ExternProcessor extends StringProcessor {
override renderFn(externURL: string) {
if (!isValidHttpUrl(externURL)) {
- throw new ProcessingError("The url is not valid: " + externURL);
+ throw new ProcessingError('The url is not valid: ' + externURL);
}
// If a seperate youtube-processor would be added, this code would need to move to that processor
// Converts youtube urls to youtube-embed urls
- let match = /(.*youtube.com\/)watch\?v=(.*)/.exec(externURL)
+ const match = /(.*youtube.com\/)watch\?v=(.*)/.exec(externURL);
if (match) {
- externURL = match[1] + "embed/" + match[2];
+ externURL = match[1] + 'embed/' + match[2];
}
- return DOMPurify.sanitize(`
+ return DOMPurify.sanitize(
+ `
`,
- { ADD_TAGS: ["iframe"], ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling']}
+ { ADD_TAGS: ['iframe'], ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling'] }
);
-
}
}
diff --git a/backend/src/services/learning-objects/processing/gift/gift-processor.ts b/backend/src/services/learning-objects/processing/gift/gift-processor.ts
index 5d20e99c..49f41904 100644
--- a/backend/src/services/learning-objects/processing/gift/gift-processor.ts
+++ b/backend/src/services/learning-objects/processing/gift/gift-processor.ts
@@ -3,21 +3,20 @@
*/
import DOMPurify from 'isomorphic-dompurify';
-import {GIFTQuestion, parse} from "gift-pegjs"
-import {DwengoContentType} from "../content-type";
-import {GIFTQuestionRenderer} from "./question-renderers/gift-question-renderer";
-import {MultipleChoiceQuestionRenderer} from "./question-renderers/multiple-choice-question-renderer";
-import {CategoryQuestionRenderer} from "./question-renderers/category-question-renderer";
-import {DescriptionQuestionRenderer} from "./question-renderers/description-question-renderer";
-import {EssayQuestionRenderer} from "./question-renderers/essay-question-renderer";
-import {MatchingQuestionRenderer} from "./question-renderers/matching-question-renderer";
-import {NumericalQuestionRenderer} from "./question-renderers/numerical-question-renderer";
-import {ShortQuestionRenderer} from "./question-renderers/short-question-renderer";
-import {TrueFalseQuestionRenderer} from "./question-renderers/true-false-question-renderer";
-import {StringProcessor} from "../string-processor";
+import { GIFTQuestion, parse } from 'gift-pegjs';
+import { DwengoContentType } from '../content-type';
+import { GIFTQuestionRenderer } from './question-renderers/gift-question-renderer';
+import { MultipleChoiceQuestionRenderer } from './question-renderers/multiple-choice-question-renderer';
+import { CategoryQuestionRenderer } from './question-renderers/category-question-renderer';
+import { DescriptionQuestionRenderer } from './question-renderers/description-question-renderer';
+import { EssayQuestionRenderer } from './question-renderers/essay-question-renderer';
+import { MatchingQuestionRenderer } from './question-renderers/matching-question-renderer';
+import { NumericalQuestionRenderer } from './question-renderers/numerical-question-renderer';
+import { ShortQuestionRenderer } from './question-renderers/short-question-renderer';
+import { TrueFalseQuestionRenderer } from './question-renderers/true-false-question-renderer';
+import { StringProcessor } from '../string-processor';
class GiftProcessor extends StringProcessor {
-
private renderers: RendererMap = {
Category: new CategoryQuestionRenderer(),
Description: new DescriptionQuestionRenderer(),
@@ -26,8 +25,8 @@ class GiftProcessor extends StringProcessor {
Numerical: new NumericalQuestionRenderer(),
Short: new ShortQuestionRenderer(),
TF: new TrueFalseQuestionRenderer(),
- MC: new MultipleChoiceQuestionRenderer()
- }
+ MC: new MultipleChoiceQuestionRenderer(),
+ };
constructor() {
super(DwengoContentType.GIFT);
@@ -38,13 +37,13 @@ class GiftProcessor extends StringProcessor {
let html = "\n";
let i = 1;
- for (let question of quizQuestions) {
+ for (const question of quizQuestions) {
html += `
\n`;
- html += " " + this.renderQuestion(question, i).replaceAll(/\n(.+)/g, "\n $1"); // replace for indentation.
+ html += ' ' + this.renderQuestion(question, i).replaceAll(/\n(.+)/g, '\n $1'); // Replace for indentation.
html += `
\n`;
i++;
}
- html += "
\n"
+ html += '\n';
return DOMPurify.sanitize(html);
}
@@ -56,7 +55,7 @@ class GiftProcessor extends StringProcessor {
}
type RendererMap = {
- [K in GIFTQuestion["type"]]: GIFTQuestionRenderer>
+ [K in GIFTQuestion['type']]: GIFTQuestionRenderer>;
};
export default GiftProcessor;
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/category-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/category-question-renderer.ts
index 6f299c17..2ed79087 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/category-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/category-question-renderer.ts
@@ -1,6 +1,6 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {Category} from "gift-pegjs";
-import {ProcessingError} from "../../processing-error";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { Category } from 'gift-pegjs';
+import { ProcessingError } from '../../processing-error';
export class CategoryQuestionRenderer extends GIFTQuestionRenderer {
render(question: Category, questionNumber: number): string {
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/description-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/description-question-renderer.ts
index adea25a6..c9302e5a 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/description-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/description-question-renderer.ts
@@ -1,6 +1,6 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {Description} from "gift-pegjs";
-import {ProcessingError} from "../../processing-error";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { Description } from 'gift-pegjs';
+import { ProcessingError } from '../../processing-error';
export class DescriptionQuestionRenderer extends GIFTQuestionRenderer {
render(question: Description, questionNumber: number): string {
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/essay-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/essay-question-renderer.ts
index af000c11..ed4b1c50 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/essay-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/essay-question-renderer.ts
@@ -1,9 +1,9 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {Essay} from "gift-pegjs";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { Essay } from 'gift-pegjs';
export class EssayQuestionRenderer extends GIFTQuestionRenderer {
render(question: Essay, questionNumber: number): string {
- let renderedHtml = "";
+ let renderedHtml = '';
if (question.title) {
renderedHtml += `${question.title}
\n`;
}
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/gift-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/gift-question-renderer.ts
index bd33107b..41ab5ba2 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/gift-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/gift-question-renderer.ts
@@ -1,4 +1,4 @@
-import {GIFTQuestion} from "gift-pegjs";
+import { GIFTQuestion } from 'gift-pegjs';
/**
* Subclasses of this class are renderers which can render a specific type of GIFT questions to HTML.
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/matching-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/matching-question-renderer.ts
index 93e7511e..302f44d3 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/matching-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/matching-question-renderer.ts
@@ -1,6 +1,6 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {Matching} from "gift-pegjs";
-import {ProcessingError} from "../../processing-error";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { Matching } from 'gift-pegjs';
+import { ProcessingError } from '../../processing-error';
export class MatchingQuestionRenderer extends GIFTQuestionRenderer {
render(question: Matching, questionNumber: number): string {
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/multiple-choice-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/multiple-choice-question-renderer.ts
index 6b6d8eea..26eac034 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/multiple-choice-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/multiple-choice-question-renderer.ts
@@ -1,9 +1,9 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {MultipleChoice} from "gift-pegjs";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { MultipleChoice } from 'gift-pegjs';
export class MultipleChoiceQuestionRenderer extends GIFTQuestionRenderer {
render(question: MultipleChoice, questionNumber: number): string {
- let renderedHtml = "";
+ let renderedHtml = '';
if (question.title) {
renderedHtml += `${question.title}
\n`;
}
@@ -11,7 +11,7 @@ export class MultipleChoiceQuestionRenderer extends GIFTQuestionRenderer${question.stem.text}
\n`;
}
let i = 0;
- for (let choice of question.choices) {
+ for (const choice of question.choices) {
renderedHtml += `\n`;
renderedHtml += `
\n`;
renderedHtml += `
\n`;
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/numerical-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/numerical-question-renderer.ts
index 6553add4..65352795 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/numerical-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/numerical-question-renderer.ts
@@ -1,6 +1,6 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {Numerical} from "gift-pegjs";
-import {ProcessingError} from "../../processing-error";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { Numerical } from 'gift-pegjs';
+import { ProcessingError } from '../../processing-error';
export class NumericalQuestionRenderer extends GIFTQuestionRenderer
{
render(question: Numerical, questionNumber: number): string {
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/short-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/short-question-renderer.ts
index 96196a67..683bbc09 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/short-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/short-question-renderer.ts
@@ -1,6 +1,6 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {ShortAnswer} from "gift-pegjs";
-import {ProcessingError} from "../../processing-error";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { ShortAnswer } from 'gift-pegjs';
+import { ProcessingError } from '../../processing-error';
export class ShortQuestionRenderer extends GIFTQuestionRenderer {
render(question: ShortAnswer, questionNumber: number): string {
diff --git a/backend/src/services/learning-objects/processing/gift/question-renderers/true-false-question-renderer.ts b/backend/src/services/learning-objects/processing/gift/question-renderers/true-false-question-renderer.ts
index 0ff108f4..7f0fb9f8 100644
--- a/backend/src/services/learning-objects/processing/gift/question-renderers/true-false-question-renderer.ts
+++ b/backend/src/services/learning-objects/processing/gift/question-renderers/true-false-question-renderer.ts
@@ -1,6 +1,6 @@
-import {GIFTQuestionRenderer} from "./gift-question-renderer";
-import {TrueFalse} from "gift-pegjs";
-import {ProcessingError} from "../../processing-error";
+import { GIFTQuestionRenderer } from './gift-question-renderer';
+import { TrueFalse } from 'gift-pegjs';
+import { ProcessingError } from '../../processing-error';
export class TrueFalseQuestionRenderer extends GIFTQuestionRenderer {
render(question: TrueFalse, questionNumber: number): string {
diff --git a/backend/src/services/learning-objects/processing/image/block-image-processor.ts b/backend/src/services/learning-objects/processing/image/block-image-processor.ts
index cb488e92..f4f8a773 100644
--- a/backend/src/services/learning-objects/processing/image/block-image-processor.ts
+++ b/backend/src/services/learning-objects/processing/image/block-image-processor.ts
@@ -2,16 +2,16 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/image/block_image_processor.js
*/
-import InlineImageProcessor from "./inline-image-processor.js"
+import InlineImageProcessor from './inline-image-processor.js';
import DOMPurify from 'isomorphic-dompurify';
class BlockImageProcessor extends InlineImageProcessor {
- constructor(){
+ constructor() {
super();
}
- override renderFn(imageUrl: string){
- let inlineHtml = super.render(imageUrl);
+ override renderFn(imageUrl: string) {
+ const inlineHtml = super.render(imageUrl);
return DOMPurify.sanitize(`${inlineHtml}
`);
}
}
diff --git a/backend/src/services/learning-objects/processing/image/inline-image-processor.ts b/backend/src/services/learning-objects/processing/image/inline-image-processor.ts
index 7815fab3..8d44d1ae 100644
--- a/backend/src/services/learning-objects/processing/image/inline-image-processor.ts
+++ b/backend/src/services/learning-objects/processing/image/inline-image-processor.ts
@@ -3,10 +3,10 @@
*/
import DOMPurify from 'isomorphic-dompurify';
-import {DwengoContentType} from "../content-type.js";
-import {ProcessingError} from "../processing-error.js";
-import {isValidHttpUrl} from "../../../../util/links";
-import {StringProcessor} from "../string-processor";
+import { DwengoContentType } from '../content-type.js';
+import { ProcessingError } from '../processing-error.js';
+import { isValidHttpUrl } from '../../../../util/links';
+import { StringProcessor } from '../string-processor';
class InlineImageProcessor extends StringProcessor {
constructor(contentType: DwengoContentType = DwengoContentType.IMAGE_INLINE) {
diff --git a/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts b/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts
index 04b15b94..96710591 100644
--- a/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts
+++ b/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts
@@ -1,15 +1,15 @@
/**
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/markdown/learing_object_markdown_renderer.js [sic!]
*/
-import PdfProcessor from "../pdf/pdf-processor.js";
-import AudioProcessor from "../audio/audio-processor.js";
-import ExternProcessor from "../extern/extern-processor.js";
-import InlineImageProcessor from "../image/inline-image-processor.js";
-import * as marked from "marked";
-import {getUrlStringForLearningObjectHTML, isValidHttpUrl} from "../../../../util/links";
-import {ProcessingError} from "../processing-error";
-import {LearningObjectIdentifier} from "../../../../interfaces/learning-content";
-import {Language} from "../../../../entities/content/language";
+import PdfProcessor from '../pdf/pdf-processor.js';
+import AudioProcessor from '../audio/audio-processor.js';
+import ExternProcessor from '../extern/extern-processor.js';
+import InlineImageProcessor from '../image/inline-image-processor.js';
+import * as marked from 'marked';
+import { getUrlStringForLearningObjectHTML, isValidHttpUrl } from '../../../../util/links';
+import { ProcessingError } from '../processing-error';
+import { LearningObjectIdentifier } from '../../../../interfaces/learning-content';
+import { Language } from '../../../../entities/content/language';
import Image = marked.Tokens.Image;
import Heading = marked.Tokens.Heading;
@@ -27,11 +27,11 @@ const prefixes = {
};
function extractLearningObjectIdFromHref(href: string): LearningObjectIdentifier {
- const [hruid, language, version] = href.split(/\/(.+)/, 2)[1].split("/");
+ const [hruid, language, version] = href.split(/\/(.+)/, 2)[1].split('/');
return {
hruid,
language: language as Language,
- version: parseInt(version)
+ version: parseInt(version),
};
}
@@ -41,69 +41,69 @@ function extractLearningObjectIdFromHref(href: string): LearningObjectIdentifier
* - links to other learning objects,
* - embeddings of other learning objects.
*/
- const dwengoMarkedRenderer: RendererObject = {
+const dwengoMarkedRenderer: RendererObject = {
heading(heading: Heading): string {
const text = heading.text;
const level = heading.depth;
const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
- return `\n` +
- ` \n` +
- ` \n` +
- ` \n` +
- ` ${text}\n` +
- `\n`
+ return (
+ `\n` +
+ ` \n` +
+ ` \n` +
+ ` \n` +
+ ` ${text}\n` +
+ `\n`
+ );
},
// When the syntax for a link is used => [text](href "title")
- // render a custom link when the prefix for a learning object is used.
+ // Render a custom link when the prefix for a learning object is used.
link(link: Link): string {
const href = link.href;
- const title = link.title || "";
+ const title = link.title || '';
const text = marked.parseInline(link.text); // There could for example be an image in the link.
if (href.startsWith(prefixes.learningObject)) {
- // link to learning-object
+ // Link to learning-object
const learningObjectId = extractLearningObjectIdFromHref(href);
return `${text}`;
- } else {
- // any other link
- if (!isValidHttpUrl(href)) {
- throw new ProcessingError("Link is not a valid HTTP URL!");
- }
- //
- return `${text}`;
}
+ // Any other link
+ if (!isValidHttpUrl(href)) {
+ throw new ProcessingError('Link is not a valid HTTP URL!');
+ }
+ //
+ return `${text}`;
},
// When the syntax for an image is used => 
- // render a learning object, pdf, audio or video if a prefix is used.
+ // Render a learning object, pdf, audio or video if a prefix is used.
image(img: Image): string {
const href = img.href;
if (href.startsWith(prefixes.learningObject)) {
- // embedded learning-object
+ // Embedded learning-object
const learningObjectId = extractLearningObjectIdFromHref(href);
return `
`; // Placeholder for the learning object since we cannot fetch its HTML here (this has to be a sync function!)
} else if (href.startsWith(prefixes.pdf)) {
- // embedded pdf
- let proc = new PdfProcessor();
+ // Embedded pdf
+ const proc = new PdfProcessor();
return proc.render(href.split(/\/(.+)/, 2)[1]);
} else if (href.startsWith(prefixes.audio)) {
- // embedded audio
- let proc = new AudioProcessor();
+ // Embedded audio
+ const proc = new AudioProcessor();
return proc.render(href.split(/\/(.+)/, 2)[1]);
} else if (href.startsWith(prefixes.extern) || href.startsWith(prefixes.video) || href.startsWith(prefixes.notebook)) {
- // embedded youtube video or notebook (or other extern content)
- let proc = new ExternProcessor();
+ // Embedded youtube video or notebook (or other extern content)
+ const proc = new ExternProcessor();
return proc.render(href.split(/\/(.+)/, 2)[1]);
- } else {
- // embedded image
- let proc = new InlineImageProcessor();
- return proc.render(href)
}
+ // Embedded image
+ const proc = new InlineImageProcessor();
+ return proc.render(href);
},
-}
+};
export default dwengoMarkedRenderer;
diff --git a/backend/src/services/learning-objects/processing/markdown/markdown-processor.ts b/backend/src/services/learning-objects/processing/markdown/markdown-processor.ts
index c20f08a3..5daeceec 100644
--- a/backend/src/services/learning-objects/processing/markdown/markdown-processor.ts
+++ b/backend/src/services/learning-objects/processing/markdown/markdown-processor.ts
@@ -2,12 +2,12 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/markdown/markdown_processor.js
*/
-import {marked} from 'marked';
+import { marked } from 'marked';
import InlineImageProcessor from '../image/inline-image-processor.js';
-import {DwengoContentType} from "../content-type";
-import dwengoMarkedRenderer from "./dwengo-marked-renderer";
-import {StringProcessor} from "../string-processor";
-import {ProcessingError} from "../processing-error";
+import { DwengoContentType } from '../content-type';
+import dwengoMarkedRenderer from './dwengo-marked-renderer';
+import { StringProcessor } from '../string-processor';
+import { ProcessingError } from '../processing-error';
class MarkdownProcessor extends StringProcessor {
constructor() {
@@ -15,10 +15,10 @@ class MarkdownProcessor extends StringProcessor {
}
override renderFn(mdText: string) {
- let html = "";
+ let html = '';
try {
- marked.use({renderer: dwengoMarkedRenderer});
- html = marked(mdText, {async: false});
+ marked.use({ renderer: dwengoMarkedRenderer });
+ html = marked(mdText, { async: false });
html = this.replaceLinks(html); // Replace html image links path
} catch (e: any) {
throw new ProcessingError(e.message);
@@ -27,17 +27,11 @@ class MarkdownProcessor extends StringProcessor {
}
replaceLinks(html: string) {
- let proc = new InlineImageProcessor();
- html = html.replace(//g, (
- match: string,
- src: string,
- alt: string,
- altText: string,
- title: string,
- titleText: string
- ) => {
- return proc.render(src);
- });
+ const proc = new InlineImageProcessor();
+ html = html.replace(
+ //g,
+ (match: string, src: string, alt: string, altText: string, title: string, titleText: string) => proc.render(src)
+ );
return html;
}
}
diff --git a/backend/src/services/learning-objects/processing/pdf/pdf-processor.ts b/backend/src/services/learning-objects/processing/pdf/pdf-processor.ts
index dcb08ba7..2ebed94e 100644
--- a/backend/src/services/learning-objects/processing/pdf/pdf-processor.ts
+++ b/backend/src/services/learning-objects/processing/pdf/pdf-processor.ts
@@ -5,10 +5,10 @@
*/
import DOMPurify from 'isomorphic-dompurify';
-import {DwengoContentType} from "../content-type.js";
-import {isValidHttpUrl} from "../../../../util/links.js";
-import {ProcessingError} from "../processing-error.js";
-import {StringProcessor} from "../string-processor";
+import { DwengoContentType } from '../content-type.js';
+import { isValidHttpUrl } from '../../../../util/links.js';
+import { ProcessingError } from '../processing-error.js';
+import { StringProcessor } from '../string-processor';
class PdfProcessor extends StringProcessor {
constructor() {
@@ -20,9 +20,11 @@ class PdfProcessor extends StringProcessor {
throw new ProcessingError(`PDF URL is invalid: ${pdfUrl}`);
}
- return DOMPurify.sanitize(`
+ return DOMPurify.sanitize(
+ `
- `, { ADD_TAGS: ["embed"] }
+ `,
+ { ADD_TAGS: ['embed'] }
);
}
}
diff --git a/backend/src/services/learning-objects/processing/processing-service.ts b/backend/src/services/learning-objects/processing/processing-service.ts
index a9885718..5bdbbd9c 100644
--- a/backend/src/services/learning-objects/processing/processing-service.ts
+++ b/backend/src/services/learning-objects/processing/processing-service.ts
@@ -2,20 +2,20 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/processing_proxy.js
*/
-import BlockImageProcessor from "./image/block-image-processor.js";
-import InlineImageProcessor from "./image/inline-image-processor.js";
-import { MarkdownProcessor } from "./markdown/markdown-processor.js";
-import TextProcessor from "./text/text-processor.js";
-import AudioProcessor from "./audio/audio-processor.js";
-import PdfProcessor from "./pdf/pdf-processor.js";
-import ExternProcessor from "./extern/extern-processor.js";
-import GiftProcessor from "./gift/gift-processor.js";
-import {LearningObject} from "../../../entities/content/learning-object.entity";
-import Processor from "./processor";
-import {DwengoContentType} from "./content-type";
-import {LearningObjectIdentifier} from "../../../interfaces/learning-content";
-import {Language} from "../../../entities/content/language";
-import {replaceAsync} from "../../../util/async";
+import BlockImageProcessor from './image/block-image-processor.js';
+import InlineImageProcessor from './image/inline-image-processor.js';
+import { MarkdownProcessor } from './markdown/markdown-processor.js';
+import TextProcessor from './text/text-processor.js';
+import AudioProcessor from './audio/audio-processor.js';
+import PdfProcessor from './pdf/pdf-processor.js';
+import ExternProcessor from './extern/extern-processor.js';
+import GiftProcessor from './gift/gift-processor.js';
+import { LearningObject } from '../../../entities/content/learning-object.entity';
+import Processor from './processor';
+import { DwengoContentType } from './content-type';
+import { LearningObjectIdentifier } from '../../../interfaces/learning-content';
+import { Language } from '../../../entities/content/language';
+import { replaceAsync } from '../../../util/async';
const EMBEDDED_LEARNING_OBJECT_PLACEHOLDER = //g;
const LEARNING_OBJECT_DOES_NOT_EXIST = "";
@@ -32,12 +32,10 @@ class ProcessingService {
new AudioProcessor(),
new PdfProcessor(),
new ExternProcessor(),
- new GiftProcessor()
+ new GiftProcessor(),
];
- this.processors = new Map(
- processors.map(processor => [processor.contentType, processor])
- )
+ this.processors = new Map(processors.map((processor) => [processor.contentType, processor]));
}
/**
@@ -54,7 +52,7 @@ class ProcessingService {
learningObject: LearningObject,
fetchEmbeddedLearningObjects?: (loId: LearningObjectIdentifier) => Promise
): Promise {
- let html = this.processors.get(learningObject.contentType)!.renderLearningObject(learningObject);
+ const html = this.processors.get(learningObject.contentType)!.renderLearningObject(learningObject);
if (fetchEmbeddedLearningObjects) {
// Replace all embedded learning objects.
return replaceAsync(
@@ -65,7 +63,7 @@ class ProcessingService {
const learningObject = await fetchEmbeddedLearningObjects({
hruid,
language: language as Language,
- version: parseInt(version)
+ version: parseInt(version),
});
// If it does not exist, replace it by a placeholder.
diff --git a/backend/src/services/learning-objects/processing/processor.ts b/backend/src/services/learning-objects/processing/processor.ts
index 3e511cd9..85e11cee 100644
--- a/backend/src/services/learning-objects/processing/processor.ts
+++ b/backend/src/services/learning-objects/processing/processor.ts
@@ -1,6 +1,6 @@
-import {LearningObject} from "../../../entities/content/learning-object.entity";
-import {ProcessingError} from "./processing-error";
-import {DwengoContentType} from "./content-type";
+import { LearningObject } from '../../../entities/content/learning-object.entity';
+import { ProcessingError } from './processing-error';
+import { DwengoContentType } from './content-type';
/**
* Abstract base class for all processors.
diff --git a/backend/src/services/learning-objects/processing/string-processor.ts b/backend/src/services/learning-objects/processing/string-processor.ts
index 2026fa93..df5e6ed3 100644
--- a/backend/src/services/learning-objects/processing/string-processor.ts
+++ b/backend/src/services/learning-objects/processing/string-processor.ts
@@ -1,5 +1,5 @@
-import Processor from "./processor";
-import {LearningObject} from "../../../entities/content/learning-object.entity";
+import Processor from './processor';
+import { LearningObject } from '../../../entities/content/learning-object.entity';
export abstract class StringProcessor extends Processor {
/**
@@ -14,6 +14,6 @@ export abstract class StringProcessor extends Processor {
* @protected
*/
protected renderLearningObjectFn(toRender: LearningObject): string {
- return this.render(toRender.content.toString("ascii"));
+ return this.render(toRender.content.toString('ascii'));
}
}
diff --git a/backend/src/services/learning-objects/processing/text/text-processor.ts b/backend/src/services/learning-objects/processing/text/text-processor.ts
index fb3922a7..6b4ca248 100644
--- a/backend/src/services/learning-objects/processing/text/text-processor.ts
+++ b/backend/src/services/learning-objects/processing/text/text-processor.ts
@@ -3,8 +3,8 @@
*/
import DOMPurify from 'isomorphic-dompurify';
-import {DwengoContentType} from "../content-type.js";
-import {StringProcessor} from "../string-processor";
+import { DwengoContentType } from '../content-type.js';
+import { StringProcessor } from '../string-processor';
class TextProcessor extends StringProcessor {
constructor() {
diff --git a/backend/src/services/learning-paths/database-learning-path-provider.ts b/backend/src/services/learning-paths/database-learning-path-provider.ts
index b9fa9ff6..3b3b49af 100644
--- a/backend/src/services/learning-paths/database-learning-path-provider.ts
+++ b/backend/src/services/learning-paths/database-learning-path-provider.ts
@@ -1,19 +1,11 @@
-import {LearningPathProvider} from "./learning-path-provider";
-import {
- FilteredLearningObject,
- LearningObjectNode,
- LearningPath,
- LearningPathResponse,
- Transition
-} from "../../interfaces/learning-content";
-import {
- LearningPath as LearningPathEntity
-} from "../../entities/content/learning-path.entity"
-import {getLearningPathRepository} from "../../data/repositories";
-import {Language} from "../../entities/content/language";
-import learningObjectService from "../learning-objects/learning-object-service";
-import { LearningPathNode } from "../../entities/content/learning-path-node.entity";
-import {LearningPathTransition} from "../../entities/content/learning-path-transition.entity";
+import { LearningPathProvider } from './learning-path-provider';
+import { FilteredLearningObject, LearningObjectNode, LearningPath, LearningPathResponse, Transition } from '../../interfaces/learning-content';
+import { LearningPath as LearningPathEntity } from '../../entities/content/learning-path.entity';
+import { getLearningPathRepository } from '../../data/repositories';
+import { Language } from '../../entities/content/language';
+import learningObjectService from '../learning-objects/learning-object-service';
+import { LearningPathNode } from '../../entities/content/learning-path-node.entity';
+import { LearningPathTransition } from '../../entities/content/learning-path-transition.entity';
/**
* Fetches the corresponding learning object for each of the nodes and creates a map that maps each node to its
@@ -22,22 +14,22 @@ import {LearningPathTransition} from "../../entities/content/learning-path-trans
*/
async function getLearningObjectsForNodes(nodes: LearningPathNode[]): Promise
diff --git a/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts b/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts
index 6abc56dd..52b6adbe 100644
--- a/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts
+++ b/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts
@@ -1,9 +1,9 @@
-import {LearningObjectExample} from "../learning-object-example";
-import {LearningObject} from "../../../../src/entities/content/learning-object.entity";
-import {loadTestAsset} from "../../../test-utils/load-test-asset";
-import {EnvVars, getEnvVar} from "../../../../src/util/envvars";
-import {Language} from "../../../../src/entities/content/language";
-import {DwengoContentType} from "../../../../src/services/learning-objects/processing/content-type";
+import { LearningObjectExample } from '../learning-object-example';
+import { LearningObject } from '../../../../src/entities/content/learning-object.entity';
+import { loadTestAsset } from '../../../test-utils/load-test-asset';
+import { EnvVars, getEnvVar } from '../../../../src/util/envvars';
+import { Language } from '../../../../src/entities/content/language';
+import { DwengoContentType } from '../../../../src/services/learning-objects/processing/content-type';
const example: LearningObjectExample = {
createLearningObject: () => {
@@ -11,14 +11,14 @@ const example: LearningObjectExample = {
learningObject.hruid = `${getEnvVar(EnvVars.UserContentPrefix)}test_multiple_choice`;
learningObject.language = Language.English;
learningObject.version = 1;
- learningObject.title = "Multiple choice question for testing";
- learningObject.description = "This multiple choice question was only created for testing purposes.";
+ learningObject.title = 'Multiple choice question for testing';
+ learningObject.description = 'This multiple choice question was only created for testing purposes.';
learningObject.contentType = DwengoContentType.GIFT;
- learningObject.content = loadTestAsset("learning-objects/test-multiple-choice/content.txt");
+ learningObject.content = loadTestAsset('learning-objects/test-multiple-choice/content.txt');
return learningObject;
},
createAttachment: {},
- getHTMLRendering: () => loadTestAsset("learning-objects/test-multiple-choice/rendering.html").toString()
+ getHTMLRendering: () => loadTestAsset('learning-objects/test-multiple-choice/rendering.html').toString(),
};
export default example;
diff --git a/backend/tests/test-assets/learning-paths/learning-path-example.d.ts b/backend/tests/test-assets/learning-paths/learning-path-example.d.ts
index 47d0221f..9df3ba48 100644
--- a/backend/tests/test-assets/learning-paths/learning-path-example.d.ts
+++ b/backend/tests/test-assets/learning-paths/learning-path-example.d.ts
@@ -1,3 +1,3 @@
type LearningPathExample = {
- createLearningPath: () => LearningPath
+ createLearningPath: () => LearningPath;
};
diff --git a/backend/tests/test-assets/learning-paths/learning-path-utils.ts b/backend/tests/test-assets/learning-paths/learning-path-utils.ts
index 68c49412..c567de66 100644
--- a/backend/tests/test-assets/learning-paths/learning-path-utils.ts
+++ b/backend/tests/test-assets/learning-paths/learning-path-utils.ts
@@ -1,13 +1,13 @@
-import {Language} from "../../../src/entities/content/language";
-import {LearningPathTransition} from "../../../src/entities/content/learning-path-transition.entity";
-import {LearningPathNode} from "../../../src/entities/content/learning-path-node.entity";
-import {LearningPath} from "../../../src/entities/content/learning-path.entity";
+import { Language } from '../../../src/entities/content/language';
+import { LearningPathTransition } from '../../../src/entities/content/learning-path-transition.entity';
+import { LearningPathNode } from '../../../src/entities/content/learning-path-node.entity';
+import { LearningPath } from '../../../src/entities/content/learning-path.entity';
export function createLearningPathTransition(node: LearningPathNode, transitionNumber: number, condition: string | null, to: LearningPathNode) {
- let trans = new LearningPathTransition();
+ const trans = new LearningPathTransition();
trans.node = node;
trans.transitionNumber = transitionNumber;
- trans.condition = condition || "true";
+ trans.condition = condition || 'true';
trans.next = to;
return trans;
}
@@ -20,7 +20,7 @@ export function createLearningPathNode(
language: Language,
startNode: boolean
) {
- let node = new LearningPathNode();
+ const node = new LearningPathNode();
node.learningPath = learningPath;
node.nodeNumber = nodeNumber;
node.learningObjectHruid = learningObjectHruid;
diff --git a/backend/tests/test-assets/learning-paths/pn-werking-example.ts b/backend/tests/test-assets/learning-paths/pn-werking-example.ts
index a96de552..810b4da5 100644
--- a/backend/tests/test-assets/learning-paths/pn-werking-example.ts
+++ b/backend/tests/test-assets/learning-paths/pn-werking-example.ts
@@ -1,17 +1,17 @@
-import {LearningPath} from "../../../src/entities/content/learning-path.entity";
-import {Language} from "../../../src/entities/content/language";
-import {EnvVars, getEnvVar} from "../../../src/util/envvars";
-import {createLearningPathNode, createLearningPathTransition} from "./learning-path-utils";
-import {LearningPathNode} from "../../../src/entities/content/learning-path-node.entity";
+import { LearningPath } from '../../../src/entities/content/learning-path.entity';
+import { Language } from '../../../src/entities/content/language';
+import { EnvVars, getEnvVar } from '../../../src/util/envvars';
+import { createLearningPathNode, createLearningPathTransition } from './learning-path-utils';
+import { LearningPathNode } from '../../../src/entities/content/learning-path-node.entity';
function createNodes(learningPath: LearningPath): LearningPathNode[] {
- let nodes = [
- createLearningPathNode(learningPath, 0, "u_pn_werkingnotebooks", 3, Language.Dutch, true),
- createLearningPathNode(learningPath, 1, "pn_werkingnotebooks2", 3, Language.Dutch, false),
- createLearningPathNode(learningPath, 2, "pn_werkingnotebooks3", 3, Language.Dutch, false),
+ const nodes = [
+ createLearningPathNode(learningPath, 0, 'u_pn_werkingnotebooks', 3, Language.Dutch, true),
+ createLearningPathNode(learningPath, 1, 'pn_werkingnotebooks2', 3, Language.Dutch, false),
+ createLearningPathNode(learningPath, 2, 'pn_werkingnotebooks3', 3, Language.Dutch, false),
];
- nodes[0].transitions.push(createLearningPathTransition(nodes[0], 0, "true", nodes[1]));
- nodes[1].transitions.push(createLearningPathTransition(nodes[1], 0, "true", nodes[2]));
+ nodes[0].transitions.push(createLearningPathTransition(nodes[0], 0, 'true', nodes[1]));
+ nodes[1].transitions.push(createLearningPathTransition(nodes[1], 0, 'true', nodes[2]));
return nodes;
}
@@ -20,11 +20,11 @@ const example: LearningPathExample = {
const path = new LearningPath();
path.language = Language.Dutch;
path.hruid = `${getEnvVar(EnvVars.UserContentPrefix)}pn_werking`;
- path.title = "Werken met notebooks";
- path.description = "Een korte inleiding tot Python notebooks. Hoe ga je gemakkelijk en efficiënt met de notebooks aan de slag?";
+ path.title = 'Werken met notebooks';
+ path.description = 'Een korte inleiding tot Python notebooks. Hoe ga je gemakkelijk en efficiënt met de notebooks aan de slag?';
path.nodes = createNodes(path);
return path;
- }
-}
+ },
+};
export default example;
diff --git a/backend/tests/test-assets/learning-paths/test-conditions-example.ts b/backend/tests/test-assets/learning-paths/test-conditions-example.ts
index 000bb732..b6cf3e9d 100644
--- a/backend/tests/test-assets/learning-paths/test-conditions-example.ts
+++ b/backend/tests/test-assets/learning-paths/test-conditions-example.ts
@@ -1,23 +1,27 @@
-import {LearningPath} from "../../../src/entities/content/learning-path.entity";
-import {Language} from "../../../src/entities/content/language";
-import testMultipleChoiceExample from "../learning-objects/test-multiple-choice/test-multiple-choice-example";
-import {dummyLearningObject} from "../learning-objects/dummy/dummy-learning-object-example";
-import {createLearningPathNode, createLearningPathTransition} from "./learning-path-utils";
+import { LearningPath } from '../../../src/entities/content/learning-path.entity';
+import { Language } from '../../../src/entities/content/language';
+import testMultipleChoiceExample from '../learning-objects/test-multiple-choice/test-multiple-choice-example';
+import { dummyLearningObject } from '../learning-objects/dummy/dummy-learning-object-example';
+import { createLearningPathNode, createLearningPathTransition } from './learning-path-utils';
const example: LearningPathExample = {
createLearningPath: () => {
const learningPath = new LearningPath();
- learningPath.hruid = "test_conditions";
+ learningPath.hruid = 'test_conditions';
learningPath.language = Language.English;
- learningPath.title = "Example learning path with conditional transitions";
- learningPath.description = "This learning path was made for the purpose of testing conditional transitions";
+ learningPath.title = 'Example learning path with conditional transitions';
+ learningPath.description = 'This learning path was made for the purpose of testing conditional transitions';
const branchingLearningObject = testMultipleChoiceExample.createLearningObject();
const extraExerciseLearningObject = dummyLearningObject(
- "test_extra_exercise", Language.English, "Extra exercise (for students with difficulties)"
+ 'test_extra_exercise',
+ Language.English,
+ 'Extra exercise (for students with difficulties)'
).createLearningObject();
const finalLearningObject = dummyLearningObject(
- "test_final_learning_object", Language.English, "Final exercise (for everyone)"
+ 'test_final_learning_object',
+ Language.English,
+ 'Final exercise (for everyone)'
).createLearningObject();
const branchingNode = createLearningPathNode(
@@ -48,21 +52,11 @@ const example: LearningPathExample = {
const transitionToExtraExercise = createLearningPathTransition(
branchingNode,
0,
- "$[?(@[0] == 0)]", // The answer to the first question was the first one, which says that it is difficult for the student to follow along.
+ '$[?(@[0] == 0)]', // The answer to the first question was the first one, which says that it is difficult for the student to follow along.
extraExerciseNode
);
- const directTransitionToFinal = createLearningPathTransition(
- branchingNode,
- 1,
- "$[?(@[0] == 1)]",
- finalNode
- );
- const transitionExtraExerciseToFinal = createLearningPathTransition(
- extraExerciseNode,
- 0,
- "true",
- finalNode
- );
+ const directTransitionToFinal = createLearningPathTransition(branchingNode, 1, '$[?(@[0] == 1)]', finalNode);
+ const transitionExtraExerciseToFinal = createLearningPathTransition(extraExerciseNode, 0, 'true', finalNode);
branchingNode.transitions = [transitionToExtraExercise, directTransitionToFinal];
extraExerciseNode.transitions = [transitionExtraExerciseToFinal];
@@ -70,5 +64,5 @@ const example: LearningPathExample = {
learningPath.nodes = [branchingNode, extraExerciseNode, finalNode];
return learningPath;
- }
+ },
};
diff --git a/backend/tests/test-utils/expectations.ts b/backend/tests/test-utils/expectations.ts
index e8e70845..f9fe2c68 100644
--- a/backend/tests/test-utils/expectations.ts
+++ b/backend/tests/test-utils/expectations.ts
@@ -1,63 +1,62 @@
-import {AssertionError} from "node:assert";
-import {LearningObject} from "../../src/entities/content/learning-object.entity";
-import {FilteredLearningObject, LearningPath} from "../../src/interfaces/learning-content";
-import {LearningPath as LearningPathEntity} from "../../src/entities/content/learning-path.entity"
-import { expect } from "vitest";
+import { AssertionError } from 'node:assert';
+import { LearningObject } from '../../src/entities/content/learning-object.entity';
+import { FilteredLearningObject, LearningPath } from '../../src/interfaces/learning-content';
+import { LearningPath as LearningPathEntity } from '../../src/entities/content/learning-path.entity';
+import { expect } from 'vitest';
// Ignored properties because they belang for example to the class, not to the entity itself.
-const IGNORE_PROPERTIES = ["parent"];
+const IGNORE_PROPERTIES = ['parent'];
/**
* Checks if the actual entity from the database conforms to the entity that was added previously.
* @param actual The actual entity retrieved from the database
* @param expected The (previously added) entity we would expect to retrieve
*/
-export function expectToBeCorrectEntity(
- actual: {entity: T, name?: string},
- expected: {entity: T, name?: string}
-): void {
+export function expectToBeCorrectEntity(actual: { entity: T; name?: string }, expected: { entity: T; name?: string }): void {
if (!actual.name) {
- actual.name = "actual";
+ actual.name = 'actual';
}
if (!expected.name) {
- expected.name = "expected";
+ expected.name = 'expected';
}
- for (let property in expected.entity) {
+ for (const property in expected.entity) {
if (
- property !in IGNORE_PROPERTIES
- && expected.entity[property] !== undefined // If we don't expect a certain value for a property, we assume it can be filled in by the database however it wants.
- && typeof expected.entity[property] !== "function" // Functions obviously are not persisted via the database
+ property! in IGNORE_PROPERTIES &&
+ expected.entity[property] !== undefined && // If we don't expect a certain value for a property, we assume it can be filled in by the database however it wants.
+ typeof expected.entity[property] !== 'function' // Functions obviously are not persisted via the database
) {
if (!actual.entity.hasOwnProperty(property)) {
throw new AssertionError({
- message: `${expected.name} has defined property ${property}, but ${actual.name} is missing it.`
+ message: `${expected.name} has defined property ${property}, but ${actual.name} is missing it.`,
});
}
- if (typeof expected.entity[property] === "boolean") { // Sometimes, booleans get represented by numbers 0 and 1 in the objects actual from the database.
- if (!!expected.entity[property] !== !!actual.entity[property]) {
+ if (typeof expected.entity[property] === 'boolean') {
+ // Sometimes, booleans get represented by numbers 0 and 1 in the objects actual from the database.
+ if (Boolean(expected.entity[property]) !== Boolean(actual.entity[property])) {
throw new AssertionError({
message: `${property} was ${expected.entity[property]} in ${expected.name},
- but ${actual.entity[property]} (${!!expected.entity[property]}) in ${actual.name}`
+ but ${actual.entity[property]} (${Boolean(expected.entity[property])}) in ${actual.name}`,
});
}
} else if (typeof expected.entity[property] !== typeof actual.entity[property]) {
throw new AssertionError({
- message: `${property} has type ${typeof expected.entity[property]} in ${expected.name}, but type ${typeof actual.entity[property]} in ${actual.name}.`
+ message: `${property} has type ${typeof expected.entity[property]} in ${expected.name}, but type ${typeof actual.entity[property]} in ${actual.name}.`,
});
- } else if (typeof expected.entity[property] === "object") {
+ } else if (typeof expected.entity[property] === 'object') {
expectToBeCorrectEntity(
{
- name: actual.name + "." + property,
- entity: actual.entity[property] as object
- }, {
- name: expected.name + "." + property,
- entity: expected.entity[property] as object
+ name: actual.name + '.' + property,
+ entity: actual.entity[property] as object,
+ },
+ {
+ name: expected.name + '.' + property,
+ entity: expected.entity[property] as object,
}
);
} else {
if (expected.entity[property] !== actual.entity[property]) {
throw new AssertionError({
- message: `${property} was ${expected.entity[property]} in ${expected.name}, but ${actual.entity[property]} in ${actual.name}`
+ message: `${property} was ${expected.entity[property]} in ${expected.name}, but ${actual.entity[property]} in ${actual.name}`,
});
}
}
@@ -78,7 +77,7 @@ export function expectToBeCorrectFilteredLearningObject(filtered: FilteredLearni
expect(filtered.key).toEqual(original.hruid);
expect(filtered.targetAges).toEqual(original.targetAges);
expect(filtered.title).toEqual(original.title);
- expect(!!filtered.teacherExclusive).toEqual(!!original.teacherExclusive) // !!: Workaround: MikroORM with SQLite returns 0 and 1 instead of booleans.
+ expect(Boolean(filtered.teacherExclusive)).toEqual(original.teacherExclusive); // !!: Workaround: MikroORM with SQLite returns 0 and 1 instead of booleans.
expect(filtered.skosConcepts).toEqual(original.skosConcepts);
expect(filtered.estimatedTime).toEqual(original.estimatedTime);
expect(filtered.educationalGoals).toEqual(original.educationalGoals);
@@ -112,10 +111,10 @@ export function expectToBeCorrectLearningPath(
expect(learningPath.description).toEqual(expectedEntity.description);
expect(learningPath.title).toEqual(expectedEntity.title);
- const keywords = new Set(learningObjectsOnPath.flatMap(it => it.keywords || []));
- expect(new Set(learningPath.keywords.split(' '))).toEqual(keywords)
+ const keywords = new Set(learningObjectsOnPath.flatMap((it) => it.keywords || []));
+ expect(new Set(learningPath.keywords.split(' '))).toEqual(keywords);
- const targetAges = new Set(learningObjectsOnPath.flatMap(it => it.targetAges || []));
+ const targetAges = new Set(learningObjectsOnPath.flatMap((it) => it.targetAges || []));
expect(new Set(learningPath.target_ages)).toEqual(targetAges);
expect(learningPath.min_age).toEqual(Math.min(...targetAges));
expect(learningPath.max_age).toEqual(Math.max(...targetAges));
@@ -123,42 +122,29 @@ export function expectToBeCorrectLearningPath(
expect(learningPath.num_nodes).toEqual(expectedEntity.nodes.length);
expect(learningPath.image || null).toEqual(expectedEntity.image);
- let expectedLearningPathNodes = new Map(
- expectedEntity.nodes.map(node => [
- {learningObjectHruid: node.learningObjectHruid, language: node.language, version: node.version},
- {startNode: node.startNode, transitions: node.transitions}
+ const expectedLearningPathNodes = new Map(
+ expectedEntity.nodes.map((node) => [
+ { learningObjectHruid: node.learningObjectHruid, language: node.language, version: node.version },
+ { startNode: node.startNode, transitions: node.transitions },
])
);
- for (let node of learningPath.nodes) {
+ for (const node of learningPath.nodes) {
const nodeKey = {
learningObjectHruid: node.learningobject_hruid,
language: node.language,
- version: node.version
+ version: node.version,
};
expect(expectedLearningPathNodes.keys()).toContainEqual(nodeKey);
- let expectedNode = [...expectedLearningPathNodes.entries()]
- .filter(([key, _]) =>
- key.learningObjectHruid === nodeKey.learningObjectHruid
- && key.language === node.language
- && key.version === node.version
- )[0][1]
+ const expectedNode = [...expectedLearningPathNodes.entries()].filter(
+ ([key, _]) => key.learningObjectHruid === nodeKey.learningObjectHruid && key.language === node.language && key.version === node.version
+ )[0][1];
expect(node.start_node).toEqual(expectedNode?.startNode);
- expect(
- new Set(node.transitions.map(it => it.next.hruid))
- ).toEqual(
- new Set(expectedNode.transitions.map(it => it.next.learningObjectHruid))
- );
- expect(
- new Set(node.transitions.map(it => it.next.language))
- ).toEqual(
- new Set(expectedNode.transitions.map(it => it.next.language))
- );
- expect(
- new Set(node.transitions.map(it => it.next.version))
- ).toEqual(
- new Set(expectedNode.transitions.map(it => it.next.version))
+ expect(new Set(node.transitions.map((it) => it.next.hruid))).toEqual(
+ new Set(expectedNode.transitions.map((it) => it.next.learningObjectHruid))
);
+ expect(new Set(node.transitions.map((it) => it.next.language))).toEqual(new Set(expectedNode.transitions.map((it) => it.next.language)));
+ expect(new Set(node.transitions.map((it) => it.next.version))).toEqual(new Set(expectedNode.transitions.map((it) => it.next.version)));
}
}
diff --git a/backend/tests/test-utils/load-test-asset.ts b/backend/tests/test-utils/load-test-asset.ts
index effa0c73..35f6cdbf 100644
--- a/backend/tests/test-utils/load-test-asset.ts
+++ b/backend/tests/test-utils/load-test-asset.ts
@@ -1,5 +1,5 @@
-import fs from "fs";
-import path from "node:path";
+import fs from 'fs';
+import path from 'node:path';
/**
* Load the asset at the given path.