mirror of
https://github.com/classchartsapi/classcharts-api-js.git
synced 2026-05-14 11:58:13 +00:00
Merge branch 'main' into main
This commit is contained in:
commit
8b0ad3667d
13 changed files with 113 additions and 41 deletions
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"denoland.vscode-deno"
|
||||
]
|
||||
}
|
||||
|
|
@ -2,5 +2,8 @@
|
|||
"tasks": {
|
||||
"npm": "deno run -A scripts/build_npm.ts"
|
||||
},
|
||||
"exclude": ["npm"]
|
||||
"exclude": ["npm"],
|
||||
"imports": {
|
||||
"~/": "./"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
32
deno.lock
generated
32
deno.lock
generated
|
|
@ -79,6 +79,38 @@
|
|||
"https://deno.land/std@0.200.0/assert/unimplemented.ts": "d56fbeecb1f108331a380f72e3e010a1f161baa6956fd0f7cf3e095ae1a4c75a",
|
||||
"https://deno.land/std@0.200.0/assert/unreachable.ts": "4600dc0baf7d9c15a7f7d234f00c23bca8f3eba8b140286aaca7aa998cf9a536",
|
||||
"https://deno.land/std@0.200.0/fmt/colors.ts": "a7eecffdf3d1d54db890723b303847b6e0a1ab4b528ba6958b8f2e754cf1b3bc",
|
||||
"https://deno.land/std@0.201.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9",
|
||||
"https://deno.land/std@0.201.0/assert/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea",
|
||||
"https://deno.land/std@0.201.0/assert/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7",
|
||||
"https://deno.land/std@0.201.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
|
||||
"https://deno.land/std@0.201.0/assert/assert_almost_equals.ts": "e15ca1f34d0d5e0afae63b3f5d975cbd18335a132e42b0c747d282f62ad2cd6c",
|
||||
"https://deno.land/std@0.201.0/assert/assert_array_includes.ts": "6856d7f2c3544bc6e62fb4646dfefa3d1df5ff14744d1bca19f0cbaf3b0d66c9",
|
||||
"https://deno.land/std@0.201.0/assert/assert_equals.ts": "d8ec8a22447fbaf2fc9d7c3ed2e66790fdb74beae3e482855d75782218d68227",
|
||||
"https://deno.land/std@0.201.0/assert/assert_exists.ts": "407cb6b9fb23a835cd8d5ad804e2e2edbbbf3870e322d53f79e1c7a512e2efd7",
|
||||
"https://deno.land/std@0.201.0/assert/assert_false.ts": "a9962749f4bf5844e3fa494257f1de73d69e4fe0e82c34d0099287552163a2dc",
|
||||
"https://deno.land/std@0.201.0/assert/assert_greater.ts": "ae2158a2d19313bf675bf7251d31c6dc52973edb12ac64ac8fc7064152af3e63",
|
||||
"https://deno.land/std@0.201.0/assert/assert_greater_or_equal.ts": "1439da5ebbe20855446cac50097ac78b9742abe8e9a43e7de1ce1426d556e89c",
|
||||
"https://deno.land/std@0.201.0/assert/assert_instance_of.ts": "3aedb3d8186e120812d2b3a5dea66a6e42bf8c57a8bd927645770bd21eea554c",
|
||||
"https://deno.land/std@0.201.0/assert/assert_is_error.ts": "c21113094a51a296ffaf036767d616a78a2ae5f9f7bbd464cd0197476498b94b",
|
||||
"https://deno.land/std@0.201.0/assert/assert_less.ts": "aec695db57db42ec3e2b62e97e1e93db0063f5a6ec133326cc290ff4b71b47e4",
|
||||
"https://deno.land/std@0.201.0/assert/assert_less_or_equal.ts": "5fa8b6a3ffa20fd0a05032fe7257bf985d207b85685fdbcd23651b70f928c848",
|
||||
"https://deno.land/std@0.201.0/assert/assert_match.ts": "c4083f80600bc190309903c95e397a7c9257ff8b5ae5c7ef91e834704e672e9b",
|
||||
"https://deno.land/std@0.201.0/assert/assert_not_equals.ts": "9f1acab95bd1f5fc9a1b17b8027d894509a745d91bac1718fdab51dc76831754",
|
||||
"https://deno.land/std@0.201.0/assert/assert_not_instance_of.ts": "0c14d3dfd9ab7a5276ed8ed0b18c703d79a3d106102077ec437bfe7ed912bd22",
|
||||
"https://deno.land/std@0.201.0/assert/assert_not_match.ts": "3796a5b0c57a1ce6c1c57883dd4286be13a26f715ea662318ab43a8491a13ab0",
|
||||
"https://deno.land/std@0.201.0/assert/assert_not_strict_equals.ts": "ca6c6d645e95fbc873d25320efeb8c4c6089a9a5e09f92d7c1c4b6e935c2a6ad",
|
||||
"https://deno.land/std@0.201.0/assert/assert_object_match.ts": "d8fc2867cfd92eeacf9cea621e10336b666de1874a6767b5ec48988838370b54",
|
||||
"https://deno.land/std@0.201.0/assert/assert_rejects.ts": "45c59724de2701e3b1f67c391d6c71c392363635aad3f68a1b3408f9efca0057",
|
||||
"https://deno.land/std@0.201.0/assert/assert_strict_equals.ts": "b1f538a7ea5f8348aeca261d4f9ca603127c665e0f2bbfeb91fa272787c87265",
|
||||
"https://deno.land/std@0.201.0/assert/assert_string_includes.ts": "b821d39ebf5cb0200a348863c86d8c4c4b398e02012ce74ad15666fc4b631b0c",
|
||||
"https://deno.land/std@0.201.0/assert/assert_throws.ts": "63784e951475cb7bdfd59878cd25a0931e18f6dc32a6077c454b2cd94f4f4bcd",
|
||||
"https://deno.land/std@0.201.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
|
||||
"https://deno.land/std@0.201.0/assert/equal.ts": "9f1a46d5993966d2596c44e5858eec821859b45f783a5ee2f7a695dfc12d8ece",
|
||||
"https://deno.land/std@0.201.0/assert/fail.ts": "c36353d7ae6e1f7933d45f8ea51e358c8c4b67d7e7502028598fe1fea062e278",
|
||||
"https://deno.land/std@0.201.0/assert/mod.ts": "37c49a26aae2b254bbe25723434dc28cd7532e444cf0b481a97c045d110ec085",
|
||||
"https://deno.land/std@0.201.0/assert/unimplemented.ts": "d56fbeecb1f108331a380f72e3e010a1f161baa6956fd0f7cf3e095ae1a4c75a",
|
||||
"https://deno.land/std@0.201.0/assert/unreachable.ts": "4600dc0baf7d9c15a7f7d234f00c23bca8f3eba8b140286aaca7aa998cf9a536",
|
||||
"https://deno.land/std@0.201.0/fmt/colors.ts": "87544aa2bc91087bb37f9c077970c85bfb041b48e4c37356129d7b450a415b6f",
|
||||
"https://deno.land/x/code_block_writer@12.0.0/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5",
|
||||
"https://deno.land/x/code_block_writer@12.0.0/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff",
|
||||
"https://deno.land/x/deno_cache@0.5.2/auth_tokens.ts": "5d1d56474c54a9d152e44d43ea17c2e6a398dd1e9682c69811a313567c01ee1e",
|
||||
|
|
|
|||
5
deps_dev.ts
Normal file
5
deps_dev.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export {
|
||||
assertEquals,
|
||||
assertExists,
|
||||
assertRejects,
|
||||
} from "https://deno.land/std@0.201.0/assert/mod.ts";
|
||||
11
index.html
11
index.html
|
|
@ -4,7 +4,10 @@
|
|||
<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="description"
|
||||
content="Documentation for classcharts-api javascript package. A library for interacting with the ClassCharts API."
|
||||
/>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0"
|
||||
|
|
@ -13,12 +16,6 @@
|
|||
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>
|
||||
|
|
|
|||
4
mod.ts
4
mod.ts
|
|
@ -1,2 +1,2 @@
|
|||
export * from "./src/core/studentClient.ts";
|
||||
export * from "./src/core/parentClient.ts";
|
||||
export * from "~/src/core/studentClient.ts";
|
||||
export * from "~/src/core/parentClient.ts";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// This dependancy cannot be moved to dev_deps.ts since dnt complains about a top-level await
|
||||
import { build, emptyDir } from "https://deno.land/x/dnt@0.38.1/mod.ts";
|
||||
|
||||
if (!Deno.args[0]) throw new Error("No version specified");
|
||||
|
|
@ -13,6 +14,7 @@ await build({
|
|||
path: "./src/types.ts",
|
||||
}],
|
||||
outDir: "./npm",
|
||||
importMap: "./deno.jsonc",
|
||||
shims: {
|
||||
deno: true,
|
||||
},
|
||||
|
|
@ -22,13 +24,12 @@ await build({
|
|||
},
|
||||
typeCheck: "both",
|
||||
package: {
|
||||
// package.json properties
|
||||
name: "classcharts-api",
|
||||
version: String(Deno.args[0]).replace("v", ""),
|
||||
author: {
|
||||
name: "James Cook",
|
||||
email: "james@jaminit.co.uk",
|
||||
},
|
||||
version: Deno.args[0],
|
||||
description:
|
||||
"A Typescript wrapper for getting information from the ClassCharts API",
|
||||
license: "ISC",
|
||||
|
|
@ -47,7 +48,6 @@ await build({
|
|||
sideEffects: false,
|
||||
},
|
||||
postBuild() {
|
||||
// steps to run after building and before running the tests
|
||||
Deno.copyFileSync("LICENSE", "npm/LICENSE");
|
||||
Deno.copyFileSync("README.md", "npm/README.md");
|
||||
},
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import type {
|
|||
LessonsResponse,
|
||||
PupilFieldsResponse,
|
||||
} from "../types.ts";
|
||||
import { PING_INTERVAL } from "../utils/consts.ts";
|
||||
import { PING_INTERVAL } from "~/src/utils/consts.ts";
|
||||
|
||||
/**
|
||||
* Shared client for both parent and student. This is not exported and should not be used directly
|
||||
|
|
@ -105,7 +105,8 @@ export class BaseClient {
|
|||
}
|
||||
}
|
||||
const request = await fetch(path, requestOptions);
|
||||
let responseJSON: ClassChartsResponse<unknown, unknown>;
|
||||
// deno-lint-ignore no-explicit-any
|
||||
let responseJSON: ClassChartsResponse<any, any>;
|
||||
try {
|
||||
responseJSON = await request.json();
|
||||
} catch {
|
||||
|
|
@ -116,8 +117,7 @@ export class BaseClient {
|
|||
if (responseJSON.success == 0) {
|
||||
throw new Error(responseJSON.error);
|
||||
}
|
||||
// deno-lint-ignore no-explicit-any
|
||||
return responseJSON as unknown as any;
|
||||
return responseJSON;
|
||||
}
|
||||
/**
|
||||
* Gets general information about the current student
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { GetPupilsResponse } from "../types.ts";
|
||||
|
||||
import { BaseClient } from "./baseClient.ts";
|
||||
import { API_BASE_PARENT, BASE_URL } from "../utils/consts.ts";
|
||||
import { parseCookies } from "../utils/utils.ts";
|
||||
import { BaseClient } from "~/src/core/baseClient.ts";
|
||||
import { API_BASE_PARENT, BASE_URL } from "~/src/utils/consts.ts";
|
||||
import { parseCookies } from "~/src/utils/utils.ts";
|
||||
/**
|
||||
* Parent Client
|
||||
*/
|
||||
|
|
@ -26,6 +26,7 @@ export class ParentClient extends BaseClient {
|
|||
*/
|
||||
async login(): Promise<void> {
|
||||
if (!this.email) throw new Error("Email not provided");
|
||||
if (!this.password) throw new Error("Password not provided");
|
||||
const formData = new URLSearchParams();
|
||||
formData.append("_method", "POST");
|
||||
formData.append("email", this.email);
|
||||
|
|
@ -39,14 +40,12 @@ export class ParentClient extends BaseClient {
|
|||
method: "POST",
|
||||
body: formData,
|
||||
headers: headers,
|
||||
credentials: undefined,
|
||||
redirect: "manual",
|
||||
});
|
||||
if (response.status != 302 || !response.headers.has("set-cookie")) {
|
||||
await response.body?.cancel(); // Make deno tests happy by closing the body, unsure whether this is needed for the actual library
|
||||
throw new Error(
|
||||
"Unauthenticated: ClassCharts returned an error: " +
|
||||
response.status +
|
||||
" " +
|
||||
response.statusText,
|
||||
"Unauthenticated: ClassCharts didn't return authentication cookies",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -56,19 +55,20 @@ export class ParentClient extends BaseClient {
|
|||
const sessionID = JSON.parse(
|
||||
String(sessionCookies["parent_session_credentials"]),
|
||||
);
|
||||
super.sessionId = sessionID.session_id;
|
||||
this.sessionId = sessionID.session_id;
|
||||
this.pupils = await this.getPupils();
|
||||
if (!this.pupils) throw new Error("Account has no pupils attached");
|
||||
super.studentId = this.pupils[0].id;
|
||||
this.studentId = this.pupils[0].id;
|
||||
}
|
||||
/**
|
||||
* Get a list of pupils connected to this parent's account
|
||||
* @returns an array of Pupils connected to this parent's account
|
||||
*/
|
||||
async getPupils(): Promise<GetPupilsResponse> {
|
||||
return await super.makeAuthedRequest(super.API_BASE + "/pupils", {
|
||||
const response = await this.makeAuthedRequest(this.API_BASE + "/pupils", {
|
||||
method: "GET",
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
/**
|
||||
* Selects a pupil to be used with API requests
|
||||
|
|
@ -82,7 +82,7 @@ export class ParentClient extends BaseClient {
|
|||
for (let i = 0; i < pupils.length; i++) {
|
||||
const pupil = pupils[i];
|
||||
if (pupil.id == pupilId) {
|
||||
super.studentId = pupil.id;
|
||||
this.studentId = pupil.id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
35
src/core/parentClient_test.ts
Normal file
35
src/core/parentClient_test.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { assertRejects } from "~/deps_dev.ts";
|
||||
import { ParentClient } from "~/src/core/parentClient.ts";
|
||||
|
||||
Deno.test("Throws when no email is provided", async () => {
|
||||
const client = new ParentClient("", "password");
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await client.login();
|
||||
},
|
||||
Error,
|
||||
"Email not provided",
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("Throws when no password is provided", async () => {
|
||||
const client = new ParentClient("email", "");
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await client.login();
|
||||
},
|
||||
Error,
|
||||
"Password not provided",
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("Throws with invalid username and password", async () => {
|
||||
const client = new ParentClient("invalid", "invalid");
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await client.login();
|
||||
},
|
||||
Error,
|
||||
"Unauthenticated: ClassCharts didn't return authentication cookies",
|
||||
);
|
||||
});
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { API_BASE_STUDENT, BASE_URL } from "../utils/consts.ts";
|
||||
import { BaseClient } from "./baseClient.ts";
|
||||
import { parseCookies } from "../utils/utils.ts";
|
||||
import { RewardPurchaseResponse, RewardsResponse } from "../types.ts"
|
||||
import { API_BASE_STUDENT, BASE_URL } from "~/src/utils/consts.ts";
|
||||
import { BaseClient } from "~/src/core/baseClient.ts";
|
||||
import { parseCookies } from "~/src/utils/utils.ts";
|
||||
import { RewardPurchaseResponse, RewardsResponse } from "~/src/types.ts"
|
||||
|
||||
/**
|
||||
* Student Client
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { assertRejects } from "https://deno.land/std@0.200.0/assert/mod.ts";
|
||||
|
||||
import { StudentClient } from "./studentClient.ts";
|
||||
import { assertRejects } from "~/deps_dev.ts";
|
||||
import { StudentClient } from "~/src/core/studentClient.ts";
|
||||
|
||||
Deno.test("Throws when no student code is provided", async () => {
|
||||
const client = new StudentClient("");
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
import {
|
||||
assertEquals,
|
||||
assertExists,
|
||||
} from "https://deno.land/std@0.200.0/assert/mod.ts";
|
||||
|
||||
import { assertEquals, assertExists } from "~/deps_dev.ts";
|
||||
import { parseCookies } from "./utils.ts";
|
||||
Deno.test("Parses simple cookie", () => {
|
||||
const cookie =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue