63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
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";
|
|
|
|
/**
|
|
* Process an uploaded zip file and construct a LearningObject from its contents.
|
|
* @param filePath Path of the zip file to process.
|
|
*/
|
|
export async function processLearningObjectZip(filePath: string): Promise<LearningObject> {
|
|
const learningObjectRepo = getLearningObjectRepository();
|
|
const attachmentRepo = getAttachmentRepository();
|
|
|
|
const zip = await unzipper.Open.file(filePath);
|
|
|
|
let metadata: LearningObjectMetadata | null = null;
|
|
const attachments: {name: string, content: Buffer}[] = [];
|
|
let content: Buffer | null = null;
|
|
|
|
for (const file of zip.files) {
|
|
if (file.type === "Directory") {
|
|
throw Error("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.")) {
|
|
content = await processFile(file);
|
|
} else {
|
|
attachments.push({
|
|
name: file.path,
|
|
content: await processFile(file)
|
|
});
|
|
}
|
|
}
|
|
|
|
if (!metadata) {
|
|
throw Error("Missing metadata.json file");
|
|
}
|
|
if (!content) {
|
|
throw Error("Missing index file");
|
|
}
|
|
|
|
const learningObject = learningObjectRepo.create(metadata);
|
|
const attachmentEntities = attachments.map(it => attachmentRepo.create({
|
|
name: it.name,
|
|
content: it.content,
|
|
mimeType: mime.lookup(it.name) || "text/plain",
|
|
learningObject
|
|
}))
|
|
learningObject.attachments.push(...attachmentEntities);
|
|
|
|
return learningObject;
|
|
}
|
|
|
|
async function processMetadataJson(file: unzipper.File): LearningObjectMetadata {
|
|
const buf = await file.buffer();
|
|
const content = buf.toString();
|
|
return JSON.parse(content);
|
|
}
|
|
|
|
async function processFile(file: unzipper.File): Promise<Buffer> {
|
|
return await file.buffer();
|
|
}
|