/**
 * Small utility functions that don't need to be part of the main API class
 */ import { Semester } from '../types/modules' ; import { Cache } from '../types/persist' ; import rootLogger , { Logger } from '../services/logger' ; /**
 * Construct the 4 number term code from the academic year and semester
 */ export function getTermCode ( semester , academicYear ) { const year = /\d\d(\d\d)/ . exec ( academicYear ) ; if ( ! year ) throw new RangeError ( 'academicYear should be in the format of YYYY/YYYY or YYYY-YY' ) ; return `${ year [ 1 ] }${ semester }0` ; } /**
 * Extract the academic year and semester from a term code
 */ export function fromTermCode ( term ) { const year = parseInt ( term . slice ( 0 , 2 ) , 10 ) ; const semester = parseInt ( term . charAt ( 2 ) , 10 ) ; return [ `20${ year }/20${ year + 1 }` , semester ] ; } /**
 * Cache and return download if it succeeds, otherwise return cached data if
 * it has not expired yet
 */ export async function cacheDownload < T > ( name , download , cache , logger = rootLogger ) { try { const data = await download ( ) ; try { await cache . write ( data ) ; } catch ( err ) { logger . warn ( { err , path : cache . path } , 'Failed to cache data' ) ; } return data ; } catch ( downloadError ) { logger . warn ( downloadError , `Cannot load ${ name } from API, attempting to read from cache` ) ; try { return await cache . read ( ) ; } catch ( cacheError ) { throw downloadError ; } } } /**
 * Retries the given promise
 */ export async function retry < T > ( promiseFactory , maxRetries , retryIf = ( ) => true ) { try { return await promiseFactory ( ) ; } catch ( e ) { if ( maxRetries <= 1 || ! retryIf ( e ) ) throw e ; return retry ( promiseFactory , maxRetries - 1 , retryIf ) ; } } /**
 * Returns true if `desc` has >3 consecutive non-breaking spaces without spaces
 * between them.
 *
 * Intended to catch cases where someone unintentially used NBSPs instead of
 * regular spaces, while still allowing intentional uses of NBSPs. The >3
 * consecutive criterion is just a simple good-enough heuristic.
 */ export function containsNbsps ( desc ) { return new RegExp ( /\u00A0[^ ]*\u00A0[^ ]*\u00A0/ ) . test ( desc ) ; }