mirror of
https://github.com/classchartsapi/classcharts-api-js.git
synced 2026-05-14 19:59:37 +00:00
Merge branch 'main' into feat/getCode
This commit is contained in:
commit
7e53992dbc
23 changed files with 427 additions and 196 deletions
5
.changeset/red-lobsters-destroy.md
Normal file
5
.changeset/red-lobsters-destroy.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"classcharts-api": patch
|
||||
---
|
||||
|
||||
Export types first
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/javascript-node/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 16, 14, 12, 16-bullseye, 14-bullseye, 12-bullseye, 16-buster, 14-buster, 12-buster
|
||||
ARG VARIANT="16-bullseye"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
||||
|
||||
# [Optional] Uncomment if you want to install an additional version of node using nvm
|
||||
# ARG EXTRA_NODE_VERSION=10
|
||||
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
|
||||
|
||||
# [Optional] Uncomment if you want to install more global node modules
|
||||
RUN su node -c "npm install -g pnpm np"
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/javascript-node
|
||||
{
|
||||
"name": "Node.js",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick a Node version: 16, 14, 12.
|
||||
// Append -bullseye or -buster to pin to an OS version.
|
||||
// Use -bullseye variants on local arm64/Apple Silicon.
|
||||
"args": {
|
||||
"VARIANT": "16-bullseye"
|
||||
}
|
||||
},
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {},
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": ["dbaeumer.vscode-eslint"],
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "pnpm install",
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "node"
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
dist/
|
||||
docs/
|
||||
node_modules/
|
||||
.eslintrc.js
|
||||
.eslintrc.cjs
|
||||
tsconfig.json
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
name: Typedoc
|
||||
name: Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -19,21 +19,21 @@ jobs:
|
|||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8.2.0
|
||||
- name: Retrieve the cached "node_modules" directory (if present)
|
||||
- name: Retrieve the cache
|
||||
uses: actions/cache@v3
|
||||
id: node-cache
|
||||
with:
|
||||
path: node_modules
|
||||
key: node-modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies (if the cached directory was not found)
|
||||
- name: Install dependencies
|
||||
if: steps.node-cache.outputs.cache-hit != 'true'
|
||||
run: pnpm install
|
||||
|
||||
- name: Test to see if the project compiles
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Create the docs directory locally in CI
|
||||
- name: Generate typedoc
|
||||
run: pnpm generateDocs
|
||||
|
||||
- name: Deploy 🚀
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -118,6 +118,5 @@ dist
|
|||
.pnp.*
|
||||
|
||||
tests/config.json
|
||||
tests/sandbox.js
|
||||
|
||||
docs/
|
||||
docs/typedoc
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
dist
|
||||
docs
|
||||
node_modules
|
||||
dist/
|
||||
node_modules/
|
||||
pnpm-lock.yaml
|
||||
.prettierrc.json
|
||||
.eslint.js
|
||||
CHANGELOG.md
|
||||
6
.vscode/extensions.json
vendored
6
.vscode/extensions.json
vendored
|
|
@ -1,7 +1,3 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"EditorConfig.EditorConfig"
|
||||
]
|
||||
"recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
|
||||
}
|
||||
|
|
|
|||
17
CHANGELOG.md
17
CHANGELOG.md
|
|
@ -1,5 +1,22 @@
|
|||
# classcharts-api
|
||||
|
||||
## 2.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 6552c28: Migrate to native fetch
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- a3e078b: Throw more description JSON parsing errors
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 350878c: Fixed internal typing typo
|
||||
- 451f800: Specify the required node version
|
||||
|
||||
## 2.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
|||
0
docs/.nojekyll
Normal file
0
docs/.nojekyll
Normal file
297
docs/README.md
Normal file
297
docs/README.md
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
<p align="center">
|
||||
<h1 align="center">ClassCharts API JS</h1>
|
||||
<p align="center">
|
||||
A typescript wrapper for getting information from the Classcharts API
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/classchartsapi/classcharts-api-js">Source</a>
|
||||
<span> • </span>
|
||||
<a href="https://github.com/classchartsapi/classcharts-api-js/issues">Issues</a>
|
||||
<span> • </span>
|
||||
<a href="https://www.npmjs.com/package/classcharts-api">NPM</a>
|
||||
<span> • </span>
|
||||
<a href="https://discord.gg/DTcwugcgZ2">Discord</a>
|
||||
<span> • </span>
|
||||
<a href="https://classchartsapi.github.io/classcharts-api-js/typedoc/">TypeDoc</a>
|
||||
<span> • </span>
|
||||
<a href="https://classchartsapi.github.io/api-docs/">API Docs</a>
|
||||
</p>
|
||||
|
||||
# Introduction
|
||||
|
||||
The ClassCharts API is a typescript wrapper around the ClassCharts API. It allows you to easily make requests to the ClassCharts API without having to worry about the underlying implementation of making requests.
|
||||
|
||||
## Help
|
||||
|
||||
For any help with the library, please join the [discord](https://discord.gg/DTcwugcgZ2) where you can ask questions and get help from the community.
|
||||
|
||||
# Installation
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js 18 or newer
|
||||
|
||||
## NPM
|
||||
|
||||
```bash
|
||||
npm install classcharts-api # npm
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn add classcharts-api # yarn
|
||||
```
|
||||
|
||||
```bash
|
||||
pnpm add classcharts-api # pnpm
|
||||
```
|
||||
|
||||
# Logging In
|
||||
|
||||
Before making any requests, you must login to the client. This will get you a session ID which will be used for all requests.
|
||||
|
||||
## Student Client
|
||||
|
||||
```typescript
|
||||
import { StudentClient } from "classcharts-api";
|
||||
|
||||
// Date of birth MUST in the format DD/MM/YYYY
|
||||
const client = new StudentClient("classchartsCode", "01/1/2000");
|
||||
await client.login();
|
||||
```
|
||||
|
||||
## Parent Client
|
||||
|
||||
```typescript
|
||||
import { ParentClient } from "classcharts-api";
|
||||
|
||||
const client = new ParentClient("username", "password");
|
||||
await client.login();
|
||||
```
|
||||
|
||||
# Universal Methods
|
||||
|
||||
All the following methods can be used on both the student and parent client. Each example expects the client to be already logged in.
|
||||
|
||||
## `.getStudentInfo`
|
||||
|
||||
```typescript
|
||||
const studentInfo = await client.getStudentInfo();
|
||||
console.log(studentInfo);
|
||||
/**
|
||||
{
|
||||
success: 1,
|
||||
data: {
|
||||
user: {
|
||||
id: 2339528,
|
||||
...
|
||||
}
|
||||
},
|
||||
meta: {
|
||||
session_id: '5vf2v7n5uk9jftrxaarrik39vk6yjm48',
|
||||
...
|
||||
}
|
||||
}
|
||||
*/
|
||||
```
|
||||
|
||||
## `.getActivity`
|
||||
|
||||
```typescript
|
||||
// Dates must be in format YYYY-MM-DD
|
||||
const activity = await client.getActivity({
|
||||
from: "2023-04-01",
|
||||
to: "2023-05-10",
|
||||
last_id: "12",
|
||||
});
|
||||
console.log(activity);
|
||||
```
|
||||
|
||||
## `.getFullActivity`
|
||||
|
||||
```typescript
|
||||
// Dates must be in format YYYY-MM-DD
|
||||
const activity = await client.getFullActivity({
|
||||
from: "2023-04-01",
|
||||
to: "2023-05-10",
|
||||
});
|
||||
console.log(activity);
|
||||
```
|
||||
|
||||
## `.getBehaviour`
|
||||
|
||||
Gets behaviour for a given date range.
|
||||
|
||||
```typescript
|
||||
// Dates must be in format YYYY-MM-DD
|
||||
const behaviour = await client.getBehaviour({
|
||||
from: "2023-04-01",
|
||||
to: "2023-05-10",
|
||||
});
|
||||
console.log(behaviour);
|
||||
|
||||
/**
|
||||
{
|
||||
"success": 1,
|
||||
"data": {
|
||||
"timeline": [
|
||||
{
|
||||
"positive": 426,
|
||||
...
|
||||
},
|
||||
],
|
||||
...
|
||||
"meta": {
|
||||
"start_date": "2023-04-01T00:00:00+00:00",
|
||||
...
|
||||
}
|
||||
}
|
||||
*/
|
||||
```
|
||||
|
||||
## `.getHomeworks`
|
||||
|
||||
Gets homeworks for a given date range.
|
||||
|
||||
```typescript
|
||||
// Dates must be in format YYYY-MM-DD
|
||||
const homeworks = await client.getHomeworks({
|
||||
from: "2023-04-01",
|
||||
to: "2023-05-10",
|
||||
displayDate: 'issue_date' // Can be 'due_date' or 'issue_date'
|
||||
});
|
||||
console.log(homeworks);
|
||||
|
||||
/**
|
||||
{
|
||||
success: 1,
|
||||
data: [
|
||||
{
|
||||
lesson: '7A/Pe1',
|
||||
...
|
||||
},
|
||||
],
|
||||
meta: {
|
||||
start_date: '2023-04-01T00:00:00+00:00',
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## `.getLessons`
|
||||
|
||||
Gets lessons for a specific date.
|
||||
|
||||
```typescript
|
||||
// Dates must be in format YYYY-MM-DD
|
||||
const lessons = await client.getLessons({
|
||||
date: "2023-04-01",
|
||||
});
|
||||
console.log(lessons);
|
||||
|
||||
/**
|
||||
{
|
||||
"success": 1,
|
||||
"data": [
|
||||
{
|
||||
"teacher_name": "Mr J Doe",
|
||||
...
|
||||
}
|
||||
...
|
||||
],
|
||||
"meta": {
|
||||
"dates": [
|
||||
"2023-05-04"
|
||||
],
|
||||
...
|
||||
}
|
||||
}
|
||||
*/
|
||||
```
|
||||
|
||||
## `.getBadges`
|
||||
|
||||
Gets all earned badges.
|
||||
|
||||
```typescript
|
||||
const badges = await client.getBadges();
|
||||
console.log(badges);
|
||||
|
||||
/**
|
||||
{
|
||||
success: 1,
|
||||
data: [
|
||||
{
|
||||
id: 123,
|
||||
name: 'Big Badge',
|
||||
...
|
||||
},
|
||||
...
|
||||
],
|
||||
meta: []
|
||||
}
|
||||
*/
|
||||
```
|
||||
|
||||
## `.getAnnouncements`
|
||||
|
||||
?> This method does not include `meta` in the response, since I do not have access to this endpoint to test it. If you have access to this endpoint, please open a PR to add the `meta` response. Thanks!
|
||||
|
||||
Gets all announcements.
|
||||
|
||||
```typescript
|
||||
const announcements = await client.getAnnouncements();
|
||||
console.log(announcements);
|
||||
```
|
||||
|
||||
## `.getDetentions`
|
||||
|
||||
?> This method does not include `meta` in the response, since I do not have access to this endpoint to test it. If you have access to this endpoint, please open a PR to add the `meta` response. Thanks!
|
||||
|
||||
Gets all detentions.
|
||||
|
||||
```typescript
|
||||
const detentions = await client.getDetentions();
|
||||
console.log(detentions);
|
||||
```
|
||||
|
||||
## `.getAttendance`
|
||||
|
||||
?> This method does not include `meta` in the response, since I do not have access to this endpoint to test it. If you have access to this endpoint, please open a PR to add the `meta` response. Thanks!
|
||||
|
||||
Gets attendance.
|
||||
|
||||
```typescript
|
||||
const attendance = await client.getAttendance();
|
||||
console.log(attendance);
|
||||
```
|
||||
|
||||
# Parent Specific Methods
|
||||
|
||||
## `.getPupils`
|
||||
|
||||
Gets a list of all pupils the parent has access to.
|
||||
|
||||
```typescript
|
||||
const pupils = await client.getPupils();
|
||||
console.log(pupils);
|
||||
/**
|
||||
[
|
||||
{
|
||||
id: 123,
|
||||
name: 'John Doe',
|
||||
...
|
||||
},
|
||||
...
|
||||
]
|
||||
*/
|
||||
```
|
||||
|
||||
## `.selectPupil`
|
||||
|
||||
Selects a pupil to make subsequent requests for.
|
||||
|
||||
```typescript
|
||||
await client.selectPupil(123);
|
||||
```
|
||||
40
docs/index.html
Normal file
40
docs/index.html
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ClassCharts-API</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<!-- <meta name="description" content="Description"> -->
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css"
|
||||
/>
|
||||
<script
|
||||
async
|
||||
src="https://umami.jaminit.co.uk/script.js"
|
||||
data-website-id="3f01674a-5c63-47a2-962b-43d0c62c7c6c"
|
||||
data-domains="classchartsapi.github.io"
|
||||
></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
name: "ClassCharts API JS",
|
||||
repo: "classchartsapi/classcharts-api-js",
|
||||
auto2top: true,
|
||||
autoHeader: true,
|
||||
};
|
||||
</script>
|
||||
<!-- Docsify v4 -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-typescript.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
16
package.json
16
package.json
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"name": "classcharts-api",
|
||||
"type": "module",
|
||||
"version": "2.1.3",
|
||||
"version": "2.3.0",
|
||||
"license": "ISC",
|
||||
"author": {
|
||||
"name": "James Cook",
|
||||
"email": "james@jaminit.co.uk"
|
||||
},
|
||||
"description": "A Typescript wrapper for getting information from the Classcharts API",
|
||||
"description": "A Typescript wrapper for getting information from the ClassCharts API",
|
||||
"keywords": [
|
||||
"node",
|
||||
"typescript",
|
||||
|
|
@ -28,9 +28,6 @@
|
|||
"test": "jest",
|
||||
"release": "pnpm run build && changeset publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"ky-universal": "^0.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.26.1",
|
||||
"@types/jest": "^29.5.1",
|
||||
|
|
@ -51,14 +48,17 @@
|
|||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
"require": "./dist/index.js"
|
||||
},
|
||||
"./types": "./dist/index.d.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"dist/**"
|
||||
]
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
76
pnpm-lock.yaml
generated
76
pnpm-lock.yaml
generated
|
|
@ -1,10 +1,5 @@
|
|||
lockfileVersion: '6.0'
|
||||
|
||||
dependencies:
|
||||
ky-universal:
|
||||
specifier: ^0.11.0
|
||||
version: 0.11.0(ky@0.33.3)
|
||||
|
||||
devDependencies:
|
||||
'@changesets/cli':
|
||||
specifier: ^2.26.1
|
||||
|
|
@ -1200,13 +1195,6 @@ packages:
|
|||
eslint-visitor-keys: 3.4.0
|
||||
dev: true
|
||||
|
||||
/abort-controller@3.0.0:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
dev: false
|
||||
|
||||
/acorn-jsx@5.3.2(acorn@8.8.2):
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -1630,11 +1618,6 @@ packages:
|
|||
stream-transform: 2.1.3
|
||||
dev: true
|
||||
|
||||
/data-uri-to-buffer@4.0.1:
|
||||
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
||||
engines: {node: '>= 12'}
|
||||
dev: false
|
||||
|
||||
/debug@4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
|
|
@ -1949,11 +1932,6 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/event-target-shim@5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/execa@5.1.1:
|
||||
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -2033,14 +2011,6 @@ packages:
|
|||
bser: 2.1.1
|
||||
dev: true
|
||||
|
||||
/fetch-blob@3.2.0:
|
||||
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
||||
engines: {node: ^12.20 || >= 14.13}
|
||||
dependencies:
|
||||
node-domexception: 1.0.0
|
||||
web-streams-polyfill: 3.2.1
|
||||
dev: false
|
||||
|
||||
/file-entry-cache@6.0.1:
|
||||
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
|
||||
engines: {node: ^10.12.0 || >=12.0.0}
|
||||
|
|
@ -2096,13 +2066,6 @@ packages:
|
|||
is-callable: 1.2.7
|
||||
dev: true
|
||||
|
||||
/formdata-polyfill@4.0.10:
|
||||
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
dependencies:
|
||||
fetch-blob: 3.2.0
|
||||
dev: false
|
||||
|
||||
/fs-extra@7.0.1:
|
||||
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
|
||||
engines: {node: '>=6 <7 || >=8'}
|
||||
|
|
@ -3089,26 +3052,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/ky-universal@0.11.0(ky@0.33.3):
|
||||
resolution: {integrity: sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==}
|
||||
engines: {node: '>=14.16'}
|
||||
peerDependencies:
|
||||
ky: '>=0.31.4'
|
||||
web-streams-polyfill: '>=3.2.1'
|
||||
peerDependenciesMeta:
|
||||
web-streams-polyfill:
|
||||
optional: true
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
ky: 0.33.3
|
||||
node-fetch: 3.3.1
|
||||
dev: false
|
||||
|
||||
/ky@0.33.3:
|
||||
resolution: {integrity: sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==}
|
||||
engines: {node: '>=14.16'}
|
||||
dev: false
|
||||
|
||||
/leven@3.1.0:
|
||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -3302,20 +3245,6 @@ packages:
|
|||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
dev: true
|
||||
|
||||
/node-domexception@1.0.0:
|
||||
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||
engines: {node: '>=10.5.0'}
|
||||
dev: false
|
||||
|
||||
/node-fetch@3.3.1:
|
||||
resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dependencies:
|
||||
data-uri-to-buffer: 4.0.1
|
||||
fetch-blob: 3.2.0
|
||||
formdata-polyfill: 4.0.10
|
||||
dev: false
|
||||
|
||||
/node-int64@0.4.0:
|
||||
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
|
||||
dev: true
|
||||
|
|
@ -4191,11 +4120,6 @@ packages:
|
|||
defaults: 1.0.4
|
||||
dev: true
|
||||
|
||||
/web-streams-polyfill@3.2.1:
|
||||
resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
|
||||
engines: {node: '>= 8'}
|
||||
dev: false
|
||||
|
||||
/which-boxed-primitive@1.0.2:
|
||||
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
|
||||
dependencies:
|
||||
|
|
|
|||
38
readme.md
38
readme.md
|
|
@ -1,31 +1,23 @@
|
|||
# Classcharts API
|
||||
<h1 align="center">Classcharts API JS</h1>
|
||||
<div align="center">
|
||||
<img alt="Discord" src="https://img.shields.io/discord/918103752068726855">
|
||||
<img alt="npm" src="https://img.shields.io/npm/dm/classcharts-api">
|
||||
<img alt="NPM" src="https://img.shields.io/npm/l/classcharts-api">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/classcharts-api">
|
||||
<img alt="node-current" src="https://img.shields.io/node/v/classcharts-api">
|
||||
</div>
|
||||
|
||||
A client for the classcharts API
|
||||
<p align="center">A typescript wrapper for getting information from the Classcharts API.</p>
|
||||
|
||||
# Links
|
||||
|
||||
- [Documentation](https://classchartsapi.github.io/classcharts-api-js/)
|
||||
- [API Documentation (with library examples)](https://classchartsapi.github.io/api-docs/#introduction)
|
||||
- [Discord](https://discord.gg/DTcwugcgZ2)
|
||||
|
||||
# Examples
|
||||
# Contributing
|
||||
|
||||
Docs are very much a WIP, for any help with the library, please join the discord above
|
||||
Contributions are welcome! There are lots of API endpoints which we simply do not have access to to implement, so if you have access to them, please consider contributing! If you have any questions, feel free to ask in the [discord](https://discord.gg/DTcwugcgZ2).
|
||||
|
||||
```typescript
|
||||
import { StudentClient } from "classcharts-api";
|
||||
async function main() {
|
||||
const client = new StudentClient("classchartsCode", "01/1/2000");
|
||||
await client.login();
|
||||
console.log(
|
||||
await client.getBehaviour({
|
||||
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());
|
||||
}
|
||||
# Help
|
||||
|
||||
main();
|
||||
```
|
||||
For any help with the library, please join the [discord](https://discord.gg/DTcwugcgZ2) where you can ask questions and get help from the community.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import ky, { type Options as KyOptions } from "ky-universal";
|
||||
import type {
|
||||
ActivityResponse,
|
||||
AnnouncementsResponse,
|
||||
|
|
@ -44,13 +43,13 @@ export class BaseClient {
|
|||
*/
|
||||
public lastPing = 0;
|
||||
/**
|
||||
* @property API_BASE Base API URL, this is different depending if its called as a parent or student
|
||||
* @property API_BASE Base API URL, this is different depending on if its called as a parent or student
|
||||
* @internal
|
||||
*/
|
||||
protected API_BASE = "";
|
||||
/**
|
||||
*
|
||||
* @param API_BASE Base API URL, this is different depending if its called as a parent or student
|
||||
* @param API_BASE Base API URL, this is different depending on if its called as a parent or student
|
||||
*/
|
||||
constructor(API_BASE: string) {
|
||||
this.authCookies = [];
|
||||
|
|
@ -59,7 +58,7 @@ export class BaseClient {
|
|||
/**
|
||||
* Revalidates the session ID.
|
||||
*
|
||||
* This is called automatically when the session ID is older than 3 minutes or when intially using the .login() method
|
||||
* This is called automatically when the session ID is older than 3 minutes or when initially using the .login() method
|
||||
* @internal
|
||||
*/
|
||||
public async getNewSessionId() {
|
||||
|
|
@ -77,7 +76,7 @@ export class BaseClient {
|
|||
this.lastPing = Date.now();
|
||||
}
|
||||
/**
|
||||
* Makes a request to the Classcharts API with the required authentication headers
|
||||
* Makes a request to the ClassCharts API with the required authentication headers
|
||||
*
|
||||
* @param path Path to the API endpoint
|
||||
* @param kyOptions Ky (fetch library) request options
|
||||
|
|
@ -89,7 +88,7 @@ export class BaseClient {
|
|||
*/
|
||||
public async makeAuthedRequest(
|
||||
path: string,
|
||||
kyOptions: KyOptions,
|
||||
fetchOptions: RequestInit,
|
||||
options?: { revalidateToken?: boolean }
|
||||
) {
|
||||
if (!this.sessionId) throw new Error("No session ID");
|
||||
|
|
@ -100,24 +99,27 @@ export class BaseClient {
|
|||
options.revalidateToken = true;
|
||||
}
|
||||
const requestOptions = {
|
||||
...kyOptions,
|
||||
...fetchOptions,
|
||||
headers: {
|
||||
Cookie: this?.authCookies?.join(";") ?? [],
|
||||
Authorization: "Basic " + this.sessionId,
|
||||
...kyOptions.headers,
|
||||
...fetchOptions.headers,
|
||||
},
|
||||
credentials: undefined,
|
||||
} satisfies KyOptions;
|
||||
} satisfies RequestInit;
|
||||
if (options?.revalidateToken === true && this.lastPing) {
|
||||
if (Date.now() - this.lastPing + 5000 > PING_INTERVAL) {
|
||||
await this.getNewSessionId();
|
||||
}
|
||||
}
|
||||
const request = await ky(path, requestOptions);
|
||||
const responseJSON = (await request.json()) as ClassChartsResponse<
|
||||
unknown,
|
||||
unknown
|
||||
>;
|
||||
const request = await fetch(path, requestOptions);
|
||||
let responseJSON: ClassChartsResponse<unknown, unknown>;
|
||||
try {
|
||||
responseJSON = await request.json();
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
"Error parsing JSON. Returned response: " + (await request.text())
|
||||
);
|
||||
}
|
||||
if (responseJSON.success == 0) {
|
||||
throw new Error(responseJSON.error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import ky from "ky-universal";
|
||||
import type { GetPupilsResponse } from "../types.js";
|
||||
|
||||
import { BaseClient } from "./baseClient.js";
|
||||
|
|
@ -24,7 +23,7 @@ export class ParentClient extends BaseClient {
|
|||
}
|
||||
|
||||
/**
|
||||
* Authenticates with classcharts
|
||||
* Authenticates with ClassCharts
|
||||
*/
|
||||
async login(): Promise<void> {
|
||||
if (!this.email) throw new Error("Email not inputted");
|
||||
|
|
@ -33,11 +32,11 @@ export class ParentClient extends BaseClient {
|
|||
formData.append("email", this.email);
|
||||
formData.append("logintype", "existing");
|
||||
formData.append("password", this.password);
|
||||
formData.append("recaptcha-token", "no-token-avaliable");
|
||||
formData.append("recaptcha-token", "no-token-available");
|
||||
const headers = new Headers({
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
});
|
||||
const response = await ky(BASE_URL + "/parent/login", {
|
||||
const response = await fetch(BASE_URL + "/parent/login", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: headers,
|
||||
|
|
@ -45,7 +44,7 @@ export class ParentClient extends BaseClient {
|
|||
});
|
||||
if (response.status != 302 || !response.headers.get("set-cookie"))
|
||||
throw new Error(
|
||||
"Unauthenticated: Classcharts returned an error: " +
|
||||
"Unauthenticated: ClassCharts returned an error: " +
|
||||
response.status +
|
||||
" " +
|
||||
response.statusText
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import { API_BASE_STUDENT, BASE_URL } from "../utils/consts.js";
|
||||
import { BaseClient } from "./baseClient.js";
|
||||
import { parseCookies } from "../utils/utils.js";
|
||||
import ky from "ky-universal";
|
||||
|
||||
/**
|
||||
* Student Client
|
||||
*/
|
||||
export class StudentClient extends BaseClient {
|
||||
/**
|
||||
* @property studentCode Classcharts student code
|
||||
* @property studentCode ClassCharts student code
|
||||
* @internal
|
||||
*/
|
||||
private studentCode = "";
|
||||
|
|
@ -20,7 +19,7 @@ export class StudentClient extends BaseClient {
|
|||
|
||||
/**
|
||||
*
|
||||
* @param studentCode Classcharts student code
|
||||
* @param studentCode ClassCharts student code
|
||||
* @param dateOfBirth Student's date of birth
|
||||
*/
|
||||
constructor(studentCode: string, dateOfBirth?: string) {
|
||||
|
|
@ -30,7 +29,7 @@ export class StudentClient extends BaseClient {
|
|||
}
|
||||
|
||||
/**
|
||||
* Authenticates with classcharts
|
||||
* Authenticates with ClassCharts
|
||||
*/
|
||||
async login(): Promise<void> {
|
||||
if (!this.studentCode) throw new Error("Student Code not inputted");
|
||||
|
|
@ -39,17 +38,16 @@ export class StudentClient extends BaseClient {
|
|||
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 ky(BASE_URL + "/student/login", {
|
||||
formData.append("recaptcha-token", "no-token-available");
|
||||
const request = await fetch(BASE_URL + "/student/login", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
redirect: "manual",
|
||||
throwHttpErrors: false,
|
||||
credentials: undefined,
|
||||
});
|
||||
if (request.status != 302 || !request.headers.get("set-cookie")) {
|
||||
throw new Error(
|
||||
"Unauthenticated: Classcharts returned an error: " +
|
||||
"Unauthenticated: ClassCharts returned an error: " +
|
||||
request.status +
|
||||
" " +
|
||||
request.statusText
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
* Helper type to define response from ClassCharts
|
||||
* @internal
|
||||
*/
|
||||
export type ClassChartsResponse<Data, Error> = {
|
||||
export type ClassChartsResponse<Data, Meta> = {
|
||||
data: Data;
|
||||
meta: Error;
|
||||
meta: Meta;
|
||||
error?: string;
|
||||
success: number;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { StudentClient } from "../src";
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import { code, dob } from "./config.json";
|
||||
import "jest-extended";
|
||||
const client = new StudentClient(code, dob);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"skipLibCheck": true,
|
||||
"isolatedModules": true
|
||||
"isolatedModules": true,
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module.exports = {
|
|||
Github: "https://github.com/classchartsapi/classcharts-api-js",
|
||||
},
|
||||
includeVersion: true,
|
||||
out: "docs",
|
||||
out: "docs/typedoc",
|
||||
sort: "required-first",
|
||||
umamiOptions: {
|
||||
src: "https://umami.jaminit.co.uk/script.js",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue