fix: lint + format

This commit is contained in:
Gabriellvl 2025-02-28 17:21:03 +01:00
parent ac778981e2
commit acfffda82d
8 changed files with 162 additions and 118 deletions

View file

@ -1,9 +1,8 @@
import express, { Express, Response } from 'express'; import express, { Express, Response } from 'express';
import initORM from './orm.js'; import initORM from './orm.js';
import themeRoutes from './routes/themes.js'; import themeRoutes from './routes/themes.js';
import learningPathRoutes from './routes/learningPaths.js' import learningPathRoutes from './routes/learningPaths.js';
import learningObjectRoutes from './routes/learningObjects.js' import learningObjectRoutes from './routes/learningObjects.js';
const app: Express = express(); const app: Express = express();
const port: string | number = process.env.PORT || 3000; const port: string | number = process.env.PORT || 3000;

View file

@ -1,9 +1,8 @@
// Can be placed in dotenv but found it redundant // Can be placed in dotenv but found it redundant
// import dotenv from "dotenv"; // Import dotenv from "dotenv";
// Load .env file // Load .env file
// dotenv.config(); // Dotenv.config();
export const DWENGO_API_BASE = "https://dwengo.org/backend/api";
export const DWENGO_API_BASE = 'https://dwengo.org/backend/api';

View file

@ -1,20 +1,28 @@
import { Request, Response } from "express"; import { Request, Response } from 'express';
import { getLearningObjectsFromPath } from "../services/learningObjects.js"; import { getLearningObjectsFromPath } from '../services/learningObjects.js';
export async function getAllLearningObjects(req: Request, res: Response): Promise<void> { export async function getAllLearningObjects(
req: Request,
res: Response
): Promise<void> {
try { try {
const { hruid } = req.params; const { hruid } = req.params;
const language = req.query.language as string || "nl"; // Default to Dutch; const language = (req.query.language as string) || 'nl'; // Default to Dutch;
if (!language) { if (!language) {
res.status(400).json({ error: "Language query parameter is required." }); res.status(400).json({
error: 'Language query parameter is required.',
});
return; return;
} }
const learningObjects = await getLearningObjectsFromPath(hruid, language); const learningObjects = await getLearningObjectsFromPath(
hruid,
language
);
res.json(learningObjects); res.json(learningObjects);
} catch (error) { } catch (error) {
console.error("Error fetching learning objects:", error); console.error('Error fetching learning objects:', error);
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
} }

View file

@ -1,19 +1,24 @@
import { Request, Response } from "express"; import { Request, Response } from 'express';
import axios from "axios"; import axios from 'axios';
import { themes } from "../data/themes.js"; import { themes } from '../data/themes.js';
import { DWENGO_API_BASE } from "../config/config.js"; import { DWENGO_API_BASE } from '../config/config.js';
/** /**
* Fetch learning paths for a given list of HRUIDs. * Fetch learning paths for a given list of HRUIDs.
* This function sends a request to the Dwengo API with the provided HRUIDs. * This function sends a request to the Dwengo API with the provided HRUIDs.
*/ */
export async function getLearningPathsFromIds(req: Request, res: Response): Promise<void> { export async function getLearningPathsFromIds(
req: Request,
res: Response
): Promise<void> {
try { try {
const { hruids } = req.query; const { hruids } = req.query;
const language = (req.query.language as string) || "nl"; // Default to Dutch const language = (req.query.language as string) || 'nl'; // Default to Dutch
if (!hruids) { if (!hruids) {
res.status(400).json({ error: "Missing required parameter: hruids" }); res.status(400).json({
error: 'Missing required parameter: hruids',
});
return; return;
} }
@ -21,17 +26,20 @@ export async function getLearningPathsFromIds(req: Request, res: Response): Prom
const hruidList = Array.isArray(hruids) ? hruids : [hruids]; const hruidList = Array.isArray(hruids) ? hruids : [hruids];
// Request learning paths from Dwengo API // Request learning paths from Dwengo API
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`, { const response = await axios.get(
`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`,
{
params: { params: {
pathIdList: JSON.stringify({ hruids: hruidList }), pathIdList: JSON.stringify({ hruids: hruidList }),
language language,
},
} }
}); );
res.json(response.data); res.json(response.data);
} catch (error) { } catch (error) {
console.error("Error fetching learning paths:", error); console.error('Error fetching learning paths:', error);
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
} }
@ -40,16 +48,21 @@ export async function getLearningPathsFromIds(req: Request, res: Response): Prom
* First retrieves the HRUIDs associated with the theme, * First retrieves the HRUIDs associated with the theme,
* then fetches the corresponding learning paths from the Dwengo API. * then fetches the corresponding learning paths from the Dwengo API.
*/ */
export async function getLearningPathsByTheme(req: Request, res: Response): Promise<void> { export async function getLearningPathsByTheme(
req: Request,
res: Response
): Promise<void> {
try { try {
const themeKey = req.params.theme; const themeKey = req.params.theme;
const language = (req.query.language as string) || "nl"; // Default to Dutch const language = (req.query.language as string) || 'nl'; // Default to Dutch
// Find the theme by its title // Find the theme by its title
const theme = themes.find((t) => t.title === themeKey); const theme = themes.find((t) => {
return t.title === themeKey;
});
if (!theme) { if (!theme) {
res.status(404).json({ error: "Theme not found" }); res.status(404).json({ error: 'Theme not found' });
return; return;
} }
@ -57,69 +70,85 @@ export async function getLearningPathsByTheme(req: Request, res: Response): Prom
const hruidList = theme.hruids; const hruidList = theme.hruids;
// Request learning paths from Dwengo API using the extracted HRUIDs // Request learning paths from Dwengo API using the extracted HRUIDs
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`, { const response = await axios.get(
`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`,
{
params: { params: {
pathIdList: JSON.stringify({ hruids: hruidList }), pathIdList: JSON.stringify({ hruids: hruidList }),
language language,
},
} }
}); );
res.json({ res.json({
theme: themeKey, theme: themeKey,
hruids: hruidList, hruids: hruidList,
learningPaths: response.data learningPaths: response.data,
}); });
} catch (error) { } catch (error) {
console.error("Error fetching learning paths for theme:", error); console.error('Error fetching learning paths for theme:', error);
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
} }
export async function searchLearningPaths(req: Request, res: Response): Promise<void> { export async function searchLearningPaths(
req: Request,
res: Response
): Promise<void> {
try { try {
const query = req.query.query as string; const query = req.query.query as string;
const language = (req.query.language as string) || "nl"; const language = (req.query.language as string) || 'nl';
if (!query) { if (!query) {
res.status(400).json({ error: "Missing search query" }); res.status(400).json({ error: 'Missing search query' });
return; return;
} }
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/search`, { const response = await axios.get(
params: { all: query, language } `${DWENGO_API_BASE}/learningPath/search`,
}); {
params: { all: query, language },
}
);
res.json(response.data); res.json(response.data);
} catch (error) { } catch (error) {
console.error("Error searching learning paths:", error); console.error('Error searching learning paths:', error);
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
} }
export async function getAllLearningPaths(req: Request, res: Response): Promise<void> { export async function getAllLearningPaths(
req: Request,
res: Response
): Promise<void> {
try { try {
const language = (req.query.language as string) || "nl"; // Default to Dutch const language = (req.query.language as string) || 'nl'; // Default to Dutch
// Collect all HRUIDs from all themes // Collect all HRUIDs from all themes
const allHruids: string[] = themes.flatMap(theme => theme.hruids); const allHruids: string[] = themes.flatMap((theme) => {
return theme.hruids;
});
if (allHruids.length === 0) { if (allHruids.length === 0) {
res.status(404).json({ error: "No HRUIDs found in themes" }); res.status(404).json({ error: 'No HRUIDs found in themes' });
return; return;
} }
// Call the Dwengo API with all HRUIDs combined // Call the Dwengo API with all HRUIDs combined
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`, { const response = await axios.get(
`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`,
{
params: { params: {
pathIdList: JSON.stringify({ hruids: allHruids }), pathIdList: JSON.stringify({ hruids: allHruids }),
language language,
},
} }
}); );
res.json(response.data); res.json(response.data);
} catch (error) { } catch (error) {
console.error("Error fetching all learning paths:", error); console.error('Error fetching all learning paths:', error);
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: 'Internal server error' });
} }
} }

View file

@ -1,11 +1,11 @@
import express from "express"; import express from 'express';
import { getAllLearningObjects } from "../controllers/learningObjects.js"; import { getAllLearningObjects } from '../controllers/learningObjects.js';
const router = express.Router(); const router = express.Router();
// arg: hruid learningPath // Arg: hruid learningPath
// query: language // Query: language
// Route to fetch list of learning objects based on hruid of learning path // Route to fetch list of learning objects based on hruid of learning path
router.get("/:hruid", getAllLearningObjects); router.get('/:hruid', getAllLearningObjects);
export default router; export default router;

View file

@ -1,23 +1,28 @@
import express from "express"; import express from 'express';
import { getLearningPathsFromIds, getLearningPathsByTheme, getAllLearningPaths, searchLearningPaths } from "../controllers/learningPaths.js"; import {
getLearningPathsFromIds,
getLearningPathsByTheme,
getAllLearningPaths,
searchLearningPaths,
} from '../controllers/learningPaths.js';
const router = express.Router(); const router = express.Router();
// query: language // Query: language
// Route to fetch learning paths based on a list of HRUIDs // Route to fetch learning paths based on a list of HRUIDs
router.get("/", getLearningPathsFromIds); router.get('/', getLearningPathsFromIds);
// query: language // Query: language
// Route to fetch all possible learning paths // Route to fetch all possible learning paths
router.get("/all", getAllLearningPaths); router.get('/all', getAllLearningPaths);
// query: language // Query: language
// Route to fetch learning paths based on a searchterm // Route to fetch learning paths based on a searchterm
router.get("/search", searchLearningPaths); router.get('/search', searchLearningPaths);
// arg: theme id // Arg: theme id
// query: language // Query: language
// Route to fetch learning paths based on a theme // Route to fetch learning paths based on a theme
router.get("/theme/:theme", getLearningPathsByTheme); router.get('/theme/:theme', getLearningPathsByTheme);
export default router; export default router;

