From e9888e3f954b29f43522693d0e9b8ef750cb59e0 Mon Sep 17 00:00:00 2001 From: Harrison Date: Thu, 26 May 2022 17:26:37 +0100 Subject: [PATCH] attendance filtering & meta responses --- src/baseClient.ts | 36 +++++++++++++++++++++++++++++------- src/types.ts | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/baseClient.ts b/src/baseClient.ts index fab6ded..ba004d8 100644 --- a/src/baseClient.ts +++ b/src/baseClient.ts @@ -3,11 +3,15 @@ import type { AxiosRequestConfig, AxiosInstance } from "axios"; import type { ActivityResponse, AnnouncementsResponse, + AttendanceDate, AttendanceResponse, + AttendanceScheme, BadgesResponse, BehaviourResponse, DetentionsResponse, + ErrorResponse, GetActivityOptions, + GetAttendanceOptions, GetBehaviourOptions, GetFullActivityOptions, GetHomeworkOptions, @@ -15,7 +19,9 @@ import type { Homework, HomeworksResponse, LessonsResponse, + ResponseFormat, Student, + SuccessResponse, } from "./types"; /** * The base client @@ -35,9 +41,17 @@ export class ClasschartsClient { this.API_BASE = API_BASE; this.axios = axios.create(axiosConfig); } + /** + * Utilising Axios to create authenticated requests to endpoints which have not yet been incorporated + * @param {string} path URL Endpoint to make request to + * @param {AxiosRequestConfig} options Set optional parameters for Axios Request + * @param {boolean} includeMeta Boolean to determine if the meta property is included in the response + * @returns {object | SuccessResponse} If includeMeta is false, will return standard data object + */ public async makeAuthedRequest( path: string, - options: Omit + options: Omit, + includeMeta?: boolean, ) { if (!this.authCookies) throw new Error("Not authenticated"); const requestOptions: AxiosRequestConfig = { @@ -51,11 +65,14 @@ export class ClasschartsClient { validateStatus: () => true, }; const request = await this.axios.request(requestOptions); - const responseJSON = request.data; + const responseJSON: ResponseFormat = request.data; if (responseJSON.success == 0) { - throw new Error(responseJSON.error); + const err: ErrorResponse = responseJSON; + throw new Error(err.error); } - return responseJSON.data; + const data = responseJSON.data, meta = responseJSON.meta; + const res: SuccessResponse = { data, meta }; + return includeMeta ? res : data; } /** @@ -219,14 +236,19 @@ export class ClasschartsClient { } /** * Gets the logged in student's attendance + * @param options GetAttendanceOptions * @returns Array of dates of attendance */ - async listAttendance(): Promise { + async listAttendance(options?: GetAttendanceOptions): Promise { + const params = new URLSearchParams(); + options?.from && params.append("from", String(options?.from)); + options?.to && params.append("to", String(options?.to)); return await this.makeAuthedRequest( - this.API_BASE + "/attendance/" + this.studentId, + this.API_BASE + "/attendance/" + this.studentId + '?' + params.toString(), { method: "GET", - } + }, + true ); } } diff --git a/src/types.ts b/src/types.ts index 8363f01..b9696e9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,14 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +export interface ResponseFormat { + success?: number; + expired?: number; + error?: string; + data: Record | Array | any; + meta: Record | Array | any; +} +export type SuccessResponse = Pick; +export type ErrorResponse = Omit; + export interface Student { id: number; name: string; @@ -310,18 +320,36 @@ export interface GetFullActivityOptions { */ to: string; } - +export interface AttendanceMeta { + dates: Array; + end_date: string; + percentage: string; + percentage_singe_august: string; + sessions: Array; + start_date: string; +} +export interface GetAttendanceOptions { + /** + * From date, in format YYYY-MM-DD + */ + from: string; + /** + * To date, in format YYYY-MM-DD + */ + to: string; +} +export type AttendanceStatus = "present" | "ignore" | "absent" | "excused"; export interface AttendanceDate { AM: { code: string; - status: "present" | "ignore"; + status: AttendanceStatus; late_minutes: number; }; PM: { code: string; - status: "present" | "ignore"; + status: AttendanceStatus; late_minutes: number; }; } - +export type AttendanceScheme = { data: AttendanceDate; meta: AttendanceMeta }; export type AttendanceResponse = Array>; \ No newline at end of file