chore: lint-format-docs-tests-bugfixes (#105)

* docs: add jsdoc

* feat: change enums to as const objects

* chore(test): add themeColors.test.ts

* fix: fix tests and bugs with strings.ts util

* fix: path alias imports and tsconfig file bug

* fix: remove --max-warnings 0
This commit is contained in:
doprz
2024-02-22 22:42:58 -06:00
parent 8ab60c9f01
commit 8a6e9070e0
134 changed files with 986 additions and 623 deletions

View File

@@ -1,39 +1,44 @@
import { Course, InstructionMode, ScrapedRow, Semester, Status } from '@shared/types/Course';
import type { InstructionMode, ScrapedRow, Semester } from '@shared/types/Course';
import { Course, Status } from '@shared/types/Course';
import { CourseSchedule } from '@shared/types/CourseSchedule';
import Instructor from '@shared/types/Instructor';
import { SiteSupport } from '@views/lib/getSiteSupport';
import type { SiteSupportType } from '@views/lib/getSiteSupport';
/**
* The selectors that we use to scrape the course catalog list table (https://utdirect.utexas.edu/apps/registrar/course_schedule/20239/results/?fos_fl=C+S&level=U&search_type_main=FIELD)
*/
enum TableDataSelector {
COURSE_HEADER = 'td.course_header',
UNIQUE_ID = 'td[data-th="Unique"]',
REGISTER_URL = 'td[data-th="Add"] a',
INSTRUCTORS = 'td[data-th="Instructor"] span',
INSTRUCTION_MODE = 'td[data-th="Instruction Mode"]',
STATUS = 'td[data-th="Status"]',
SCHEDULE_DAYS = 'td[data-th="Days"]>span',
SCHEDULE_HOURS = 'td[data-th="Hour"]>span',
SCHEDULE_LOCATION = 'td[data-th="Room"]>span',
FLAGS = 'td[data-th="Flags"] ul li',
}
const TableDataSelector = {
COURSE_HEADER: 'td.course_header',
UNIQUE_ID: 'td[data-th="Unique"]',
REGISTER_URL: 'td[data-th="Add"] a',
INSTRUCTORS: 'td[data-th="Instructor"] span',
INSTRUCTION_MODE: 'td[data-th="Instruction Mode"]',
STATUS: 'td[data-th="Status"]',
SCHEDULE_DAYS: 'td[data-th="Days"]>span',
SCHEDULE_HOURS: 'td[data-th="Hour"]>span',
SCHEDULE_LOCATION: 'td[data-th="Room"]>span',
FLAGS: 'td[data-th="Flags"] ul li',
} as const;
type TableDataSelectorType = (typeof TableDataSelector)[keyof typeof TableDataSelector];
/**
* The selectors that we use to scrape the course details page for an individual course (https://utdirect.utexas.edu/apps/registrar/course_schedule/20239/52700/)
*/
enum DetailsSelector {
COURSE_NAME = '#details h2',
COURSE_DESCRIPTION = '#details p',
}
const DetailsSelector = {
COURSE_NAME: '#details h2',
COURSE_DESCRIPTION: '#details p',
} as const;
type DetailsSelectorType = (typeof DetailsSelector)[keyof typeof DetailsSelector];
/**
* A class that allows us to scrape information from UT's course catalog to create our internal representation of a course
*/
export class CourseCatalogScraper {
support: SiteSupport;
support: SiteSupportType;
constructor(support: SiteSupport) {
constructor(support: SiteSupportType) {
this.support = support;
}

View File

@@ -1,6 +1,5 @@
import initSqlJs from 'sql.js/dist/sql-wasm';
import DB_FILE_URL from '@public/database/grades.db?url';
import initSqlJs from 'sql.js/dist/sql-wasm';
import WASM_FILE_URL from 'sql.js/dist/sql-wasm.wasm?url';
// import WASM_FILE_URL from '../../../../public/database/sql-wasm.wasm?url';

View File

@@ -1,5 +1,6 @@
import { Course, Semester } from '@shared/types/Course';
import { CourseSQLRow, Distribution } from '@shared/types/Distribution';
import type { Course, Semester } from '@shared/types/Course';
import type { CourseSQLRow, Distribution } from '@shared/types/Distribution';
import { initializeDB } from './initializeDB';
/**

View File

@@ -4,21 +4,27 @@ import { isExtensionPage, isExtensionPopup } from 'chrome-extension-toolkit';
* An enum that represents the different types of pages that we support
* a given url/page can correspond to many of these enum values
*/
export enum SiteSupport {
COURSE_CATALOG_LIST = 'COURSE_CATALOG_LIST',
COURSE_CATALOG_DETAILS = 'COURSE_CATALOG_DETAILS',
UT_PLANNER = 'UT_PLANNER',
WAITLIST = 'WAITLIST',
EXTENSION_POPUP = 'EXTENSION_POPUP',
MY_CALENDAR = 'MY_CALENDAR',
}
export const SiteSupport = {
COURSE_CATALOG_LIST: 'COURSE_CATALOG_LIST',
COURSE_CATALOG_DETAILS: 'COURSE_CATALOG_DETAILS',
UT_PLANNER: 'UT_PLANNER',
WAITLIST: 'WAITLIST',
EXTENSION_POPUP: 'EXTENSION_POPUP',
MY_CALENDAR: 'MY_CALENDAR',
} as const;
/**
* Represents the type of SiteSupport.
* It is a union type that includes all the values of the SiteSupport object.
*/
export type SiteSupportType = (typeof SiteSupport)[keyof typeof SiteSupport];
/**
* We use this function to determine what page the user is on, and then we can use that information to determine what to do
* @param url the url of the current page
* @returns a list of page types that the current page is
*/
export default function getSiteSupport(url: string): SiteSupport | null {
export default function getSiteSupport(url: string): SiteSupportType | null {
if (isExtensionPopup()) {
return SiteSupport.EXTENSION_POPUP;
}

View File

@@ -2,15 +2,22 @@ import getCourseTableRows from './getCourseTableRows';
const NEXT_PAGE_BUTTON_SELECTOR = '#next_nav_link';
const PREV_PAGE_BUTTON_SELECTOR = '#prev_nav_link';
/**
* Represents all the states that we care about when autoloading the next page of courses
*/
export enum AutoLoadStatus {
LOADING = 'LOADING',
IDLE = 'IDLE',
ERROR = 'ERROR',
DONE = 'DONE',
}
export const AutoLoadStatus = {
LOADING: 'LOADING',
IDLE: 'IDLE',
ERROR: 'ERROR',
DONE: 'DONE',
} as const;
/**
* Represents the type of the auto load status.
* It is a union type that includes all the values of the AutoLoadStatus object.
*/
export type AutoLoadStatusType = (typeof AutoLoadStatus)[keyof typeof AutoLoadStatus];
let isLoading = false;
let nextPageURL = getNextButton(document)?.href;
@@ -22,7 +29,7 @@ let nextPageURL = getNextButton(document)?.href;
* or if there was an error loading the next page) and an array of the table rows from the next page (or an empty array
* if we have reached the end of the course catalog
*/
export async function loadNextCourseCatalogPage(): Promise<[AutoLoadStatus, HTMLTableRowElement[]]> {
export async function loadNextCourseCatalogPage(): Promise<[AutoLoadStatusType, HTMLTableRowElement[]]> {
// if there is no more nextPageURL, then we have reached the end of the course catalog, so we can stop
if (!nextPageURL) {
return [AutoLoadStatus.DONE, []];

View File

@@ -1,25 +1,28 @@
import { createMessenger } from "chrome-extension-toolkit";
import { createMessenger } from 'chrome-extension-toolkit';
type MyMessages = {
openNewTab: {
data: { url: string };
data: { url: string };
};
};
};
const messenger = createMessenger<MyMessages>('background');
/**
* Content scripts and background scripts are isolated environments.
/**
* Content scripts and background scripts are isolated environments.
* Content scripts are where our code interacting with the webpage lives,
* whereas the background script is where we can open a tab from.
* This function allows us to open a new tab from the content script by communicating
* with the background script.
* This function allows us to open a new tab from the content script by communicating
* with the background script.
*/
export async function openTabFromContentScript(url: string) {
// @ts-ignore
messenger.openNewTab({ url }).then(() => {
console.log('New tab opened with URL:', url);
}).catch((error) => {
console.error('Error opening new tab:', error);
});
messenger
.openNewTab({ url })
.then(() => {
console.log('New tab opened with URL:', url);
})
.catch(error => {
console.error('Error opening new tab:', error);
});
}

View File

@@ -1,4 +1,3 @@
/**
* The course schedule page has a search form that allows users to search for courses by department and course level.
* The problem is that once the user triggers a search and refreshes the page,

View File

@@ -1,6 +1,12 @@
import React from 'react';
import type React from 'react';
import ReactDOM from 'react-dom/client';
/**
* Renders a React element into a container.
* @param element - The React element to render.
* @param container - The container element where the React element will be rendered.
* @throws Error if the container is null.
*/
export default function render(element: React.ReactElement, container: HTMLElement | ShadowRoot | null) {
if (!container) {
throw new Error('Container is null');