feat(backend): Controller en route voor het aanmaken van leerobjecten aangemaakt.
This commit is contained in:
parent
86ba4ea11e
commit
78353d6b65
6 changed files with 81 additions and 6 deletions
|
@ -31,6 +31,7 @@
|
|||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^5.0.1",
|
||||
"express-fileupload": "^1.5.1",
|
||||
"express-jwt": "^8.5.1",
|
||||
"gift-pegjs": "^1.0.2",
|
||||
"isomorphic-dompurify": "^2.22.0",
|
||||
|
@ -51,6 +52,7 @@
|
|||
"@mikro-orm/cli": "6.4.12",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/express-fileupload": "^1.5.1",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^22.13.4",
|
||||
"@types/response-time": "^2.3.8",
|
||||
|
|
|
@ -7,6 +7,7 @@ import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
|||
import { NotFoundException } from '../exceptions/not-found-exception.js';
|
||||
import { envVars, getEnvVar } from '../util/envVars.js';
|
||||
import { FilteredLearningObject, LearningObjectIdentifierDTO, LearningPathIdentifier } from '@dwengo-1/common/interfaces/learning-content';
|
||||
import {UploadedFile} from "express-fileupload";
|
||||
|
||||
function getLearningObjectIdentifierFromRequest(req: Request): LearningObjectIdentifierDTO {
|
||||
if (!req.params.hruid) {
|
||||
|
@ -72,3 +73,10 @@ export async function getAttachment(req: Request, res: Response): Promise<void>
|
|||
}
|
||||
res.setHeader('Content-Type', attachment.mimeType).send(attachment.content);
|
||||
}
|
||||
|
||||
export async function handlePostLearningObject(req: Request, res: Response): Promise<void> {
|
||||
if (!req.files || !req.files[0]) {
|
||||
throw new BadRequestException('No file uploaded');
|
||||
}
|
||||
await learningObjectService.storeLearningObject((req.files[0] as UploadedFile).tempFilePath);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
import express from 'express';
|
||||
import { getAllLearningObjects, getAttachment, getLearningObject, getLearningObjectHTML } from '../controllers/learning-objects.js';
|
||||
import {
|
||||
getAllLearningObjects,
|
||||
getAttachment,
|
||||
getLearningObject,
|
||||
getLearningObjectHTML,
|
||||
handlePostLearningObject
|
||||
} from '../controllers/learning-objects.js';
|
||||
|
||||
import submissionRoutes from './submissions.js';
|
||||
import questionRoutes from './questions.js';
|
||||
import fileUpload from "express-fileupload";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
|
@ -18,6 +25,8 @@ const router = express.Router();
|
|||
// Example 2: http://localhost:3000/learningObject?full=true&hruid=un_artificiele_intelligentie
|
||||
router.get('/', getAllLearningObjects);
|
||||
|
||||
router.post('/', fileUpload({useTempFiles: true}), handlePostLearningObject)
|
||||
|
||||
// Parameter: hruid of learning object
|
||||
// Query: language
|
||||
// Route to fetch data of one learning object based on its hruid
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from '@dwengo-1/common/interfaces/learning-content';
|
||||
import {getLearningObjectRepository} from "../../data/repositories";
|
||||
import {processLearningObjectZip} from "./learning-object-zip-processing-service";
|
||||
import {BadRequestException} from "../../exceptions/bad-request-exception";
|
||||
|
||||
function getProvider(id: LearningObjectIdentifierDTO): LearningObjectProvider {
|
||||
if (id.hruid.startsWith(getEnvVar(envVars.UserContentPrefix))) {
|
||||
|
@ -58,7 +59,7 @@ const learningObjectService = {
|
|||
const learningObject = await processLearningObjectZip(learningObjectPath);
|
||||
|
||||
if (!learningObject.hruid.startsWith(getEnvVar(envVars.UserContentPrefix))) {
|
||||
throw Error("Learning object name must start with the user content prefix!");
|
||||
throw new BadRequestException("Learning object name must start with the user content prefix!");
|
||||
}
|
||||
|
||||
await learningObjectRepository.save(learningObject, {preventOverwrite: true});
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import unzipper from 'unzipper';
|
||||
import mime from 'mime-types';
|
||||
import {LearningObjectMetadata} from "@dwengo-1/common/dist/interfaces/learning-content";
|
||||
import {LearningObject} from "../../entities/content/learning-object.entity";
|
||||
import {getAttachmentRepository, getLearningObjectRepository} from "../../data/repositories";
|
||||
import {BadRequestException} from "../../exceptions/bad-request-exception";
|
||||
import {LearningObjectMetadata} from "@dwengo-1/common/dist/interfaces/learning-content";
|
||||
|
||||
/**
|
||||
* Process an uploaded zip file and construct a LearningObject from its contents.
|
||||
|
@ -20,7 +21,7 @@ export async function processLearningObjectZip(filePath: string): Promise<Learni
|
|||
|
||||
for (const file of zip.files) {
|
||||
if (file.type === "Directory") {
|
||||
throw Error("The learning object zip file should not contain directories.");
|
||||
throw new BadRequestException("The learning object zip file should not contain directories.");
|
||||
} else if (file.path === "metadata.json") {
|
||||
metadata = await processMetadataJson(file);
|
||||
} else if (file.path.startsWith("index.")) {
|
||||
|
@ -34,10 +35,10 @@ export async function processLearningObjectZip(filePath: string): Promise<Learni
|
|||
}
|
||||
|
||||
if (!metadata) {
|
||||
throw Error("Missing metadata.json file");
|
||||
throw new BadRequestException("Missing metadata.json file");
|
||||
}
|
||||
if (!content) {
|
||||
throw Error("Missing index file");
|
||||
throw new BadRequestException("Missing index file");
|
||||
}
|
||||
|
||||
const learningObject = learningObjectRepo.create(metadata);
|
||||
|
|
54
package-lock.json
generated
54
package-lock.json
generated
|
@ -44,6 +44,7 @@
|
|||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^5.0.1",
|
||||
"express-fileupload": "^1.5.1",
|
||||
"express-jwt": "^8.5.1",
|
||||
"gift-pegjs": "^1.0.2",
|
||||
"isomorphic-dompurify": "^2.22.0",
|
||||
|
@ -64,6 +65,7 @@
|
|||
"@mikro-orm/cli": "6.4.12",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/express-fileupload": "^1.5.1",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^22.13.4",
|
||||
"@types/response-time": "^2.3.8",
|
||||
|
@ -1639,6 +1641,16 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/busboy": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.4.tgz",
|
||||
"integrity": "sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.38",
|
||||
"license": "MIT",
|
||||
|
@ -1673,6 +1685,17 @@
|
|||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express-fileupload": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.5.1.tgz",
|
||||
"integrity": "sha512-DllImBVI1lCyjl2klky/TEwk60mbNebgXv1669h66g9TfptWSrEFq5a/raHSutaFzjSm1tmn9ypdNfu4jPSixQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/busboy": "*",
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express-serve-static-core": {
|
||||
"version": "5.0.6",
|
||||
"dev": true,
|
||||
|
@ -2857,6 +2880,17 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||
"dependencies": {
|
||||
"streamsearch": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"license": "MIT",
|
||||
|
@ -4235,6 +4269,18 @@
|
|||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/express-fileupload": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.5.1.tgz",
|
||||
"integrity": "sha512-LsYG1ALXEB7vlmjuSw8ABeOctMp8a31aUC5ZF55zuz7O2jLFnmJYrCv10py357ky48aEoBQ/9bVXgFynjvaPmA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"busboy": "^1.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express-jwt": {
|
||||
"version": "8.5.1",
|
||||
"license": "MIT",
|
||||
|
@ -7798,6 +7844,14 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/streamsearch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"license": "MIT",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue