Merge branch 'dev' into refactor/common

This commit is contained in:
Tibo De Peuter 2025-04-01 21:38:50 +02:00
commit a4408b5bc0
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
145 changed files with 3437 additions and 2822 deletions

View file

@ -1,5 +1,6 @@
import axios, { AxiosRequestConfig } from 'axios';
import { getLogger, Logger } from '../logging/initalize.js';
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
const logger: Logger = getLogger();
@ -17,8 +18,8 @@ export async function fetchWithLogging<T>(
url: string,
description: string,
options?: {
params?: Record<string, any>;
query?: Record<string, any>;
params?: Record<string, unknown> | LearningObjectIdentifier;
query?: Record<string, unknown>;
responseType?: 'json' | 'text';
}
): Promise<T | null> {
@ -26,18 +27,21 @@ export async function fetchWithLogging<T>(
const config: AxiosRequestConfig = options || {};
const response = await axios.get<T>(url, config);
return response.data;
} catch (error: any) {
if (error.response) {
if (error.response.status === 404) {
logger.debug(`❌ ERROR: ${description} not found (404) at "${url}".`);
} catch (error: unknown) {
if (axios.isAxiosError(error)) {
if (error.response) {
if (error.response.status === 404) {
logger.debug(`❌ ERROR: ${description} not found (404) at "${url}".`);
} else {
logger.debug(
`❌ ERROR: Failed to fetch ${description}. Status: ${error.response.status} - ${error.response.statusText} (URL: "${url}")`
);
}
} else {
logger.debug(
`❌ ERROR: Failed to fetch ${description}. Status: ${error.response.status} - ${error.response.statusText} (URL: "${url}")`
);
logger.debug(`❌ ERROR: Network or unexpected error when fetching ${description}:`, error.message);
}
} else {
logger.debug(`❌ ERROR: Network or unexpected error when fetching ${description}:`, error.message);
}
logger.error(`❌ ERROR: Unknown error while fetching ${description}.`, error);
return null;
}
}

View file

@ -6,7 +6,11 @@
* @param regex
* @param replacementFn
*/
export async function replaceAsync(str: string, regex: RegExp, replacementFn: (match: string, ...args: string[]) => Promise<string>) {
export async function replaceAsync(
str: string,
regex: RegExp,
replacementFn: (match: string, ...args: string[]) => Promise<string>
): Promise<string> {
const promises: Promise<string>[] = [];
// First run through matches: add all Promises resulting from the replacement function

View file

@ -6,9 +6,13 @@ const TEACHER_IDP_PREFIX = IDP_PREFIX + 'TEACHER_';
const CORS_PREFIX = PREFIX + 'CORS_';
const LOGGING_PREFIX = PREFIX + 'LOGGING_';
type EnvVar = { key: string; required?: boolean; defaultValue?: any };
interface EnvVar {
key: string;
required?: boolean;
defaultValue?: number | string | boolean;
}
export const EnvVars: { [key: string]: EnvVar } = {
export const envVars: Record<string, EnvVar> = {
Port: { key: PREFIX + 'PORT', defaultValue: 3000 },
LearningContentRepoApiBaseUrl: { key: PREFIX + 'LEARNING_CONTENT_REPO_API_BASE_URL', defaultValue: 'https://dwengo.org/backend/api' },
FallbackLanguage: { key: PREFIX + 'FALLBACK_LANGUAGE', defaultValue: 'nl' },
@ -52,7 +56,7 @@ export function getEnvVar(envVar: EnvVar): string {
} else if (envVar.required) {
throw new Error(`Missing environment variable: ${envVar.key}`);
} else {
return envVar.defaultValue || '';
return String(envVar.defaultValue) || '';
}
}

View file

@ -4,12 +4,12 @@ export function isValidHttpUrl(url: string): boolean {
try {
const parsedUrl = new URL(url, 'http://test.be');
return parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:';
} catch (e) {
} catch (_) {
return false;
}
}
export function getUrlStringForLearningObject(learningObjectId: LearningObjectIdentifier) {
export function getUrlStringForLearningObject(learningObjectId: LearningObjectIdentifier): string {
let url = `/learningObject/${learningObjectId.hruid}/html?language=${learningObjectId.language}`;
if (learningObjectId.version) {
url += `&version=${learningObjectId.version}`;