View file

@ -3,11 +3,11 @@ import { getThemes, getThemeByTitle } from '../controllers/themes.js';
const router = express.Router(); const router = express.Router();
// query: language // Query: language
// Route to fetch list of {key, title, description, image} themes in their respective language // Route to fetch list of {key, title, description, image} themes in their respective language
router.get('/', getThemes); router.get('/', getThemes);
// arg: theme (key) // Arg: theme (key)
// Route to fetch list of hruids based on theme // Route to fetch list of hruids based on theme
router.get('/:theme', getThemeByTitle); router.get('/:theme', getThemeByTitle);

View file

@ -1,5 +1,5 @@
import axios from "axios"; import axios from 'axios';
import { DWENGO_API_BASE } from "../config/config.js"; import { DWENGO_API_BASE } from '../config/config.js';
interface LearningObjectNode { interface LearningObjectNode {
_id: string; _id: string;
@ -8,15 +8,47 @@ interface LearningObjectNode {
language: string; language: string;
} }
function filterLearningObjectMetadata(data: any, htmlUrl: string) {
return {
key: data.hruid,
// Hruid learningObject (not path)
_id: data._id,
uuid: data.uuid,
version: data.version,
export async function getLearningObjectsFromPath(hruid: string, language: string) { title: data.title,
html_url: htmlUrl,
// Html content object
language: data.language,
difficulty: data.difficulty,
estimated_time: data.estimated_time,
available: data.available,
teacher_exclusive: data.teacher_exclusive,
educational_goals: data.educational_goals,
// List with learningObjects
keywords: data.keywords,
// For search
description: data.description,
// For search (not an actual description)
target_ages: data.target_ages,
// Skos concepts needed ??
// Content type needed ??
// Content location ??
};
}
export async function getLearningObjectsFromPath(
hruid: string,
language: string
) {
try { try {
const learningPathUrl = `${DWENGO_API_BASE}/learningPath/${hruid}/${language}`; const learningPathUrl = `${DWENGO_API_BASE}/learningPath/${hruid}/${language}`;
const learningPathResponse = await axios.get(learningPathUrl); const learningPathResponse = await axios.get(learningPathUrl);
const nodes = learningPathResponse.data.nodes; const nodes = learningPathResponse.data.nodes;
if (!nodes || nodes.length === 0) { if (!nodes || nodes.length === 0) {
throw new Error("No learning objects found in this learning path."); throw new Error('No learning objects found in this learning path.');
} }
return await Promise.all( return await Promise.all(
@ -24,44 +56,16 @@ export async function getLearningObjectsFromPath(hruid: string, language: string
const metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata?hruid=${node.learningobject_hruid}&version=${node.version}&language=${language}`; const metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata?hruid=${node.learningobject_hruid}&version=${node.version}&language=${language}`;
const metadataResponse = await axios.get(metadataUrl); const metadataResponse = await axios.get(metadataUrl);
const html_url = `${DWENGO_API_BASE}/learningObject/getRaw?hruid=${node.learningobject_hruid}&version=${node.version}&language=${language}`; const htmlUrl = `${DWENGO_API_BASE}/learningObject/getRaw?hruid=${node.learningobject_hruid}&version=${node.version}&language=${language}`;
return filterLearningObjectMetadata(metadataResponse.data, html_url); return filterLearningObjectMetadata(
metadataResponse.data,
htmlUrl
);
}) })
); );
} catch (error) { } catch (error) {
console.error("Error fetching learning objects:", error); console.error('Error fetching learning objects:', error);
throw new Error("Failed to fetch learning objects."); throw new Error('Failed to fetch learning objects.');
} }
} }
function filterLearningObjectMetadata(data: any, html_url: String) {
return {
key: data.hruid,
// hruid learningObject (not path)
_id: data._id,
uuid: data.uuid,
version: data.version,
title: data.title,
html_url,
// html content object
language: data.language,
difficulty: data.difficulty,
estimated_time: data.estimated_time,
available: data.available,
teacher_exclusive: data.teacher_exclusive,
educational_goals: data.educational_goals,
// list with learningObjects
keywords: data.keywords,
// for search
description: data.description,
// for search (not an actual description)
target_ages: data.target_ages,
// skos concepts needed ??
// content type needed ??
// content location ??
};
}