From 0801d3aae0b3f9bfb98fe746d7c1666c06690baa Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 31 Jan 2022 22:32:29 +0000 Subject: [PATCH] style: prettier --- .prettierignore | 3 + .prettierrc.json | 1 + package.json | 19 +-- pnpm-lock.yaml | 170 +++++++++++++--------- readme.md | 30 ++-- src/client.ts | 360 +++++++++++++++++++++++------------------------ src/consts.ts | 4 +- src/index.ts | 2 +- src/types.ts | 250 ++++++++++++++++---------------- tsconfig.json | 182 ++++++++++++------------ 10 files changed, 529 insertions(+), 492 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc.json diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..40af9dc --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +dist +docs +node_modules \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1 @@ +{} diff --git a/package.json b/package.json index aaa90b4..e45ea97 100644 --- a/package.json +++ b/package.json @@ -7,24 +7,25 @@ }, "main": "./dist/index.js", "scripts": { - "prepare": "npm run build", "build": "tsc", - "generateDocs": "pnpm typedoc --entryPointStrategy expand ./src", - "test": "echo TEST" + "generateDocs": "pnpm typedoc --entryPointStrategy expand ./src" }, "author": "", "license": "ISC", "dependencies": { - "undici": "^4.11.3" + "undici": "^4.13.0" }, "files": [ "dist/**" ], "devDependencies": { - "@types/node": "^16.11.12", - "dotenv": "^10.0.0", - "typedoc": "^0.22.10", - "typescript": "^4.5.3" + "@types/node": "^17.0.13", + "prettier": "^2.5.1", + "typedoc": "^0.22.11", + "typescript": "^4.5.5" }, - "types": "./dist/index.d.ts" + "types": "./dist/index.d.ts", + "volta": { + "node": "16.13.2" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ac98eb..6dbc8ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,53 +1,59 @@ lockfileVersion: 5.3 specifiers: - '@types/node': ^16.11.12 - dotenv: ^10.0.0 - typedoc: ^0.22.10 - typescript: ^4.5.3 - undici: ^4.11.3 + "@types/node": ^17.0.13 + prettier: ^2.5.1 + typedoc: ^0.22.11 + typescript: ^4.5.5 + undici: ^4.13.0 dependencies: - undici: 4.11.3 + undici: 4.13.0 devDependencies: - '@types/node': 16.11.12 - dotenv: 10.0.0 - typedoc: 0.22.10_typescript@4.5.3 - typescript: 4.5.3 + "@types/node": 17.0.13 + prettier: 2.5.1 + typedoc: 0.22.11_typescript@4.5.5 + typescript: 4.5.5 packages: - - /@types/node/16.11.12: - resolution: {integrity: sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==} + /@types/node/17.0.13: + resolution: + { + integrity: sha512-Y86MAxASe25hNzlDbsviXl8jQHb0RDvKt4c40ZJQ1Don0AAL0STLZSs4N+6gLEO55pedy7r2cLwS+ZDxPm/2Bw==, + } dev: true /balanced-match/1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } dev: true /brace-expansion/1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 dev: true /concat-map/0.0.1: - resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} - dev: true - - /dotenv/10.0.0: - resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} - engines: {node: '>=10'} + resolution: { integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= } dev: true /fs.realpath/1.0.0: - resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} + resolution: { integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8= } dev: true /glob/7.2.0: - resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + resolution: + { + integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==, + } dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -58,101 +64,131 @@ packages: dev: true /inflight/1.0.6: - resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} + resolution: { integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= } dependencies: once: 1.4.0 wrappy: 1.0.2 dev: true /inherits/2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } dev: true /jsonc-parser/3.0.0: - resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==} - dev: true - - /lru-cache/5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 + resolution: + { + integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==, + } dev: true /lunr/2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + resolution: + { + integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==, + } dev: true - /marked/3.0.8: - resolution: {integrity: sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw==} - engines: {node: '>= 12'} + /marked/4.0.12: + resolution: + { + integrity: sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==, + } + engines: { node: ">= 12" } hasBin: true dev: true /minimatch/3.0.4: - resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} + resolution: + { + integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==, + } dependencies: brace-expansion: 1.1.11 dev: true /once/1.4.0: - resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} + resolution: { integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E= } dependencies: wrappy: 1.0.2 dev: true - /onigasm/2.2.5: - resolution: {integrity: sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==} - dependencies: - lru-cache: 5.1.1 - dev: true - /path-is-absolute/1.0.1: - resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} - engines: {node: '>=0.10.0'} + resolution: { integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18= } + engines: { node: ">=0.10.0" } dev: true - /shiki/0.9.12: - resolution: {integrity: sha512-VXcROdldv0/Qu0w2XvzU4IrvTeBNs/Kj/FCmtcEXGz7Tic/veQzliJj6tEiAgoKianhQstpYmbPDStHU5Opqcw==} + /prettier/2.5.1: + resolution: + { + integrity: sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==, + } + engines: { node: ">=10.13.0" } + hasBin: true + dev: true + + /shiki/0.10.0: + resolution: + { + integrity: sha512-iczxaIYeBFHTFrQPb9DVy2SKgYxC4Wo7Iucm7C17cCh2Ge/refnvHscUOxM85u57MfLoNOtjoEFUWt9gBexblA==, + } dependencies: jsonc-parser: 3.0.0 - onigasm: 2.2.5 + vscode-oniguruma: 1.6.1 vscode-textmate: 5.2.0 dev: true - /typedoc/0.22.10_typescript@4.5.3: - resolution: {integrity: sha512-hQYZ4WtoMZ61wDC6w10kxA42+jclWngdmztNZsDvIz7BMJg7F2xnT+uYsUa7OluyKossdFj9E9Ye4QOZKTy8SA==} - engines: {node: '>= 12.10.0'} + /typedoc/0.22.11_typescript@4.5.5: + resolution: + { + integrity: sha512-pVr3hh6dkS3lPPaZz1fNpvcrqLdtEvXmXayN55czlamSgvEjh+57GUqfhAI1Xsuu/hNHUT1KNSx8LH2wBP/7SA==, + } + engines: { node: ">= 12.10.0" } hasBin: true peerDependencies: typescript: 4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x dependencies: glob: 7.2.0 lunr: 2.3.9 - marked: 3.0.8 + marked: 4.0.12 minimatch: 3.0.4 - shiki: 0.9.12 - typescript: 4.5.3 + shiki: 0.10.0 + typescript: 4.5.5 dev: true - /typescript/4.5.3: - resolution: {integrity: sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==} - engines: {node: '>=4.2.0'} + /typescript/4.5.5: + resolution: + { + integrity: sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==, + } + engines: { node: ">=4.2.0" } hasBin: true dev: true - /undici/4.11.3: - resolution: {integrity: sha512-bLOCH2juB9gAkqE4a4zb+eMGhI8XD4SH1tF9Qu9J3Y8TA379Xxg7lWRMiDvc36pRWV1z9/HICv05fXkeeLw1Dg==} - engines: {node: '>=12.18'} + /undici/4.13.0: + resolution: + { + integrity: sha512-8lk8S/f2V0VUNGf2scU2b+KI2JSzEQLdCyRNRF3XmHu+5jectlSDaPSBCXAHFaUlt1rzngzOBVDgJS9/Gue/KA==, + } + engines: { node: ">=12.18" } dev: false + /vscode-oniguruma/1.6.1: + resolution: + { + integrity: sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==, + } + dev: true + /vscode-textmate/5.2.0: - resolution: {integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==} + resolution: + { + integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==, + } dev: true /wrappy/1.0.2: - resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} - dev: true - - /yallist/3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + resolution: { integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= } dev: true diff --git a/readme.md b/readme.md index 8cfb4e6..9b12b7c 100644 --- a/readme.md +++ b/readme.md @@ -7,22 +7,22 @@ A very WIP client for the classcharts API # Examples ```typescript -import { ClasschartsClient } from 'classcharts-api' +import { ClasschartsClient } from "classcharts-api"; async function main() { - const client = new ClasschartsClient('classchartsCode', '01/1/2000') - await client.init() - console.log( - await client.getBehaviour({ - displayDate: 'due_date', - fromDate: '20/01/2000', - toDate: '01/02/2000', - }) - ) - console.log(await client.getActivity()) - console.log(await client.getStudentInfo()) - console.log(await client.getActivity()) - console.log(await client.getActivity()) + const client = new ClasschartsClient("classchartsCode", "01/1/2000"); + await client.init(); + console.log( + await client.getBehaviour({ + displayDate: "due_date", + fromDate: "20/01/2000", + toDate: "01/02/2000", + }) + ); + console.log(await client.getActivity()); + console.log(await client.getStudentInfo()); + console.log(await client.getActivity()); + console.log(await client.getActivity()); } -main() +main(); ``` diff --git a/src/client.ts b/src/client.ts index 8aac63c..958f168 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,188 +1,184 @@ -import Undici from 'undici' -import { RequestOptions } from 'undici/types/dispatcher' +import Undici from "undici"; +import { RequestOptions } from "undici/types/dispatcher"; import { - ActivityResponse, - BehaviourResponse, - GetActivityOptions, - GetBehaviourOptions, - GetHomeworkOptions, - GetLessonsOptions, - Homework, - HomeworksResponse, - LessonsResponse, - Student, -} from './types' -import { API_BASE, BASE_URL } from './consts' + ActivityResponse, + BehaviourResponse, + GetActivityOptions, + GetBehaviourOptions, + GetHomeworkOptions, + GetLessonsOptions, + Homework, + HomeworksResponse, + LessonsResponse, + Student, +} from "./types"; +import { API_BASE, BASE_URL } from "./consts"; /** * The base client */ export class ClasschartsClient { - public studentCode = '' - public dateOfBirth = '' - public studentId = 0 - public studentName = '' - private authCookies: Array | undefined - private sessionId = '' - /** - * - * @param studentCode Classcharts student code - * @param dateOfBirth Student's date of birth - */ - constructor(studentCode: string, dateOfBirth?: string) { - this.studentCode = String(studentCode) - this.dateOfBirth = String(dateOfBirth) - } - public async makeAuthedRequest( - path: string, - options: Omit - ) { - if (!this.authCookies) throw new Error('Not authenticated') - const requestOptions: Omit = { - ...options, - headers: { - Cookie: this.authCookies.join(';'), - authorization: 'Basic ' + this.sessionId, - }, - } - const request = await Undici.request(path, requestOptions) - let responseJSON - try { - responseJSON = await request.body.json() - } catch (err) { - throw new Error('Invalid JSON response, check your dates') - } - if (responseJSON.success == 0) { - throw new Error(responseJSON.error) - } - return responseJSON.data - } - /** - * Initialises the client and authenticates with classcharts - */ - async init(): Promise { - if (!this.studentCode) throw new Error('Student Code not inputted') - const formData = new URLSearchParams() - formData.append('_method', 'POST') - formData.append('code', this.studentCode.toUpperCase()) - formData.append('dob', this.dateOfBirth) - formData.append('remember_me', '1') - formData.append('recaptcha-token', 'no-token-avaliable') - const request = await Undici.request(BASE_URL + '/student/login', { - method: 'POST', - body: formData.toString(), - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }) - if (request.statusCode != 302 || !request.headers['set-cookie']) - throw new Error('Unauthenticated: Classcharts returned an error') - let cookies = request.headers['set-cookie'] - for (let i = 0; i < cookies.length; i++) { - cookies[i] = cookies[i].substring(0, cookies[i].indexOf(';')) - } - this.authCookies = cookies - let sessionID: any = decodeURI(cookies[2]) - .replace(/%3A/g, ':') - .replace(/%2C/g, ',') - sessionID = JSON.parse( - sessionID.substring(sessionID.indexOf('{'), sessionID.length) - ) - this.sessionId = sessionID.session_id - const user = await this.getStudentInfo() - this.studentId = user.id - this.studentName = user.name - } - /** - * Gets general information about the logged in student - * @returns Student object - */ - async getStudentInfo(): Promise { - const data = await this.makeAuthedRequest(API_BASE + '/ping', { - method: 'POST', - body: 'include_date=true', - }) - return data?.user - } - /** - * Get's the logged in student's general activity - * @param options GetActivityOptions - * @returns Activity data - */ - async getActivity( - options?: GetActivityOptions - ): Promise { - const params = new URLSearchParams() - options?.from && params.append('form', options?.from) - options?.to && params.append('to', options?.to) - return this.makeAuthedRequest( - API_BASE + '/activity/' + this.sessionId + '?' + params.toString(), - { - method: 'GET', - } - ) - } - /** - * Gets the logged in students behaviour points - * @param options GetBehaviourOptions - * @returns Array of behaviour points - */ - async getBehaviour( - options?: GetBehaviourOptions - ): Promise { - const params = new URLSearchParams() - options?.from && params.append('form', options?.from) - options?.to && params.append('to', options?.to) - options?.last_id && params.append('last_id', options?.last_id) - return await this.makeAuthedRequest( - API_BASE + '/behaviour/' + this.studentId + '?' + params.toString(), - { - method: 'GET', - } - ) - } - /** - * Gets a list of the logged in student's homeworks - * @param options GetHomeworkOptions - * @returns Array of homeworks - */ - async listHomeworks( - options?: GetHomeworkOptions - ): Promise { - const params = new URLSearchParams() - if (options?.displayDate) params.append('display_date', String(options?.displayDate)) - options?.fromDate && params.append('from', String(options?.fromDate)) - options?.toDate && params.append('to', String(options?.toDate)) - let data: Array = await this.makeAuthedRequest( - API_BASE + '/homeworks/' + this.studentId + '?' + params.toString(), - { - method: 'GET', - } - ) - for (let i = 0; i < data.length; i++) { - // homework.lesson.replace(/\\/g, '') - data[i].description = data[i].description.replace( - /(<([^>]+)>)/gi, - '' - ) - data[i].description = data[i].description.replace(/ /g, '') - data[i].description = data[i].description.trim() - } - return data - } - /** - * Gets the logged in student's lessons for a day - * @param options GetLessonsOptions - * @returns Array of lessons - */ - async getLessons(options?: GetLessonsOptions): Promise { - if (!options?.date) throw new Error('No date specified') - const params = new URLSearchParams() - params.append('date', String(options?.date)) - return await this.makeAuthedRequest( - API_BASE + '/timetable/' + this.studentId + '?' + params.toString(), - { - method: 'GET', - } - ) - } + public studentCode = ""; + public dateOfBirth = ""; + public studentId = 0; + public studentName = ""; + private authCookies: Array | undefined; + private sessionId = ""; + /** + * + * @param studentCode Classcharts student code + * @param dateOfBirth Student's date of birth + */ + constructor(studentCode: string, dateOfBirth?: string) { + this.studentCode = String(studentCode); + this.dateOfBirth = String(dateOfBirth); + } + public async makeAuthedRequest( + path: string, + options: Omit + ) { + if (!this.authCookies) throw new Error("Not authenticated"); + const requestOptions: Omit = { + ...options, + headers: { + Cookie: this.authCookies.join(";"), + authorization: "Basic " + this.sessionId, + }, + }; + const request = await Undici.request(path, requestOptions); + let responseJSON; + try { + responseJSON = await request.body.json(); + } catch (err) { + throw new Error("Invalid JSON response, check your dates"); + } + if (responseJSON.success == 0) { + throw new Error(responseJSON.error); + } + return responseJSON.data; + } + /** + * Initialises the client and authenticates with classcharts + */ + async init(): Promise { + if (!this.studentCode) throw new Error("Student Code not inputted"); + const formData = new URLSearchParams(); + formData.append("_method", "POST"); + formData.append("code", this.studentCode.toUpperCase()); + formData.append("dob", this.dateOfBirth); + formData.append("remember_me", "1"); + formData.append("recaptcha-token", "no-token-avaliable"); + const request = await Undici.request(BASE_URL + "/student/login", { + method: "POST", + body: formData.toString(), + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + if (request.statusCode != 302 || !request.headers["set-cookie"]) + throw new Error("Unauthenticated: Classcharts returned an error"); + let cookies = request.headers["set-cookie"]; + for (let i = 0; i < cookies.length; i++) { + cookies[i] = cookies[i].substring(0, cookies[i].indexOf(";")); + } + this.authCookies = cookies; + let sessionID: any = decodeURI(cookies[2]) + .replace(/%3A/g, ":") + .replace(/%2C/g, ","); + sessionID = JSON.parse( + sessionID.substring(sessionID.indexOf("{"), sessionID.length) + ); + this.sessionId = sessionID.session_id; + const user = await this.getStudentInfo(); + this.studentId = user.id; + this.studentName = user.name; + } + /** + * Gets general information about the logged in student + * @returns Student object + */ + async getStudentInfo(): Promise { + const data = await this.makeAuthedRequest(API_BASE + "/ping", { + method: "POST", + body: "include_date=true", + }); + return data?.user; + } + /** + * Get's the logged in student's general activity + * @param options GetActivityOptions + * @returns Activity data + */ + async getActivity(options?: GetActivityOptions): Promise { + const params = new URLSearchParams(); + options?.from && params.append("form", options?.from); + options?.to && params.append("to", options?.to); + return this.makeAuthedRequest( + API_BASE + "/activity/" + this.sessionId + "?" + params.toString(), + { + method: "GET", + } + ); + } + /** + * Gets the logged in students behaviour points + * @param options GetBehaviourOptions + * @returns Array of behaviour points + */ + async getBehaviour( + options?: GetBehaviourOptions + ): Promise { + const params = new URLSearchParams(); + options?.from && params.append("form", options?.from); + options?.to && params.append("to", options?.to); + options?.last_id && params.append("last_id", options?.last_id); + return await this.makeAuthedRequest( + API_BASE + "/behaviour/" + this.studentId + "?" + params.toString(), + { + method: "GET", + } + ); + } + /** + * Gets a list of the logged in student's homeworks + * @param options GetHomeworkOptions + * @returns Array of homeworks + */ + async listHomeworks( + options?: GetHomeworkOptions + ): Promise { + const params = new URLSearchParams(); + if (options?.displayDate) + params.append("display_date", String(options?.displayDate)); + options?.fromDate && params.append("from", String(options?.fromDate)); + options?.toDate && params.append("to", String(options?.toDate)); + let data: Array = await this.makeAuthedRequest( + API_BASE + "/homeworks/" + this.studentId + "?" + params.toString(), + { + method: "GET", + } + ); + for (let i = 0; i < data.length; i++) { + // homework.lesson.replace(/\\/g, '') + data[i].description = data[i].description.replace(/(<([^>]+)>)/gi, ""); + data[i].description = data[i].description.replace(/ /g, ""); + data[i].description = data[i].description.trim(); + } + return data; + } + /** + * Gets the logged in student's lessons for a day + * @param options GetLessonsOptions + * @returns Array of lessons + */ + async getLessons(options?: GetLessonsOptions): Promise { + if (!options?.date) throw new Error("No date specified"); + const params = new URLSearchParams(); + params.append("date", String(options?.date)); + return await this.makeAuthedRequest( + API_BASE + "/timetable/" + this.studentId + "?" + params.toString(), + { + method: "GET", + } + ); + } } diff --git a/src/consts.ts b/src/consts.ts index d0cb547..baf5d1f 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -1,2 +1,2 @@ -export const BASE_URL = 'https://www.classcharts.com' -export const API_BASE = `${BASE_URL}/apiv2student` +export const BASE_URL = "https://www.classcharts.com"; +export const API_BASE = `${BASE_URL}/apiv2student`; diff --git a/src/index.ts b/src/index.ts index 83dae76..5ec7692 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1 @@ -export * from './client' +export * from "./client"; diff --git a/src/types.ts b/src/types.ts index 99b85be..d448198 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,145 +1,145 @@ export interface Student { - id: number - name: string - first_name: string - last_name: string - avatar_url: string - display_behaviour: boolean - display_parent_behaviour: boolean - display_homework: boolean - display_rewards: boolean - display_detentions: boolean - display_report_cards: boolean - display_classes: boolean - display_announcements: boolean - display_attendance: boolean - display_attendance_type: string - display_attendance_percentage: boolean - display_activity: boolean - display_mental_health: boolean - display_timetable: boolean - is_disabled: boolean - display_two_way_communications: boolean - display_absences: boolean - can_upload_attachments: string | null - display_event_badges: boolean - display_avatars: boolean - display_concern_submission: boolean - display_custom_fields: boolean - pupil_concerns_help_text: string - allow_pupils_add_timetable_notes: boolean - announcements_count: number - messages_count: number - pusher_channel_name: string - has_birthday: boolean - has_new_survey: boolean - survey_id: number | null - detention_alias_plural_uc: string + id: number; + name: string; + first_name: string; + last_name: string; + avatar_url: string; + display_behaviour: boolean; + display_parent_behaviour: boolean; + display_homework: boolean; + display_rewards: boolean; + display_detentions: boolean; + display_report_cards: boolean; + display_classes: boolean; + display_announcements: boolean; + display_attendance: boolean; + display_attendance_type: string; + display_attendance_percentage: boolean; + display_activity: boolean; + display_mental_health: boolean; + display_timetable: boolean; + is_disabled: boolean; + display_two_way_communications: boolean; + display_absences: boolean; + can_upload_attachments: string | null; + display_event_badges: boolean; + display_avatars: boolean; + display_concern_submission: boolean; + display_custom_fields: boolean; + pupil_concerns_help_text: string; + allow_pupils_add_timetable_notes: boolean; + announcements_count: number; + messages_count: number; + pusher_channel_name: string; + has_birthday: boolean; + has_new_survey: boolean; + survey_id: number | null; + detention_alias_plural_uc: string; } export interface GetActivityOptions { - from?: string - to?: string + from?: string; + to?: string; } export interface ActivityTimelinePoint { - positive: number - negative: number - name: string - start: string - end: string + positive: number; + negative: number; + name: string; + start: string; + end: string; } export interface ActivityResponse { - timeline: Array - positiveReasons: Record - negative_reasons: Record - other_positive: Array - other_negative: Array - other_positive_count: Array - other_negative_count: Array + timeline: Array; + positiveReasons: Record; + negative_reasons: Record; + other_positive: Array; + other_negative: Array; + other_positive_count: Array; + other_negative_count: Array; } export interface GetBehaviourOptions { - from?: string - to?: string - last_id?: string + from?: string; + to?: string; + last_id?: string; } export interface BehaviourPoint { - id: number - type: string - polarity: string - reason: string - score: number - timestamp: string - timestamp_custom_time: string | null - style: { - border_color: string | null - custom_class: string | null - } - pupil_name: string - lesson_name: string - teacher_name: string - room_name: string | null - note: string - _can_delete: string - detention_date: string | null - detention_time: string | null - detention_location: string | null - detention_type: string | null + id: number; + type: string; + polarity: string; + reason: string; + score: number; + timestamp: string; + timestamp_custom_time: string | null; + style: { + border_color: string | null; + custom_class: string | null; + }; + pupil_name: string; + lesson_name: string; + teacher_name: string; + room_name: string | null; + note: string; + _can_delete: string; + detention_date: string | null; + detention_time: string | null; + detention_location: string | null; + detention_type: string | null; } -export type BehaviourResponse = Array -export type DisplayDate = 'due_date' | 'issue_date' +export type BehaviourResponse = Array; +export type DisplayDate = "due_date" | "issue_date"; export interface GetHomeworkOptions { - displayDate?: DisplayDate - fromDate?: string - toDate?: string + displayDate?: DisplayDate; + fromDate?: string; + toDate?: string; } export interface Homework { - lesson: string - subject: string - teacher: string - homework_type: string - id: number - title: string - meta_title: string - description: string - issue_date: string - due_date: string - completion_time_unit: string - completion_time_value: string - publish_time: string - status: { - id: number - state: null - mark: null - mark_relative: number - ticked: 'yes' | 'no' - allow_attachments: string - first_seen_date: string - last_seen_date: string - attachments: Array - has_feedback: boolean - } - validated_links: Array - validated_attachments: Array + lesson: string; + subject: string; + teacher: string; + homework_type: string; + id: number; + title: string; + meta_title: string; + description: string; + issue_date: string; + due_date: string; + completion_time_unit: string; + completion_time_value: string; + publish_time: string; + status: { + id: number; + state: null; + mark: null; + mark_relative: number; + ticked: "yes" | "no"; + allow_attachments: string; + first_seen_date: string; + last_seen_date: string; + attachments: Array; + has_feedback: boolean; + }; + validated_links: Array; + validated_attachments: Array; } -export type HomeworksResponse = Array +export type HomeworksResponse = Array; export interface GetLessonsOptions { - date: string + date: string; } export interface Lesson { - teacher_name: string - lesson_name: string - subject_name: string - is_alternative_lesson: boolean - period_name: string - period_number: string - room_name: string - date: string - start_time: string - end_time: string - key: number - note_abstract: string - note: string - pupil_note_abstract: string - pupil_note: string - pupil_note_raw: string + teacher_name: string; + lesson_name: string; + subject_name: string; + is_alternative_lesson: boolean; + period_name: string; + period_number: string; + room_name: string; + date: string; + start_time: string; + end_time: string; + key: number; + note_abstract: string; + note: string; + pupil_note_abstract: string; + pupil_note: string; + pupil_note_raw: string; } -export type LessonsResponse = Array +export type LessonsResponse = Array; diff --git a/tsconfig.json b/tsconfig.json index a273a99..9450226 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,92 +1,92 @@ { - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - /* Projects */ - // "incremental": true, /* Enable incremental compilation */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "es2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ - // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "resolveJsonModule": true, /* Enable importing .json files */ - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - "outDir": "dist", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - // "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} \ No newline at end of file + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + /* Modules */ + "module": "commonjs" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "resolveJsonModule": true, /* Enable importing .json files */ + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + /* Emit */ + "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + "outDir": "dist" /* Specify an output folder for all emitted files. */, + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + // "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +}