{"id":13606470,"url":"https://github.com/Harry-Chen/thu-learn-lib","last_synced_at":"2025-04-12T08:31:18.191Z","repository":{"id":34077200,"uuid":"168858420","full_name":"Harry-Chen/thu-learn-lib","owner":"Harry-Chen","description":"A JavaScript library to provide a program-friendly interface to Web Learning of Tsinghua University","archived":false,"fork":false,"pushed_at":"2025-03-18T08:52:44.000Z","size":1741,"stargazers_count":71,"open_issues_count":0,"forks_count":10,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-05T16:02:45.265Z","etag":null,"topics":["tsinghua-university","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/thu-learn-lib","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Harry-Chen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-02T17:36:34.000Z","updated_at":"2025-03-18T08:52:47.000Z","dependencies_parsed_at":"2024-01-14T05:00:04.646Z","dependency_job_id":"21e91c8a-667f-4b3b-834f-8358f69e0f63","html_url":"https://github.com/Harry-Chen/thu-learn-lib","commit_stats":{"total_commits":269,"total_committers":14,"mean_commits":"19.214285714285715","dds":0.379182156133829,"last_synced_commit":"d5af680ca30201671ee64b90cc2b4dfc1fec190c"},"previous_names":[],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harry-Chen%2Fthu-learn-lib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harry-Chen%2Fthu-learn-lib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harry-Chen%2Fthu-learn-lib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harry-Chen%2Fthu-learn-lib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Harry-Chen","download_url":"https://codeload.github.com/Harry-Chen/thu-learn-lib/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248360298,"owners_count":21090673,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["tsinghua-university","typescript"],"created_at":"2024-08-01T19:01:09.420Z","updated_at":"2025-04-12T08:31:13.184Z","avatar_url":"https://github.com/Harry-Chen.png","language":"TypeScript","funding_links":[],"categories":["项目","TypeScript"],"sub_categories":[],"readme":"# thu-learn-lib\n\n[![Build and Publish](https://github.com/Harry-Chen/thu-learn-lib/workflows/Build%20and%20Publish/badge.svg?event=push)](https://github.com/Harry-Chen/thu-learn-lib/actions?query=workflow%3A%22Build+and+Publish%22)\n[![Github version](https://img.shields.io/github/package-json/v/Harry-Chen/thu-learn-lib)](https://github.com/Harry-Chen/thu-learn-lib)\n[![npm version](https://img.shields.io/npm/v/thu-learn-lib)](https://www.npmjs.com/package/thu-learn-lib)\n![npm size](https://img.shields.io/bundlephobia/min/thu-learn-lib)\n![npm downloads](https://img.shields.io/npm/dw/thu-learn-lib)\n\nThis is a JavaScript library aimed to provide a program-friendly interface of [web Learning of Tsinghua University](https://learn.tsinghua.edu.cn).\n\nThis project is licensed under MIT License.\n\n## Compatibility\n\nThe library uses [`node-fetch-cookie-native`](https://github.com/AsakuraMizu/node-fetch-cookie-native), which is a simple wrapper for [node-fetch-native](https://github.com/unjs/node-fetch-native) and [fetch-cookie](https://github.com/valeriangalliat/fetch-cookie), providing cookie and redirection support in both browsers and Node.\n\nIn case of any syntax problems, just upgrade your browser / Node, or use any corresponding polyfills.\n\n## Installation\n\n### Node / Bundler\n\n```bash\nyarn add thu-learn-lib\n```\n\n### Browser (IIFE)\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/thu-learn-lib@3\"\u003e\u003c/script\u003e\n\u003c!-- or --\u003e\n\u003cscript src=\"https://unpkg.com/thu-learn-lib@3\"\u003e\u003c/script\u003e\n```\n\nThe library is exposed under `window.LearnLib`.\n\n### Browser (ESM)\n\n```html\n\u003cscript type=\"module\"\u003e\n  import { Learn2018Helper } from 'https://esm.sh/thu-learn-lib@3';\n\u003c/script\u003e\n```\n\n## Build\n\n```\nyarn run build\n```\n\nYou can find the bundled library in `lib/`.\n\n- `index.js`: ES module entry\n- `index.d.ts`: definition file for TypeScript\n- `index.global.js{,.map}`: IIFE for use in browser (with source map for debugging)\n\n## Development in browser\n\n```\nyarn run dev\n```\n\nThis will open a dev browser with a testing extension. Click the `t` icon in extension bar, then execute anything you want in the Console of Chrome Developer Tool.\nThe library is exposed under `window.LearnLib`.\n\nUse `yarn run dev:build` to build the extension that can be installed to your chrome browser manually.\n\n## Usage\n\n### Authentication related (important changes since v1.2.0)\n\n```typescript\nimport { Learn2018Helper } from 'thu-learn-lib';\n\n// There are three ways of logging in:\n\n// 1. provide a cookie jar with existing cookies (see `tough-cookie`)\nconst helper = new Learn2018Helper({ cookieJar });\n// 2. provide nothing, but invoking login with username and password\nconst helper = new Learn2018Helper();\n// 3. provide a CredentialProvider function, which can be async\nconst helper = new Learn2018Helper({\n  provider: () =\u003e ({ username, password }),\n});\n\n// Note that by using the following two methods you may encounter problems like login time out.\n// But if you provide a credential provider, the library will retry logging in when failing, automatically resolving the cookie expiry problem.\n// So we strongly recommend using this method.\n\n// If you do not provide a cookie jar or CredentialProvider, you must log in manually. Otherwise you do not need to call login explicitly.\ntry {\n  await helper.login(username, password);\n} catch (e) {\n  // e is a FailReason\n}\n\n// You can also take out cookies (e.g. for file download), which will not work in browsers.\nconsole.log(helper.cookieJar);\n\n// Logout if you want, but the cookie jar will not be cleared.\nawait helper.logout();\n```\n\n### Content related\n\nWe currently support both student and teacher (or TA) version of web learning. To keep backwards compatibility, the **default behavior of all APIs is to use the student version**. The following APIs needs `CourseType.TEACHER` as the last (optional) parameter to access the teacher version. You **should use them when you are the teacher / TA** of one course, for you will get nothing from the student version in that case.\n\nWe do not maintain a global type in `Learn2018Helper` class, for there can be the situation that one can be a student and teacher of the same course simultaneously, on which by using different `CourseType` you can get different results.\n\n- `getCourseList`\n- `getNotificationList/getFileList/getHomeworkList/getDiscussionList/getAnsweredQuestionList`\n- `getAllContents`\n\nNote that currently fetching homework information from teacher version is **partially implemented**.\n\n```typescript\nimport { ContentType, ApiError } from 'thu-learn-lib';\n\n// get ids of all semesters that current account has access to\nconst semesters = await helper.getSemesterIdList();\n\n// get get semester info\nconst semester = await helper.getCurrentSemester();\n\n// get courses of this semester\nconst courses = await helper.getCourseList(semester.id);\nconst course = courses[0];\n\n// get detail information about the course\nconst discussions = await helper.getDiscussionList(course.id);\nconst notifications = await helper.getNotificationList(course.id);\nconst files = await helper.getFileList(course.id);\nconst homework = await helper.getHomeworkList(course.id);\nconst questions = await helper.getAnsweredQuestionList(course.id);\n\n// get content from bunches of courses\n// the return type will be { [id: string]: Content }\n// where Content = Notification | File | Homework | Discussion | Question\nconst homeworks = await helper.getAllContents([1, 2, 3], ContentType.HOMEWORK);\n\n// get course calendar in a period\ntry {\n  const calendar = await helper.getCalendar('20191001', '20191201');\n} catch (e) {\n  const error = e as ApiError;\n  // check e.reason and e.extra for information\n  // you might want to check your date format or shrink the range (currently we observe a limit of 29 days)\n}\n```\n\nAccording to security strategies (CORS, CORB) of browsers, you might need to run the code in the page context of `https://learn.tsinghua.edu.cn` and `https://id.tsinghua.edu.cn`. The simplest way is to run the code in Node.js or in [browser extension](#development-in-browser).\n\n## Typing\n\nSee `src/types.ts` for type definitions. Note that `ApiError` represents the type that will be used in rejected Promises.\n\n## Testing\n\nRun `yarn test` for testing. It requires your personal credential since we don't have mocks for these APIs. To do this, you must touch a `.env` similar to `template.env` under /test folder.\n\nIt's ok if you meet `Timeout * Async callback was not invoked within the 5000ms timeout...` error when running tests, rerun tests may resolve this problem. If you hate this, just add the third argument `timeout` to every testcase `it(\"should...\", async () =\u003e void, timeout)` and make sure it's greater than 5000.\n\n## Changelog\n\n- v3.2.1\n  - Upgrade to eslint v9\n  - Add `setCSRFToken` function to manually reuse previous (maybe valid) token and prevent unnecessary re-login (see [#49](https://github.com/Harry-Chen/thu-learn-lib/issues/49))  \n    *Note:* To use this feature in Node.js, `cookieJar` should also be reused, otherwise it will not work. (not the case in browser env)\n  - Fix `CourseContent` type: default value for type param `T` (breaking change introduced in [#53](https://github.com/Harry-Chen/thu-learn-lib/issues/53))\n  - *(Breaking...?)* Rename `File.id2` added in previous version to actual `id` and previously used `id` to  `fileId` (see [#60](https://github.com/Harry-Chen/thu-learn-lib/issues/60))\n  - Upgrade dependencies\n- v3.2.0\n  - Support file categories (see [#57](https://github.com/Harry-Chen/thu-learn-lib/issues/57)):\n    - Add `FileCategory` type and optional `category` field in `File` type\n    - Now `getFileList` function automatically fetches all categories and saves them in each `File` object\n    - Add `getFileCategoryList` function to fetch file categories\n    - Add `getFileListByCategory` function to get file list by category\n  - Fix content of file download url and visit count in for `CourseType.TEACHER`\n- v3.1.4\n  - Allow and check for undefined credential in login (see [#52](https://github.com/Harry-Chen/thu-learn-lib/issues/52))\n  - Discriminate `getAllContents` return type based on input content type (see [#53](https://github.com/Harry-Chen/thu-learn-lib/issues/53))\n  - Use `searchParams` to set csrf token \u0026 add csrf token to `getCalendar` (see [#54](https://github.com/Harry-Chen/thu-learn-lib/issues/54))\n  - Update bunches of dependencies\n- v3.1.3\n  - Fix empty time and location of course (see [#145](https://github.com/Harry-Chen/Learn-Helper/issues/145))\n- v3.1.2\n  - Fix empty course name parsing\n  - (Maybe BEARKING) `Homework.gradeLevel` changed to `HomeworkGradeLevel` (a string enum) for better i18n\n  - Fix get language\n- v3.1.1\n  - Remove `fetch-cookie` dependency in browser build, reducing bundle size\n  - Add `getUserInfo` interface (#48, thanks to @robertying)\n- v3.1.0\n  - **Refactor**:\n    - Build tool: `webpack` -\u003e `tsup`\n    - Development tool: `webpack` -\u003e `vite`\n    - Test tool: `jest` -\u003e `vitest`\n    - Fetch:\n      - `cross-fetch` -\u003e `node-fetch-native` (Node.js now has native `fetch`)\n      - `real-isomorphic-fetch` -\u003e `fetch-cookie` (`fetch-cookie` now can handle redirects)\n      - `tough-cookie-no-native` -\u003e `tough-cookie` (`tough-cookie` is now native)\n    - **(BREAKING)** Updated library output structure, now everything exported in index, cannot use `/lib` or `/lib/types` anymore\n  - Added:\n    - Submit homework\n    - Language switching and related behaviour\n    - Get TA's homework info (partial support)\n  - Fixed:\n    - **Web Learning API update**\n    - Decode course name\n  - Other:\n    - Move `fake-parse5` to [a seperate library](https://github.com/AsakuraMizu/fake-parse5)\n- v3.0.4\n  - No feature changes, upgrade dependencies\n- v3.0.3\n  - No feature changes, upgrade dependencies\n- v3.0.2\n  - No feature changes, upgrade dependencies to mitigate security vulnerabilities\n- v3.0.1\n  - Add config `generatePreviewUrlForFirstPage` to switch preview URL type (default to `true`)\n- v3.0.0\n  - (BREAKING CHANGE) Redesign exported types, use `RemoteFile` to represent a file on Web Learning\n  - Add support for parsing attachment sizes \u0026 preview URLs in homework \u0026 notifications (Harry-Chen/Learn-Helper#109)\n- v2.5.4\n  - Fix (sometimes) incorrect publish time of notifications (#36)\n- v2.5.3\n  - Add `allowFailure` in `getAllContents` for convenience\n- v2.5.2\n  - Allow retrieving CSRF token via `getCSRFToken` method\n  - Export `addCSRFTokenToUrl` function as API for convenience\n- v2.5.1\n  - No feature change, add support for direct `import` in Node.js\n- v2.5.0\n  - Add transparent support for CSRF token (recently deployed) in all Web Learning APIs\n- v2.4.2\n  - No functionality change, bump some dependencies to mitigate security concerns\n- v2.4.1\n  - Replace `parse5` with `htmlparser2` in Cheerio and remove it from bundled file (replaced with `src/fake-parse5`)\n  - Replace TSLint with ESLint\n- v2.4.0\n  - Upgrade to TypeScript 4.1 \u0026 Webpack 5.15\n  - Add more null checking for disabled functionalities (see [xxr3376/Learn-Project#90](https://github.com/xxr3376/Learn-Project/issues/90))\n- v2.3.2\n  - Fix a problem in `v2.3.1` (not published) and `v2.3.0` that build output fails to be uploaded to npm\n- v2.3.0\n  - Refine error detecting \u0026 handling by using `ApiError` in usage of `Promise.reject` (might be a breaking change)\n- v2.2.3\n  - Add workaround for some strange behaviors in teacher mode (thanks to @MashPlant)\n- v2.2.2\n  - Return error when API return any non-success result\n- v2.2.1\n  - Fix a missing parameter in `previewUrl`\n- v2.2.0\n  - Use ECMAScript private fields in `Learn2018Helper` class to protect credentials\n  - Add `previewUrl` to `File`\n  - Upgrade to TypeScript 3.8.2\n- v2.1.2\n  - Fix problem in invoking JSONP callback (because some engines might do JIT)\n- v2.1.1\n  - Remove usage of `eval` in `getCalendar`\n- v2.1.0\n  - Catch errors returned by calendar API and throw user-defined error\n  - Add documentation for all public APIs\n- v2.0.0\n  - Use ES2018 in generated library\n  - Add `FailReason` to represent all strings that will be used as the reason of rejected Promises\n  - `login` and `logout` no longer return Promises\n- v1.2.2\n  - Fix a function signature to keep compatibility\n- v1.2.1\n  - Support TA version of many APIs (see above for usage)\n  - Fix some wrong URLs in fetched data\n- v1.2.0\n  - Support getting course calendars from academic.tsinghua.edu.cn (thanks to robertying)\n  - Automatic retry logging in when fetching failed and `CredentialProvider` is provided (thanks to mayeths)\n  - Add unit tests using `jest` (thanks to mayeths)\n  - Filter out `null` values in `getSemesterIdList` API\n  - Switch to `https://learn.tsinghua.edu.cn/` from `learn2018` permanently\n- v1.1.4\n  - Return empty array if any content module is disabled\n  - Add `getTACourseList` to get TA's course list (temporarily can not be used by other functions)\n- v1.1.3\n  - Emergency fix of wrongly decoded base64 string, add `js-base64` back\n- v1.1.2\n  - Switch to `Base64.js` instead of `js-base64`, which uses evil `eval`\n- v1.1.1\n  - Decode HTML entities in the title of disscussions (the last one, I promise!)\n- v1.1.0\n  - Fix an typo in grade level mapping\n  - Bump to a new minor version\n- v1.0.16 (no v1.0.15 due to some publishing issues)\n  - Switch to `yarn`\n  - Add parsing of grade levels of homework (A+/A/.../F)\n- v1.0.14\n  - Add prefix for `attachmentUrl` filed of Notification\n  - Deprecate all old versions\n- v1.0.13\n  - Decode HTML entities whenever possible\n- v1.0.12\n  - Add `url` for Course\n  - Fix `url` for Question (to display correct section name)\n- v1.0.11\n  - Fix `url` error in Question\n- v1.0.10\n  - Decode the HTML entities in the `description` field of homework\n- v1.0.9\n  - Use `entities` to decode HTML entities\n- v1.0.8\n  - Export type CourseContent\n- v1.0.7\n  - No change made to code, update README\n- v1.0.6\n  - Add API to fetching content for a list of courses\n- v1.0.5\n  - Fix HTML entity replacement.\n- v1.0.4\n  - No change made to code\n  - Remove unused build commands\n  - Fix multiple typos in README\n- v1.0.3\n  - Add real logout API (thank @zhaofeng-shu33)\n- v1.0.2\n  - Add API to get IDs of all semesters (thank @jiegec)\n- v1.0.1\n  - Expose CookieJar in helper class\n  - Fix some HTML entity decoding problems\n  - **Rename of some APIs** (break compatibility before we have actual users)\n- v1.0.0\n  - First release\n  - Support parsing of notification, homework, file, discussion and **answered** questions\n\n## Projects using this library\n\n- [Harry-Chen/Learn Project](https://github.com/Harry-Chen/Learn-Project)\n- [jiegec/clone-learn-tsinghua](https://github.com/jiegec/clone-learn-tsinghua)\n- [robertying/learnX](https://github.com/robertying/learnX) (customized fork)\n- [Konano/thu-weblearn-tgbot](https://github.com/Konano/thu-weblearn-tgbot)\n- [Starrah/THUCourseHelper](https://github.com/Starrah/THUCourseHelper)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHarry-Chen%2Fthu-learn-lib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHarry-Chen%2Fthu-learn-lib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHarry-Chen%2Fthu-learn-lib/lists"}