@robertying/thu-learn-lib 4.1.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -7
- package/lib/auth.d.ts +1 -1
- package/lib/auth.d.ts.map +1 -1
- package/lib/auth.js +17 -5
- package/lib/auth.js.map +1 -1
- package/lib/calendar.d.ts +6 -4
- package/lib/calendar.d.ts.map +1 -1
- package/lib/calendar.js +21 -8
- package/lib/calendar.js.map +1 -1
- package/lib/contents.d.ts +4 -4
- package/lib/contents.d.ts.map +1 -1
- package/lib/contents.js +28 -20
- package/lib/contents.js.map +1 -1
- package/lib/courses.d.ts +5 -3
- package/lib/courses.d.ts.map +1 -1
- package/lib/courses.js +24 -12
- package/lib/courses.js.map +1 -1
- package/lib/discussions.js +2 -2
- package/lib/discussions.js.map +1 -1
- package/lib/favorites.d.ts.map +1 -1
- package/lib/favorites.js +12 -12
- package/lib/favorites.js.map +1 -1
- package/lib/files.d.ts +1 -1
- package/lib/files.d.ts.map +1 -1
- package/lib/files.js +10 -8
- package/lib/files.js.map +1 -1
- package/lib/homework.d.ts +11 -4
- package/lib/homework.d.ts.map +1 -1
- package/lib/homework.js +46 -43
- package/lib/homework.js.map +1 -1
- package/lib/index.d.ts +47 -13
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +63 -17
- package/lib/index.js.map +1 -1
- package/lib/notices.d.ts +11 -3
- package/lib/notices.d.ts.map +1 -1
- package/lib/notices.js +40 -36
- package/lib/notices.js.map +1 -1
- package/lib/questionnaires.d.ts +6 -3
- package/lib/questionnaires.d.ts.map +1 -1
- package/lib/questionnaires.js +20 -12
- package/lib/questionnaires.js.map +1 -1
- package/lib/request.d.ts +66 -10
- package/lib/request.d.ts.map +1 -1
- package/lib/request.js +234 -50
- package/lib/request.js.map +1 -1
- package/lib/types.d.ts +52 -3
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +1 -0
- package/lib/types.js.map +1 -1
- package/lib/user.js +1 -1
- package/lib/user.js.map +1 -1
- package/lib/utils.d.ts +3 -0
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +11 -3
- package/lib/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/auth.ts +18 -5
- package/src/calendar.ts +28 -10
- package/src/contents.ts +30 -25
- package/src/courses.ts +31 -19
- package/src/discussions.ts +2 -2
- package/src/favorites.ts +22 -32
- package/src/files.ts +12 -12
- package/src/homework.ts +118 -123
- package/src/index.ts +94 -19
- package/src/notices.ts +58 -59
- package/src/questionnaires.ts +51 -37
- package/src/request.ts +260 -48
- package/src/types.ts +62 -2
- package/src/user.ts +1 -1
- package/src/utils.ts +14 -3
package/lib/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import * as notices from './notices.js';
|
|
|
10
10
|
import * as questionnaires from './questionnaires.js';
|
|
11
11
|
import { Session } from './request.js';
|
|
12
12
|
import { CourseType } from './types.js';
|
|
13
|
+
import * as URLS from './urls.js';
|
|
13
14
|
import * as user from './user.js';
|
|
14
15
|
export { addCSRFTokenToUrl } from './request.js';
|
|
15
16
|
export * from './types.js';
|
|
@@ -18,7 +19,7 @@ export class Learn2018Helper {
|
|
|
18
19
|
#session;
|
|
19
20
|
/** you can provide a CookieJar and / or CredentialProvider in the configuration */
|
|
20
21
|
constructor(config) {
|
|
21
|
-
this.#session = new Session(config, () =>
|
|
22
|
+
this.#session = new Session(config, () => auth.login(this.#session));
|
|
22
23
|
}
|
|
23
24
|
/** whether preview URLs open the first page only (`HelperConfig.generatePreviewUrlForFirstPage`) */
|
|
24
25
|
get previewFirstPage() {
|
|
@@ -42,9 +43,23 @@ export class Learn2018Helper {
|
|
|
42
43
|
async getRoamingTicket(username, password, fingerPrint, fingerGenPrint = '', fingerGenPrint3 = '') {
|
|
43
44
|
return auth.getRoamingTicket(this.#session, username, password, fingerPrint, fingerGenPrint, fingerGenPrint3);
|
|
44
45
|
}
|
|
45
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Login is necessary if you do not provide a `CredentialProvider`.
|
|
48
|
+
* Without credentials it uses the provider, and concurrent calls share one SSO login. Logins never overlap: one with
|
|
49
|
+
* credentials waits for a login in progress, and requests that find the session expired meanwhile wait for it.
|
|
50
|
+
*/
|
|
46
51
|
async login(username, password, fingerPrint, fingerGenPrint, fingerGenPrint3) {
|
|
47
|
-
|
|
52
|
+
if (!username || !password || !fingerPrint)
|
|
53
|
+
return this.#session.relogin();
|
|
54
|
+
return this.#session.runLogin(() => auth.login(this.#session, username, password, fingerPrint, fingerGenPrint, fingerGenPrint3));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Make sure the session is usable without a full SSO login when possible: with a CSRF token (from an earlier login
|
|
58
|
+
* or `setCSRFToken`), make one cheap request and log in again only if the session has expired; without one, log in.
|
|
59
|
+
* Use it when resuming an app instead of `login()`.
|
|
60
|
+
*/
|
|
61
|
+
async ensureSession() {
|
|
62
|
+
return this.#session.ensureSession(URLS.LEARN_CURRENT_SEMESTER());
|
|
48
63
|
}
|
|
49
64
|
/** logout (to make everyone happy) */
|
|
50
65
|
async logout() {
|
|
@@ -57,7 +72,8 @@ export class Learn2018Helper {
|
|
|
57
72
|
/**
|
|
58
73
|
* Get calendar items during the specified period (in yyyymmdd format, both inclusive).
|
|
59
74
|
* Ranges longer than 28 days are fetched in windows and merged; windows that fail even after a retry are listed in
|
|
60
|
-
* `failedRanges`. Rejects only when every window fails (usually with `FailReason.INVALID_RESPONSE`)
|
|
75
|
+
* `failedRanges`. Rejects only when every window fails (usually with `FailReason.INVALID_RESPONSE`), or with a
|
|
76
|
+
* `RangeError` for a date that is not a valid yyyymmdd.
|
|
61
77
|
*/
|
|
62
78
|
async getCalendar(startDate, endDate, options) {
|
|
63
79
|
return calendar.getCalendar(this.#session, startDate, endDate, options);
|
|
@@ -68,20 +84,36 @@ export class Learn2018Helper {
|
|
|
68
84
|
async getCurrentSemester() {
|
|
69
85
|
return courses.getCurrentSemester(this.#session);
|
|
70
86
|
}
|
|
71
|
-
/**
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Get all courses in the specified semester.
|
|
89
|
+
* `timeAndLocation` is only fetched (one request per course) with `options.timeAndLocation`.
|
|
90
|
+
*/
|
|
91
|
+
async getCourseList(semesterID, courseType = CourseType.STUDENT, lang = this.#session.lang, options) {
|
|
92
|
+
return courses.getCourseList(this.#session, semesterID, courseType, lang, options);
|
|
93
|
+
}
|
|
94
|
+
/** Get the time and location of one course. */
|
|
95
|
+
async getCourseTimeAndLocation(courseID) {
|
|
96
|
+
return courses.getCourseTimeAndLocation(this.#session, courseID);
|
|
74
97
|
}
|
|
75
98
|
/**
|
|
76
99
|
* Get certain type of content of all specified courses.
|
|
77
|
-
* It
|
|
100
|
+
* It wraps around the `getXXX` list functions; a course that fails is reported in `errors` instead of failing
|
|
101
|
+
* the rest. `options.details` is passed on as homework `details` or notification `attachments`.
|
|
102
|
+
*/
|
|
103
|
+
async getAllContents(courseIDs, type, options) {
|
|
104
|
+
return contents.getAllContents(this.#session, courseIDs, type, options);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get all notifications (课程公告) of the specified course.
|
|
108
|
+
* Attachments are only fetched (one request per notice) for the notices `options.attachments` selects;
|
|
109
|
+
* use `getNotificationAttachment` for the others.
|
|
78
110
|
*/
|
|
79
|
-
async
|
|
80
|
-
return
|
|
111
|
+
async getNotificationList(courseID, courseType = CourseType.STUDENT, options) {
|
|
112
|
+
return notices.getNotificationList(this.#session, courseID, courseType, options);
|
|
81
113
|
}
|
|
82
|
-
/** Get
|
|
83
|
-
async
|
|
84
|
-
return notices.
|
|
114
|
+
/** Get the attachment of a notice (one request), `undefined` if it has none. */
|
|
115
|
+
async getNotificationAttachment(notification, courseType = CourseType.STUDENT) {
|
|
116
|
+
return notices.getNotificationAttachment(this.#session, notification, courseType);
|
|
85
117
|
}
|
|
86
118
|
/** Get all files (课程文件) of the specified course. */
|
|
87
119
|
async getFileList(courseID, courseType = CourseType.STUDENT) {
|
|
@@ -98,10 +130,18 @@ export class Learn2018Helper {
|
|
|
98
130
|
async getFileListByCategory(courseID, categoryId, courseType = CourseType.STUDENT) {
|
|
99
131
|
return files.getFileListByCategory(this.#session, courseID, categoryId, courseType);
|
|
100
132
|
}
|
|
101
|
-
async getHomeworkList(courseID, courseType = CourseType.STUDENT) {
|
|
133
|
+
async getHomeworkList(courseID, courseType = CourseType.STUDENT, options) {
|
|
102
134
|
return courseType === CourseType.TEACHER
|
|
103
135
|
? homework.getHomeworkList(this.#session, courseID, CourseType.TEACHER)
|
|
104
|
-
: homework.getHomeworkList(this.#session, courseID, CourseType.STUDENT);
|
|
136
|
+
: homework.getHomeworkList(this.#session, courseID, CourseType.STUDENT, options);
|
|
137
|
+
}
|
|
138
|
+
/** Get the detail (page content, attachments and description) of one homework. */
|
|
139
|
+
async getHomeworkDetail(item) {
|
|
140
|
+
return homework.getHomeworkDetail(this.#session, item);
|
|
141
|
+
}
|
|
142
|
+
/** Get the detail (page content, attachments and description) of one excellent homework. */
|
|
143
|
+
async getExcellentHomeworkDetail(item) {
|
|
144
|
+
return homework.getHomeworkDetail(this.#session, item);
|
|
105
145
|
}
|
|
106
146
|
/** Get all discussions (课程讨论) of the specified course. */
|
|
107
147
|
async getDiscussionList(courseID, courseType = CourseType.STUDENT) {
|
|
@@ -116,9 +156,15 @@ export class Learn2018Helper {
|
|
|
116
156
|
}
|
|
117
157
|
/**
|
|
118
158
|
* Get all questionnaires (课程问卷/QNR) of the specified course.
|
|
159
|
+
* Questions (`detail`, one request per questionnaire) for the questionnaires `options.details` selects, by default
|
|
160
|
+
* all; use `getQuestionnaireDetail` for the others.
|
|
119
161
|
*/
|
|
120
|
-
async getQuestionnaireList(courseID) {
|
|
121
|
-
return questionnaires.getQuestionnaireList(this.#session, courseID);
|
|
162
|
+
async getQuestionnaireList(courseID, options) {
|
|
163
|
+
return questionnaires.getQuestionnaireList(this.#session, courseID, options);
|
|
164
|
+
}
|
|
165
|
+
/** Get the questions of one questionnaire (one request). */
|
|
166
|
+
async getQuestionnaireDetail(courseID, questionnaireID) {
|
|
167
|
+
return questionnaires.getQuestionnaireDetail(this.#session, courseID, questionnaireID);
|
|
122
168
|
}
|
|
123
169
|
/**
|
|
124
170
|
* Add an item to favorites. (收藏)
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/notices.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { Session } from './request.ts';
|
|
2
|
-
import type { Notification } from './types.ts';
|
|
2
|
+
import type { INotification, Notification, NotificationListOptions, RemoteFile } from './types.ts';
|
|
3
3
|
import { CourseType } from './types.ts';
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Get all notifications (课程公告) of the specified course: current and expired lists.
|
|
6
|
+
* Attachments only for the notices `options.attachments` selects.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getNotificationList(s: Session, courseID: string, courseType?: CourseType, options?: NotificationListOptions): Promise<Notification[]>;
|
|
9
|
+
/**
|
|
10
|
+
* Get the attachment of a notice from its detail page (1 request), or `undefined` without a request if
|
|
11
|
+
* `attachmentName` says it has none, or if the page has no attachment link.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getNotificationAttachment(s: Session, notification: Pick<INotification, 'url' | 'attachmentName'>, courseType?: CourseType): Promise<RemoteFile | undefined>;
|
|
6
14
|
//# sourceMappingURL=notices.d.ts.map
|
package/lib/notices.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notices.d.ts","sourceRoot":"","sources":["../src/notices.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"notices.d.ts","sourceRoot":"","sources":["../src/notices.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAe,UAAU,EAAc,MAAM,YAAY,CAAC;AAIjE;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,UAA+B,EAC3C,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,YAAY,EAAE,CAAC,CAWzB;AAwCD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,CAAC,EAAE,OAAO,EACV,YAAY,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,gBAAgB,CAAC,EAC3D,UAAU,GAAE,UAA+B,GAC1C,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CA6BjC"}
|
package/lib/notices.js
CHANGED
|
@@ -3,19 +3,27 @@ import { Base64 } from 'js-base64';
|
|
|
3
3
|
import { $, YES } from './request.js';
|
|
4
4
|
import { ContentType, CourseType, FailReason } from './types.js';
|
|
5
5
|
import * as URLS from './urls.js';
|
|
6
|
-
import { decodeHTML, trimAndDefine } from './utils.js';
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import { decodeHTML, isSelected, trimAndDefine } from './utils.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get all notifications (课程公告) of the specified course: current and expired lists.
|
|
9
|
+
* Attachments only for the notices `options.attachments` selects.
|
|
10
|
+
*/
|
|
11
|
+
export async function getNotificationList(s, courseID, courseType = CourseType.STUDENT, options = {}) {
|
|
12
|
+
const lists = await Promise.all([
|
|
10
13
|
getNotificationListKind(s, courseID, courseType, false),
|
|
11
14
|
getNotificationListKind(s, courseID, courseType, true),
|
|
12
|
-
])
|
|
15
|
+
]);
|
|
16
|
+
return Promise.all(lists.flat().map(async (n) => {
|
|
17
|
+
if (!n.attachmentName || !isSelected(options.attachments, n))
|
|
18
|
+
return n;
|
|
19
|
+
return { ...n, attachment: await getNotificationAttachment(s, n, courseType) };
|
|
20
|
+
}));
|
|
13
21
|
}
|
|
14
22
|
async function getNotificationListKind(s, courseID, courseType, expired) {
|
|
15
|
-
const json = await
|
|
23
|
+
const json = await s.fetchJsonWithToken(URLS.LEARN_NOTIFICATION_LIST(courseType, expired), {
|
|
16
24
|
method: 'POST',
|
|
17
25
|
body: URLS.LEARN_PAGE_LIST_FORM_DATA(courseID),
|
|
18
|
-
})
|
|
26
|
+
});
|
|
19
27
|
if (json.result !== 'success') {
|
|
20
28
|
return Promise.reject({
|
|
21
29
|
reason: FailReason.INVALID_RESPONSE,
|
|
@@ -23,8 +31,9 @@ async function getNotificationListKind(s, courseID, courseType, expired) {
|
|
|
23
31
|
});
|
|
24
32
|
}
|
|
25
33
|
const result = (json.object?.aaData ?? json.object?.resultsList ?? []);
|
|
26
|
-
return
|
|
27
|
-
const
|
|
34
|
+
return result.map((n) => {
|
|
35
|
+
const attachmentName = courseType === CourseType.STUDENT ? n.fjmc : n.fjbt;
|
|
36
|
+
return {
|
|
28
37
|
id: n.ggid,
|
|
29
38
|
content: Base64.decode(n.ggnr ?? ''),
|
|
30
39
|
title: decodeHTML(n.bt),
|
|
@@ -36,49 +45,44 @@ async function getNotificationListKind(s, courseID, courseType, expired) {
|
|
|
36
45
|
expireTime: n.jzsj ?? undefined,
|
|
37
46
|
isFavorite: n.sfsc === YES,
|
|
38
47
|
comment: n.bznr ?? undefined,
|
|
48
|
+
attachmentName: typeof attachmentName === 'string' && attachmentName ? attachmentName : undefined,
|
|
39
49
|
};
|
|
40
|
-
|
|
41
|
-
const attachmentName = courseType === CourseType.STUDENT ? n.fjmc : n.fjbt;
|
|
42
|
-
if (attachmentName) {
|
|
43
|
-
detail = await parseNotificationDetail(s, courseID, notification.id, courseType, attachmentName);
|
|
44
|
-
}
|
|
45
|
-
return { ...notification, ...detail };
|
|
46
|
-
}));
|
|
50
|
+
});
|
|
47
51
|
}
|
|
48
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Get the attachment of a notice from its detail page (1 request), or `undefined` without a request if
|
|
54
|
+
* `attachmentName` says it has none, or if the page has no attachment link.
|
|
55
|
+
*/
|
|
56
|
+
export async function getNotificationAttachment(s, notification, courseType = CourseType.STUDENT) {
|
|
57
|
+
if (!notification.attachmentName)
|
|
58
|
+
return undefined;
|
|
49
59
|
/// from JSON (backup, currently not used)
|
|
50
60
|
// const postParams = new FormData();
|
|
51
61
|
// postParams.append('id', id);
|
|
52
62
|
// postParams.append('wlkcid', courseID);
|
|
53
|
-
// const metadata = await
|
|
63
|
+
// const metadata = await s.fetchJsonWithToken(URL.LEARN_NOTIFICATION_EDIT(courseType), {
|
|
54
64
|
// 'method': 'POST',
|
|
55
65
|
// 'body': postParams,
|
|
56
|
-
// })
|
|
66
|
+
// });
|
|
57
67
|
// const attachmentId = metadata.ggfjid as string;
|
|
58
68
|
/// parsed from HTML
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
else {
|
|
66
|
-
path = result('#wjid').attr('href');
|
|
67
|
-
}
|
|
68
|
-
const size = trimAndDefine(result('div#attachment > div.fl > span[class^="color"]').first().text());
|
|
69
|
+
const result = $(await s.fetchTextWithToken(notification.url));
|
|
70
|
+
let path = (courseType === CourseType.STUDENT ? result('.ml-10') : result('#wjid')).attr('href');
|
|
71
|
+
// the page has no attachment link (removed since the list was fetched, or the page changed)
|
|
72
|
+
if (!path)
|
|
73
|
+
return undefined;
|
|
74
|
+
const size = trimAndDefine(result('div#attachment > div.fl > span[class^="color"]').first().text()) ?? '';
|
|
69
75
|
const params = new URLSearchParams(path.split('?').slice(-1)[0]);
|
|
70
76
|
const attachmentId = params.get('wjid');
|
|
71
77
|
if (!path.startsWith(URLS.LEARN_PREFIX)) {
|
|
72
78
|
path = URLS.LEARN_PREFIX + path;
|
|
73
79
|
}
|
|
74
80
|
return {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
size,
|
|
81
|
-
},
|
|
81
|
+
name: notification.attachmentName,
|
|
82
|
+
id: attachmentId,
|
|
83
|
+
downloadUrl: path,
|
|
84
|
+
previewUrl: URLS.LEARN_FILE_PREVIEW(ContentType.NOTIFICATION, attachmentId, courseType, s.previewFirstPage),
|
|
85
|
+
size,
|
|
82
86
|
};
|
|
83
87
|
}
|
|
84
88
|
//# sourceMappingURL=notices.js.map
|
package/lib/notices.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notices.js","sourceRoot":"","sources":["../src/notices.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"notices.js","sourceRoot":"","sources":["../src/notices.ts"],"names":[],"mappings":"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"}
|
package/lib/questionnaires.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Session } from './request.ts';
|
|
2
|
-
import type { Questionnaire } from './types.ts';
|
|
2
|
+
import type { Questionnaire, QuestionnaireDetail, QuestionnaireListOptions } from './types.ts';
|
|
3
3
|
/**
|
|
4
|
-
* Get all questionnaires (课程问卷/QNR) of the specified course.
|
|
4
|
+
* Get all questionnaires (课程问卷/QNR) of the specified course: ongoing and ended lists.
|
|
5
|
+
* Questions (`detail`, 1 request each) only for the questionnaires `options.details` selects (default `'all'`).
|
|
5
6
|
*/
|
|
6
|
-
export declare function getQuestionnaireList(s: Session, courseID: string): Promise<Questionnaire[]>;
|
|
7
|
+
export declare function getQuestionnaireList(s: Session, courseID: string, options?: QuestionnaireListOptions): Promise<Questionnaire[]>;
|
|
8
|
+
/** Get the questions of one questionnaire (1 request). */
|
|
9
|
+
export declare function getQuestionnaireDetail(s: Session, courseID: string, qnrID: string): Promise<QuestionnaireDetail[]>;
|
|
7
10
|
//# sourceMappingURL=questionnaires.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questionnaires.d.ts","sourceRoot":"","sources":["../src/questionnaires.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"questionnaires.d.ts","sourceRoot":"","sources":["../src/questionnaires.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAY,aAAa,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAKzG;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,aAAa,EAAE,CAAC,CAa1B;AA8BD,0DAA0D;AAC1D,wBAAsB,sBAAsB,CAC1C,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAwBhC"}
|
package/lib/questionnaires.js
CHANGED
|
@@ -2,18 +2,23 @@
|
|
|
2
2
|
import { YES } from './request.js';
|
|
3
3
|
import { FailReason, QuestionnaireType } from './types.js';
|
|
4
4
|
import * as URLS from './urls.js';
|
|
5
|
-
import { QNR_TYPE_MAP, decodeHTML } from './utils.js';
|
|
5
|
+
import { QNR_TYPE_MAP, decodeHTML, isSelected } from './utils.js';
|
|
6
6
|
/**
|
|
7
|
-
* Get all questionnaires (课程问卷/QNR) of the specified course.
|
|
7
|
+
* Get all questionnaires (课程问卷/QNR) of the specified course: ongoing and ended lists.
|
|
8
|
+
* Questions (`detail`, 1 request each) only for the questionnaires `options.details` selects (default `'all'`).
|
|
8
9
|
*/
|
|
9
|
-
export async function getQuestionnaireList(s, courseID) {
|
|
10
|
-
|
|
10
|
+
export async function getQuestionnaireList(s, courseID, options = {}) {
|
|
11
|
+
const details = options.details ?? 'all';
|
|
12
|
+
const lists = await Promise.all([
|
|
11
13
|
getQuestionnaireListAtUrl(s, courseID, URLS.LEARN_QNR_LIST_ONGOING),
|
|
12
14
|
getQuestionnaireListAtUrl(s, courseID, URLS.LEARN_QNR_LIST_ENDED),
|
|
13
|
-
])
|
|
15
|
+
]);
|
|
16
|
+
return Promise.all(lists
|
|
17
|
+
.flat()
|
|
18
|
+
.map(async (q) => isSelected(details, q) ? { ...q, detail: await getQuestionnaireDetail(s, courseID, q.id) } : q));
|
|
14
19
|
}
|
|
15
20
|
async function getQuestionnaireListAtUrl(s, courseID, url) {
|
|
16
|
-
const json = await
|
|
21
|
+
const json = await s.fetchJsonWithToken(url, { method: 'POST', body: URLS.LEARN_PAGE_LIST_FORM_DATA(courseID) });
|
|
17
22
|
if (json.result !== 'success') {
|
|
18
23
|
return Promise.reject({
|
|
19
24
|
reason: FailReason.INVALID_RESPONSE,
|
|
@@ -21,7 +26,7 @@ async function getQuestionnaireListAtUrl(s, courseID, url) {
|
|
|
21
26
|
});
|
|
22
27
|
}
|
|
23
28
|
const result = (json.object?.aaData ?? []);
|
|
24
|
-
return
|
|
29
|
+
return result.map((e) => {
|
|
25
30
|
const type = QNR_TYPE_MAP.get(e.wjlx) ?? QuestionnaireType.SURVEY;
|
|
26
31
|
return {
|
|
27
32
|
id: e.wjid,
|
|
@@ -36,15 +41,18 @@ async function getQuestionnaireListAtUrl(s, courseID, url) {
|
|
|
36
41
|
isFavorite: e.sfsc === YES,
|
|
37
42
|
comment: e.bznr ?? undefined,
|
|
38
43
|
url: URLS.LEARN_QNR_SUBMIT_PAGE(e.wlkcid, e.wjid, type),
|
|
39
|
-
detail: await getQuestionnaireDetail(s, courseID, e.wjid),
|
|
40
44
|
};
|
|
41
|
-
})
|
|
45
|
+
});
|
|
42
46
|
}
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
/** Get the questions of one questionnaire (1 request). */
|
|
48
|
+
export async function getQuestionnaireDetail(s, courseID, qnrID) {
|
|
49
|
+
const json = await s.fetchJsonWithToken(URLS.LEARN_QNR_DETAIL, {
|
|
45
50
|
method: 'POST',
|
|
46
51
|
body: URLS.LEARN_QNR_DETAIL_FORM(courseID, qnrID),
|
|
47
|
-
})
|
|
52
|
+
});
|
|
53
|
+
if (!Array.isArray(json)) {
|
|
54
|
+
throw { reason: FailReason.INVALID_RESPONSE, extra: json };
|
|
55
|
+
}
|
|
48
56
|
return json.map((e) => ({
|
|
49
57
|
id: e.wtid,
|
|
50
58
|
index: Number(e.wtbh),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questionnaires.js","sourceRoot":"","sources":["../src/questionnaires.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAGzB,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"questionnaires.js","sourceRoot":"","sources":["../src/questionnaires.ts"],"names":[],"mappings":"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"}
|
package/lib/request.d.ts
CHANGED
|
@@ -6,26 +6,82 @@ import { Language } from './types.ts';
|
|
|
6
6
|
export declare const $: (html: string | Element | Element[]) => cheerio.CheerioAPI;
|
|
7
7
|
export declare const noLogin: (res: Response) => boolean;
|
|
8
8
|
export declare const YES = "\u662F";
|
|
9
|
+
/** default for `HelperConfig.maxConcurrentRequests` */
|
|
10
|
+
export declare const DEFAULT_MAX_CONCURRENT_REQUESTS = 6;
|
|
11
|
+
/** default for `HelperConfig.requestTimeout`, in milliseconds */
|
|
12
|
+
export declare const DEFAULT_REQUEST_TIMEOUT = 60000;
|
|
9
13
|
/** add CSRF token to any request URL as parameters */
|
|
10
14
|
export declare const addCSRFTokenToUrl: (url: string, token: string) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Let at most `max` calls of `inner` run at once; the rest wait in FIFO order. A slot is freed when the response
|
|
17
|
+
* headers arrive (or the call fails), so reading a body does not hold one.
|
|
18
|
+
*/
|
|
19
|
+
export declare function limitConcurrency<F extends (...args: any[]) => Promise<Response>>(inner: F, max: number): F;
|
|
20
|
+
/** `RequestInit` plus a per-request `timeout` (milliseconds; 0 or `Infinity` for none) */
|
|
21
|
+
export type RequestOptions = RequestInit & {
|
|
22
|
+
timeout?: number;
|
|
23
|
+
};
|
|
24
|
+
/** a `Fetch` whose `init` can also carry a per-request `timeout` */
|
|
25
|
+
export type TimedFetch = (input: Parameters<Fetch>[0], init?: RequestOptions) => Promise<Response>;
|
|
26
|
+
/**
|
|
27
|
+
* Abort a call of `inner` that has no response headers after `ms` milliseconds (or `init.timeout`, which overrides it
|
|
28
|
+
* for one request) and reject it with `FailReason.REQUEST_TIMEOUT`. A caller's own `signal` still works, also while
|
|
29
|
+
* the body is read. Uses only `AbortController` and `setTimeout`, which React Native has (unlike
|
|
30
|
+
* `AbortSignal.timeout` / `AbortSignal.any`). Note that React Native's fetch resolves only after the whole body has
|
|
31
|
+
* arrived, so there the timeout covers the download too.
|
|
32
|
+
*/
|
|
33
|
+
export declare function withTimeout(inner: Fetch, ms: number): TimedFetch;
|
|
34
|
+
/**
|
|
35
|
+
* Whether a 200 page is the short login or redirect page of an expired session rather than the page asked for. A
|
|
36
|
+
* heuristic (not verified against the real server): short, and pointing at the login timeout page or the SSO login.
|
|
37
|
+
*/
|
|
38
|
+
export declare const looksLikeLoginPage: (text: string) => boolean;
|
|
11
39
|
/**
|
|
12
40
|
* State shared by every request a `Learn2018Helper` makes: cookies, CSRF token, language and the fetch wrappers.
|
|
13
41
|
* Internal; the helper keeps it in a private field.
|
|
14
42
|
*/
|
|
15
43
|
export declare class Session {
|
|
16
|
-
|
|
44
|
+
#private;
|
|
45
|
+
readonly loginWithProvider: () => Promise<void>;
|
|
17
46
|
readonly provider?: CredentialProvider;
|
|
18
47
|
readonly cookieJar: CookieJar;
|
|
19
|
-
/**
|
|
20
|
-
readonly rawFetch:
|
|
21
|
-
/** rejects with `NOT_LOGGED_IN`, or logs in again and retries once when a `CredentialProvider` is set */
|
|
22
|
-
readonly fetch: Fetch;
|
|
23
|
-
csrfToken: string;
|
|
48
|
+
/** fetch with cookies, the concurrency cap and the timeout, but no login check */
|
|
49
|
+
readonly rawFetch: TimedFetch;
|
|
24
50
|
lang: Language;
|
|
25
51
|
previewFirstPage: boolean;
|
|
26
|
-
/** `
|
|
27
|
-
constructor(config: HelperConfig | undefined,
|
|
28
|
-
|
|
29
|
-
|
|
52
|
+
/** `loginWithProvider` signs in through SSO with the `CredentialProvider` */
|
|
53
|
+
constructor(config: HelperConfig | undefined, loginWithProvider: () => Promise<void>);
|
|
54
|
+
get csrfToken(): string;
|
|
55
|
+
set csrfToken(token: string);
|
|
56
|
+
/**
|
|
57
|
+
* Run one login (`login`) at a time. It starts after a login already in progress has settled, and requests that
|
|
58
|
+
* find the session expired meanwhile wait for it instead of starting their own (two SSO logins at once reset each
|
|
59
|
+
* other's id.tsinghua.edu.cn cookie).
|
|
60
|
+
*/
|
|
61
|
+
runLogin(login: () => Promise<void>): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Log in with the `CredentialProvider`, or wait for the login already in progress (also one with explicit
|
|
64
|
+
* credentials) instead of starting another.
|
|
65
|
+
*/
|
|
66
|
+
relogin(): Promise<void>;
|
|
67
|
+
/** fetch with a login check (see `#send`) */
|
|
68
|
+
readonly fetch: TimedFetch;
|
|
69
|
+
/** like `fetch`, but logs in first if there is no CSRF token yet and adds the current token to the URL */
|
|
70
|
+
readonly fetchWithToken: TimedFetch;
|
|
71
|
+
/**
|
|
72
|
+
* Like `fetchWithToken`, but returns the parsed JSON body. A 200 HTML page instead of JSON counts as an expired
|
|
73
|
+
* session (log in again and retry once, as for a 403).
|
|
74
|
+
*/
|
|
75
|
+
readonly fetchJsonWithToken: (input: Parameters<Fetch>[0], init?: RequestOptions) => Promise<any>;
|
|
76
|
+
/**
|
|
77
|
+
* Like `fetchWithToken`, but returns the text body (an HTML page). A short login or redirect page with status 200
|
|
78
|
+
* counts as an expired session (log in again and retry once, as for a 403).
|
|
79
|
+
*/
|
|
80
|
+
readonly fetchTextWithToken: (input: Parameters<Fetch>[0], init?: RequestOptions) => Promise<string>;
|
|
81
|
+
/**
|
|
82
|
+
* Make sure the session works: if there is a CSRF token, fetch the current semester (`probeUrl`) and log in only if
|
|
83
|
+
* the session has expired; otherwise log in.
|
|
84
|
+
*/
|
|
85
|
+
ensureSession(probeUrl: string): Promise<void>;
|
|
30
86
|
}
|
|
31
87
|
//# sourceMappingURL=request.d.ts.map
|
package/lib/request.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"}
|