@robertying/thu-learn-lib 5.0.0 → 6.0.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.
Files changed (84) hide show
  1. package/README.md +94 -227
  2. package/lib/auth.d.ts +15 -4
  3. package/lib/auth.d.ts.map +1 -1
  4. package/lib/auth.js +65 -55
  5. package/lib/auth.js.map +1 -1
  6. package/lib/calendar.d.ts +12 -5
  7. package/lib/calendar.d.ts.map +1 -1
  8. package/lib/calendar.js +118 -20
  9. package/lib/calendar.js.map +1 -1
  10. package/lib/contents.d.ts.map +1 -1
  11. package/lib/contents.js +10 -6
  12. package/lib/contents.js.map +1 -1
  13. package/lib/courses.d.ts.map +1 -1
  14. package/lib/courses.js +15 -29
  15. package/lib/courses.js.map +1 -1
  16. package/lib/discussions.d.ts.map +1 -1
  17. package/lib/discussions.js +8 -19
  18. package/lib/discussions.js.map +1 -1
  19. package/lib/favorites.d.ts +1 -0
  20. package/lib/favorites.d.ts.map +1 -1
  21. package/lib/favorites.js +25 -60
  22. package/lib/favorites.js.map +1 -1
  23. package/lib/files.d.ts +4 -4
  24. package/lib/files.d.ts.map +1 -1
  25. package/lib/files.js +112 -134
  26. package/lib/files.js.map +1 -1
  27. package/lib/homework.d.ts +35 -5
  28. package/lib/homework.d.ts.map +1 -1
  29. package/lib/homework.js +150 -92
  30. package/lib/homework.js.map +1 -1
  31. package/lib/index.d.ts +45 -20
  32. package/lib/index.d.ts.map +1 -1
  33. package/lib/index.js +52 -17
  34. package/lib/index.js.map +1 -1
  35. package/lib/notices.d.ts +4 -4
  36. package/lib/notices.d.ts.map +1 -1
  37. package/lib/notices.js +13 -33
  38. package/lib/notices.js.map +1 -1
  39. package/lib/questionnaires.d.ts +6 -3
  40. package/lib/questionnaires.d.ts.map +1 -1
  41. package/lib/questionnaires.js +26 -24
  42. package/lib/questionnaires.js.map +1 -1
  43. package/lib/request.d.ts +64 -20
  44. package/lib/request.d.ts.map +1 -1
  45. package/lib/request.js +174 -64
  46. package/lib/request.js.map +1 -1
  47. package/lib/timetable.d.ts +26 -0
  48. package/lib/timetable.d.ts.map +1 -0
  49. package/lib/timetable.js +110 -0
  50. package/lib/timetable.js.map +1 -0
  51. package/lib/types.d.ts +117 -76
  52. package/lib/types.d.ts.map +1 -1
  53. package/lib/types.js +3 -0
  54. package/lib/types.js.map +1 -1
  55. package/lib/urls.d.ts +10 -20
  56. package/lib/urls.d.ts.map +1 -1
  57. package/lib/urls.js +11 -56
  58. package/lib/urls.js.map +1 -1
  59. package/lib/user.d.ts +7 -2
  60. package/lib/user.d.ts.map +1 -1
  61. package/lib/user.js +20 -6
  62. package/lib/user.js.map +1 -1
  63. package/lib/utils.d.ts +42 -4
  64. package/lib/utils.d.ts.map +1 -1
  65. package/lib/utils.js +80 -29
  66. package/lib/utils.js.map +1 -1
  67. package/package.json +9 -8
  68. package/src/auth.ts +72 -70
  69. package/src/calendar.ts +136 -24
  70. package/src/contents.ts +13 -6
  71. package/src/courses.ts +21 -37
  72. package/src/discussions.ts +10 -21
  73. package/src/favorites.ts +44 -80
  74. package/src/files.ts +124 -142
  75. package/src/homework.ts +207 -135
  76. package/src/index.ts +79 -48
  77. package/src/notices.ts +29 -42
  78. package/src/questionnaires.ts +62 -45
  79. package/src/request.ts +192 -69
  80. package/src/timetable.ts +121 -0
  81. package/src/types.ts +123 -87
  82. package/src/urls.ts +13 -64
  83. package/src/user.ts +22 -7
  84. package/src/utils.ts +97 -29
package/lib/calendar.d.ts CHANGED
@@ -1,16 +1,23 @@
1
1
  import type { Session } from './request.ts';
2
2
  import type { CalendarOptions, CalendarRange, CalendarResult } from './types.ts';
3
- /** The registrar often fails for ranges longer than about a month, so longer ranges are fetched in windows of this many days. */
3
+ /**
4
+ * The registrar often fails for ranges longer than about a month, so longer ranges are fetched in windows of this many
5
+ * days.
6
+ */
4
7
  export declare const CALENDAR_WINDOW_DAYS = 28;
5
8
  /** Split an inclusive yyyymmdd range into consecutive inclusive windows of at most `days` days. */
6
9
  export declare function splitCalendarRange(startDate: string, endDate: string, days?: number): CalendarRange[];
7
10
  /**
8
11
  * Get calendar items during the specified period (in yyyymmdd format, both inclusive).
9
12
  *
10
- * Ranges longer than `CALENDAR_WINDOW_DAYS` are fetched in consecutive windows (one at a time, each retried once) and
11
- * merged in date order. Windows that still fail are listed in `failedRanges`, so callers can show partial data and
12
- * retry only those. If every window fails, this rejects with the last error instead (usually
13
- * `FailReason.INVALID_RESPONSE`). The result might be empty if the period is too far away from now.
13
+ * Ranges longer than `CALENDAR_WINDOW_DAYS` are fetched in consecutive windows (one at a time, each retried once
14
+ * unless it timed out) and merged in date order. Windows that still fail are listed in `failedRanges`, so callers can
15
+ * show partial data and retry only those; after two windows in a row time out, the rest are listed there without a
16
+ * request. If every window fails, this rejects with the last error instead (usually `FailReason.INVALID_RESPONSE`).
17
+ * The result might be empty if the period is too far away from now. Throws a `RangeError` for a date that is not a
18
+ * valid yyyymmdd, and rejects with `FailReason.ERROR_REGISTRAR_AUTH` if signing in to the registrar fails. Off campus
19
+ * this goes through WebVPN and needs the id.tsinghua.edu.cn session of the last `login`; when that has expired, a
20
+ * helper with a `CredentialProvider` logs in again and tries once more.
14
21
  */
15
22
  export declare function getCalendar(s: Session, startDate: string, endDate: string, options?: CalendarOptions): Promise<CalendarResult>;
16
23
  //# sourceMappingURL=calendar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAiB,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKhG,iIAAiI;AACjI,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAevC,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,SAAuB,GAAG,aAAa,EAAE,CASnH;AAyBD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,CAAC,EAAE,OAAO,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CA6BzB"}
1
+ {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAA2B,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAK1G;;;GAGG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAoBvC,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,SAAuB,GAAG,aAAa,EAAE,CASnH;AAuHD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,CAAC,EAAE,OAAO,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAkCzB"}
package/lib/calendar.js CHANGED
@@ -1,15 +1,22 @@
1
- // Course calendar from the registrar (academic.tsinghua.edu.cn).
1
+ // Course calendar from the registrar (zhjw.cic.tsinghua.edu.cn).
2
+ import { discard } from './request.js';
2
3
  import { FailReason } from './types.js';
3
4
  import * as URLS from './urls.js';
4
- import { JSONP_EXTRACTOR_NAME, extractJSONPResult } from './utils.js';
5
- /** The registrar often fails for ranges longer than about a month, so longer ranges are fetched in windows of this many days. */
5
+ import { $, JSONP_EXTRACTOR_NAME, apiError, extractJSONPResult } from './utils.js';
6
+ /**
7
+ * The registrar often fails for ranges longer than about a month, so longer ranges are fetched in windows of this many
8
+ * days.
9
+ */
6
10
  export const CALENDAR_WINDOW_DAYS = 28;
7
11
  const DAY_MS = 24 * 60 * 60 * 1000;
12
+ /** after this many windows in a row time out, `getCalendar` gives up on the rest (they go to `failedRanges`) */
13
+ const MAX_CONSECUTIVE_TIMEOUTS = 2;
14
+ const isTimeout = (err) => err?.reason === FailReason.REQUEST_TIMEOUT;
8
15
  const parseDate = (date) => {
9
16
  const match = /^(\d{4})(\d{2})(\d{2})$/.exec(date);
10
17
  const time = match ? Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])) : NaN;
11
18
  if (Number.isNaN(time) || formatDate(time) !== date) {
12
- throw { reason: FailReason.INVALID_RESPONSE, extra: `invalid date ${date}, expected yyyymmdd` };
19
+ throw new RangeError(`invalid date ${date}, expected yyyymmdd`);
13
20
  }
14
21
  return time;
15
22
  };
@@ -25,14 +32,98 @@ export function splitCalendarRange(startDate, endDate, days = CALENDAR_WINDOW_DA
25
32
  }
26
33
  return ranges;
27
34
  }
35
+ const FINGERPRINT_FIELDS = ['fingerPrint', 'fingerGenPrint', 'fingerGenPrint3'];
36
+ const isFingerprintField = (name) => FINGERPRINT_FIELDS.includes(name);
37
+ /** `extra.step` of an `ERROR_REGISTRAR_AUTH` that id.tsinghua.edu.cn turned down (rather than the registrar failing) */
38
+ const ID_STEP = 'id.tsinghua.edu.cn';
39
+ const isIdRefusal = (err) => err?.reason === FailReason.ERROR_REGISTRAR_AUTH &&
40
+ err.extra?.step === ID_STEP;
41
+ /** an id.tsinghua.edu.cn login form (`/do/off/ui/auth/login/check`, `.../checkSingle`) */
42
+ const isIdLoginPage = (res, page) => res.url.startsWith(URLS.ID_PREFIX) || /action="[^"]*\/do\/off\/ui\/auth\/login\//.test(page);
43
+ /**
44
+ * The body of a sign-in step, or '' when there is no text. The registrar's own pages are GBK, which React Native's
45
+ * fetch can't decode: its `text()` then gives `undefined` instead of a string. Only id.tsinghua.edu.cn pages (UTF-8)
46
+ * are looked into here, so an undecodable registrar page is as good as an empty one.
47
+ */
48
+ const readText = async (res) => {
49
+ const text = await res.text();
50
+ return typeof text === 'string' ? text : '';
51
+ };
52
+ /**
53
+ * Sign in to the registrar with a Web Learning ticket.
54
+ *
55
+ * Registrar requests use `rawFetch`, without the Web Learning login check: a 403 or login page from the registrar says
56
+ * nothing about the Web Learning session, and logging in there again wouldn't renew the registrar ticket. They don't
57
+ * carry Web Learning's CSRF token either: the registrar (and WebVPN in front of it off campus) has no use for it.
58
+ *
59
+ * Off campus the registrar is only reachable through WebVPN (webvpn.tsinghua.edu.cn): the auth URL redirects there,
60
+ * and WebVPN signs in through id.tsinghua.edu.cn OAuth. As the id.tsinghua.edu.cn session of the Web Learning login is
61
+ * still there, id.tsinghua.edu.cn answers with a form (`#logined`) that a browser submits right away with its device
62
+ * fingerprints. Submitting it answers with a page that links (by script) to the OAuth callback, which signs in to WebVPN
63
+ * and redirects back to the auth URL, so following the link ends on the registrar.
64
+ */
65
+ async function authenticateRegistrar(s, ticket) {
66
+ let res = await s.rawFetch(URLS.REGISTRAR_AUTH(ticket));
67
+ let page = await readText(res);
68
+ const form = $(page)('form#logined');
69
+ if (form.length > 0) {
70
+ const fingerprints = s.fingerprints ?? (await s.provider?.());
71
+ const data = new FormData();
72
+ form.find('input[name]').each((_, input) => {
73
+ const name = input.attribs.name;
74
+ const known = isFingerprintField(name) ? fingerprints?.[name] : undefined;
75
+ data.append(name, known ?? input.attribs.value ?? '');
76
+ });
77
+ const action = new URL(form.attr('action') ?? '', res.url || URLS.ID_PREFIX).href;
78
+ const check = await s.rawFetch(action, { method: 'POST', body: data });
79
+ const link = check.ok ? $(await readText(check))('a').attr('href') : undefined;
80
+ if (!link) {
81
+ discard(check);
82
+ throw apiError(FailReason.ERROR_REGISTRAR_AUTH, { step: ID_STEP, code: check.status });
83
+ }
84
+ res = await s.rawFetch(new URL(link, check.url || action).href);
85
+ page = await readText(res);
86
+ }
87
+ if (isIdLoginPage(res, page)) {
88
+ throw apiError(FailReason.ERROR_REGISTRAR_AUTH, { step: ID_STEP, code: res.status, url: res.url.split('?')[0] });
89
+ }
90
+ if (!res.ok) {
91
+ throw apiError(FailReason.ERROR_REGISTRAR_AUTH, { code: res.status, url: res.url.split('?')[0] });
92
+ }
93
+ }
94
+ /**
95
+ * Get a registrar ticket and sign in to the registrar with it. When id.tsinghua.edu.cn turns the sign-in down (its
96
+ * session from the last login has expired, e.g. in a session resumed from saved cookies) and there is a
97
+ * `CredentialProvider`, log in to Web Learning again (a new id.tsinghua.edu.cn session) and try once more.
98
+ */
99
+ async function signInToRegistrar(s) {
100
+ const signIn = async () => {
101
+ const ticket = await s.fetchTextWithToken(URLS.REGISTRAR_TICKET, {
102
+ method: 'POST',
103
+ body: URLS.REGISTRAR_TICKET_FORM_DATA(),
104
+ });
105
+ await authenticateRegistrar(s, ticket.substring(1, ticket.length - 1));
106
+ };
107
+ try {
108
+ await signIn();
109
+ }
110
+ catch (err) {
111
+ if (!s.provider || !isIdRefusal(err))
112
+ throw err;
113
+ await s.autoRelogin();
114
+ await signIn();
115
+ }
116
+ }
28
117
  async function fetchWindow(s, range, graduate) {
29
- const response = await s.fetchWithToken(URLS.REGISTRAR_CALENDAR(range.startDate, range.endDate, graduate, JSONP_EXTRACTOR_NAME));
118
+ const response = await s.rawFetch(URLS.REGISTRAR_CALENDAR(range.startDate, range.endDate, graduate, JSONP_EXTRACTOR_NAME));
30
119
  if (!response.ok) {
31
- return Promise.reject({
32
- reason: FailReason.INVALID_RESPONSE,
33
- });
120
+ discard(response);
121
+ throw apiError(FailReason.INVALID_RESPONSE, { code: response.status, text: response.statusText });
34
122
  }
35
123
  const result = extractJSONPResult(await response.text());
124
+ if (!Array.isArray(result)) {
125
+ throw apiError(FailReason.INVALID_RESPONSE, result);
126
+ }
36
127
  return result.map((i) => ({
37
128
  location: i.dd,
38
129
  status: i.fl,
@@ -45,33 +136,40 @@ async function fetchWindow(s, range, graduate) {
45
136
  /**
46
137
  * Get calendar items during the specified period (in yyyymmdd format, both inclusive).
47
138
  *
48
- * Ranges longer than `CALENDAR_WINDOW_DAYS` are fetched in consecutive windows (one at a time, each retried once) and
49
- * merged in date order. Windows that still fail are listed in `failedRanges`, so callers can show partial data and
50
- * retry only those. If every window fails, this rejects with the last error instead (usually
51
- * `FailReason.INVALID_RESPONSE`). The result might be empty if the period is too far away from now.
139
+ * Ranges longer than `CALENDAR_WINDOW_DAYS` are fetched in consecutive windows (one at a time, each retried once
140
+ * unless it timed out) and merged in date order. Windows that still fail are listed in `failedRanges`, so callers can
141
+ * show partial data and retry only those; after two windows in a row time out, the rest are listed there without a
142
+ * request. If every window fails, this rejects with the last error instead (usually `FailReason.INVALID_RESPONSE`).
143
+ * The result might be empty if the period is too far away from now. Throws a `RangeError` for a date that is not a
144
+ * valid yyyymmdd, and rejects with `FailReason.ERROR_REGISTRAR_AUTH` if signing in to the registrar fails. Off campus
145
+ * this goes through WebVPN and needs the id.tsinghua.edu.cn session of the last `login`; when that has expired, a
146
+ * helper with a `CredentialProvider` logs in again and tries once more.
52
147
  */
53
148
  export async function getCalendar(s, startDate, endDate, options = {}) {
54
149
  const graduate = options.graduate ?? false;
55
150
  const ranges = splitCalendarRange(startDate, endDate);
56
151
  if (ranges.length === 0)
57
152
  return { events: [], failedRanges: [] };
58
- const ticketResponse = await s.fetchWithToken(URLS.REGISTRAR_TICKET(), {
59
- method: 'POST',
60
- body: URLS.REGISTRAR_TICKET_FORM_DATA(),
61
- });
62
- let ticket = await ticketResponse.text();
63
- ticket = ticket.substring(1, ticket.length - 1);
64
- await s.fetch(URLS.REGISTRAR_AUTH(ticket));
153
+ await signInToRegistrar(s);
65
154
  const events = [];
66
155
  const failedRanges = [];
67
156
  let lastError;
157
+ let timeouts = 0;
68
158
  for (const range of ranges) {
159
+ // after this many timed-out windows in a row the registrar is taken as down, and the rest are not tried
160
+ if (timeouts >= MAX_CONSECUTIVE_TIMEOUTS) {
161
+ failedRanges.push(range);
162
+ continue;
163
+ }
69
164
  try {
70
- events.push(...(await fetchWindow(s, range, graduate).catch(() => fetchWindow(s, range, graduate))));
165
+ // a timed-out window is not retried: the registrar is slow, not flaky, and each try takes `requestTimeout`
166
+ events.push(...(await fetchWindow(s, range, graduate).catch((err) => isTimeout(err) ? Promise.reject(err) : fetchWindow(s, range, graduate))));
167
+ timeouts = 0;
71
168
  }
72
169
  catch (e) {
73
170
  lastError = e;
74
171
  failedRanges.push(range);
172
+ timeouts = isTimeout(e) ? timeouts + 1 : 0;
75
173
  }
76
174
  }
77
175
  if (failedRanges.length === ranges.length)
@@ -1 +1 @@
1
- {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAIjE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEtE,iIAAiI;AACjI,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE;IACzC,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC9F,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,IAAI,qBAAqB,EAAE,CAAC;IAClG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAE3G,mGAAmG;AACnG,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,OAAe,EAAE,IAAI,GAAG,oBAAoB;IAChG,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;QAC1D,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,CAAU,EAAE,KAAoB,EAAE,QAAiB;IAC5E,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,cAAc,CACrC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CACxF,CAAC;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,OAAO,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,UAAU,CAAC,gBAAgB;SACpC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAU,CAAC;IAElE,OAAO,MAAM,CAAC,GAAG,CAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvC,QAAQ,EAAE,CAAC,CAAC,EAAE;QACd,MAAM,EAAE,CAAC,CAAC,EAAE;QACZ,SAAS,EAAE,CAAC,CAAC,IAAI;QACjB,OAAO,EAAE,CAAC,CAAC,IAAI;QACf,IAAI,EAAE,CAAC,CAAC,EAAE;QACV,UAAU,EAAE,CAAC,CAAC,EAAE;KACjB,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,CAAU,EACV,SAAiB,EACjB,OAAe,EACf,OAAO,GAAoB,EAAE;IAE7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;IAC3C,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAEjE,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE;QACrE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI,CAAC,0BAA0B,EAAE;KACxC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEhD,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,MAAM,YAAY,GAAoB,EAAE,CAAC;IACzC,IAAI,SAAkB,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACvG,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,GAAG,CAAC,CAAC;YACd,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,MAAM,SAAS,CAAC;IAC3D,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"contents.d.ts","sourceRoot":"","sources":["../src/contents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAiC,MAAM,YAAY,CAAC;AACvG,OAAO,EAAE,WAAW,EAA0B,MAAM,YAAY,CAAC;AAOjE;;;GAGG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,WAAW,EACxD,CAAC,EAAE,OAAO,EACV,SAAS,EAAE,MAAM,EAAE,EACnB,IAAI,EAAE,CAAC,EACP,OAAO,GAAE,kBAAkB,CAAC,CAAC,CAAM,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CA0C/B"}
1
+ {"version":3,"file":"contents.d.ts","sourceRoot":"","sources":["../src/contents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAiC,MAAM,YAAY,CAAC;AAEvG,OAAO,EAAE,WAAW,EAA0B,MAAM,YAAY,CAAC;AAOjE;;;GAGG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,WAAW,EACxD,CAAC,EAAE,OAAO,EACV,SAAS,EAAE,MAAM,EAAE,EACnB,IAAI,EAAE,CAAC,EACP,OAAO,GAAE,kBAAkB,CAAC,CAAC,CAAM,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAgD/B"}
package/lib/contents.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // One kind of content for many courses at once.
2
+ import { apiError } from './utils.js';
2
3
  import { ContentType, CourseType, FailReason } from './types.js';
3
4
  import { getAnsweredQuestionList, getDiscussionList } from './discussions.js';
4
5
  import { getFileList } from './files.js';
@@ -11,7 +12,7 @@ import { getQuestionnaireList } from './questionnaires.js';
11
12
  */
12
13
  export async function getAllContents(s, courseIDs, type, options = {}) {
13
14
  const courseType = options.courseType ?? CourseType.STUDENT;
14
- const fetchContentForCourse = (id) => {
15
+ const fetchContentForCourse = async (id) => {
15
16
  switch (type) {
16
17
  case ContentType.NOTIFICATION:
17
18
  return getNotificationList(s, id, courseType, {
@@ -20,6 +21,10 @@ export async function getAllContents(s, courseIDs, type, options = {}) {
20
21
  case ContentType.FILE:
21
22
  return getFileList(s, id, courseType);
22
23
  case ContentType.HOMEWORK:
24
+ if (courseType === CourseType.TEACHER) {
25
+ // the teacher list has another shape (`HomeworkTA`); use `getHomeworkList(id, CourseType.TEACHER)`
26
+ throw apiError(FailReason.NOT_IMPLEMENTED, 'homework of a teacher course; use getHomeworkList(courseID, CourseType.TEACHER)');
27
+ }
23
28
  return getHomeworkList(s, id, CourseType.STUDENT, {
24
29
  details: options.details,
25
30
  });
@@ -28,12 +33,11 @@ export async function getAllContents(s, courseIDs, type, options = {}) {
28
33
  case ContentType.QUESTION:
29
34
  return getAnsweredQuestionList(s, id, courseType);
30
35
  case ContentType.QUESTIONNAIRE:
31
- return getQuestionnaireList(s, id);
32
- default:
33
- return Promise.reject({
34
- reason: FailReason.NOT_IMPLEMENTED,
35
- extra: 'Unknown content type',
36
+ return getQuestionnaireList(s, id, {
37
+ details: options.details,
36
38
  });
39
+ default:
40
+ throw apiError(FailReason.NOT_IMPLEMENTED, 'Unknown content type');
37
41
  }
38
42
  };
39
43
  const contents = {};
@@ -1 +1 @@
1
- {"version":3,"file":"contents.js","sourceRoot":"","sources":["../src/contents.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAIhD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,CAAU,EACV,SAAmB,EACnB,IAAO,EACP,OAAO,GAA0B,EAAE;IAEnC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,UAAU,CAAC,OAAO,CAAC;IAC5D,MAAM,qBAAqB,GAAG,CAAC,EAAU,EAAgC,EAAE;QACzE,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,WAAW,CAAC,YAAY;gBAC3B,OAAO,mBAAmB,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE;oBAC5C,WAAW,EAAG,OAAwD,CAAC,OAAO;iBAC/E,CAAiC,CAAC;YACrC,KAAK,WAAW,CAAC,IAAI;gBACnB,OAAO,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAiC,CAAC;YACxE,KAAK,WAAW,CAAC,QAAQ;gBACvB,OAAO,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,OAAO,EAAE;oBAChD,OAAO,EAAG,OAAoD,CAAC,OAAO;iBACvE,CAAiC,CAAC;YACrC,KAAK,WAAW,CAAC,UAAU;gBACzB,OAAO,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAiC,CAAC;YAC9E,KAAK,WAAW,CAAC,QAAQ;gBACvB,OAAO,uBAAuB,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAiC,CAAC;YACpF,KAAK,WAAW,CAAC,aAAa;gBAC5B,OAAO,oBAAoB,CAAC,CAAC,EAAE,EAAE,CAAiC,CAAC;YACrE;gBACE,OAAO,OAAO,CAAC,MAAM,CAAC;oBACpB,MAAM,EAAE,UAAU,CAAC,eAAe;oBAClC,KAAK,EAAE,sBAAsB;iBAC9B,CAAC,CAAC;QACP,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,MAAM,MAAM,GAAmC,EAAE,CAAC;IAElD,MAAM,OAAO,CAAC,GAAG,CACf,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,QAAQ,CAAC,EAAE,CAAC,GAAG,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"contents.js","sourceRoot":"","sources":["../src/contents.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAIhD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,CAAU,EACV,SAAmB,EACnB,IAAO,EACP,OAAO,GAA0B,EAAE;IAEnC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,UAAU,CAAC,OAAO,CAAC;IAC5D,MAAM,qBAAqB,GAAG,KAAK,EAAE,EAAU,EAAgC,EAAE;QAC/E,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,WAAW,CAAC,YAAY;gBAC3B,OAAO,mBAAmB,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE;oBAC5C,WAAW,EAAG,OAAwD,CAAC,OAAO;iBAC/E,CAAiC,CAAC;YACrC,KAAK,WAAW,CAAC,IAAI;gBACnB,OAAO,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAiC,CAAC;YACxE,KAAK,WAAW,CAAC,QAAQ;gBACvB,IAAI,UAAU,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;oBACtC,mGAAmG;oBACnG,MAAM,QAAQ,CACZ,UAAU,CAAC,eAAe,EAC1B,iFAAiF,CAClF,CAAC;gBACJ,CAAC;gBACD,OAAO,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,OAAO,EAAE;oBAChD,OAAO,EAAG,OAAoD,CAAC,OAAO;iBACvE,CAAiC,CAAC;YACrC,KAAK,WAAW,CAAC,UAAU;gBACzB,OAAO,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAiC,CAAC;YAC9E,KAAK,WAAW,CAAC,QAAQ;gBACvB,OAAO,uBAAuB,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAiC,CAAC;YACpF,KAAK,WAAW,CAAC,aAAa;gBAC5B,OAAO,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE;oBACjC,OAAO,EAAG,OAAyD,CAAC,OAAO;iBAC5E,CAAiC,CAAC;YACrC;gBACE,MAAM,QAAQ,CAAC,UAAU,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,MAAM,MAAM,GAAmC,EAAE,CAAC;IAElD,MAAM,OAAO,CAAC,GAAG,CACf,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,QAAQ,CAAC,EAAE,CAAC,GAAG,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"courses.d.ts","sourceRoot":"","sources":["../src/courses.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAY,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAIpD,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWrE;AAED,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAiB1E;AAED,uGAAuG;AACvG,wBAAsB,aAAa,CACjC,CAAC,EAAE,OAAO,EACV,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,UAA+B,EAC3C,IAAI,gCAAS,EACb,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,UAAU,EAAE,CAAC,CAmCvB;AAED,0DAA0D;AAC1D,wBAAsB,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO9F;AAED,wBAAsB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhF"}
1
+ {"version":3,"file":"courses.d.ts","sourceRoot":"","sources":["../src/courses.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAIpD,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQrE;AAED,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAc1E;AAED,uGAAuG;AACvG,wBAAsB,aAAa,CACjC,CAAC,EAAE,OAAO,EACV,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,UAA+B,EAC3C,IAAI,gCAAS,EACb,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,UAAU,EAAE,CAAC,CAgCvB;AAED,0DAA0D;AAC1D,wBAAsB,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO9F;AAED,wBAAsB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAShF"}
package/lib/courses.js CHANGED
@@ -1,26 +1,20 @@
1
1
  // Semesters and courses.
2
2
  import { CourseType, FailReason } from './types.js';
3
3
  import * as URLS from './urls.js';
4
- import { decodeHTML, parseSemesterType } from './utils.js';
4
+ import { apiError, decodeHTML, expectSuccess, parseSemesterType } from './utils.js';
5
5
  export async function getSemesterIdList(s) {
6
- const json = await (await s.fetchWithToken(URLS.LEARN_SEMESTER_LIST())).json();
6
+ const json = await s.fetchJsonWithToken(URLS.LEARN_SEMESTER_LIST);
7
7
  if (!Array.isArray(json)) {
8
- return Promise.reject({
9
- reason: FailReason.INVALID_RESPONSE,
10
- extra: json,
11
- });
8
+ throw apiError(FailReason.INVALID_RESPONSE, json);
12
9
  }
13
10
  const semesters = json;
14
- // sometimes web learning returns null, so confusing...
11
+ // the list can contain null entries
15
12
  return semesters.filter((semester) => semester != null);
16
13
  }
17
14
  export async function getCurrentSemester(s) {
18
- const json = await (await s.fetchWithToken(URLS.LEARN_CURRENT_SEMESTER())).json();
15
+ const json = await s.fetchJsonWithToken(URLS.LEARN_CURRENT_SEMESTER);
19
16
  if (json.message !== 'success') {
20
- return Promise.reject({
21
- reason: FailReason.INVALID_RESPONSE,
22
- extra: json,
23
- });
17
+ throw apiError(FailReason.INVALID_RESPONSE, json);
24
18
  }
25
19
  const result = json.result;
26
20
  return {
@@ -34,14 +28,11 @@ export async function getCurrentSemester(s) {
34
28
  }
35
29
  /** get all courses in the specified semester; time and location only with `options.timeAndLocation` */
36
30
  export async function getCourseList(s, semesterID, courseType = CourseType.STUDENT, lang = s.lang, options = {}) {
37
- const json = await (await s.fetchWithToken(URLS.LEARN_COURSE_LIST(semesterID, courseType, lang))).json();
31
+ const json = await s.fetchJsonWithToken(URLS.LEARN_COURSE_LIST(semesterID, courseType, lang));
38
32
  if (json.message !== 'success' || !Array.isArray(json.resultList)) {
39
- return Promise.reject({
40
- reason: FailReason.INVALID_RESPONSE,
41
- extra: json,
42
- });
33
+ throw apiError(FailReason.INVALID_RESPONSE, json);
43
34
  }
44
- const result = (json.resultList ?? []);
35
+ const result = json.resultList;
45
36
  return Promise.all(result.map(async (c) => {
46
37
  let timeAndLocation;
47
38
  if (options.timeAndLocation) {
@@ -49,7 +40,7 @@ export async function getCourseList(s, semesterID, courseType = CourseType.STUDE
49
40
  timeAndLocation = await getCourseTimeAndLocation(s, c.wlkcid);
50
41
  }
51
42
  catch {
52
- timeAndLocation = [];
43
+ // left out, so a failure doesn't look like a course without a schedule; see `getCourseTimeAndLocation`
53
44
  }
54
45
  }
55
46
  return {
@@ -70,25 +61,20 @@ export async function getCourseList(s, semesterID, courseType = CourseType.STUDE
70
61
  /** get the time and location of one course (1 request) */
71
62
  export async function getCourseTimeAndLocation(s, courseID) {
72
63
  // see https://github.com/Harry-Chen/Learn-Helper/issues/145
73
- const json = await (await s.fetchWithToken(URLS.LEARN_COURSE_TIME_LOCATION(courseID))).json();
64
+ const json = await s.fetchJsonWithToken(URLS.LEARN_COURSE_TIME_LOCATION(courseID));
74
65
  if (!Array.isArray(json)) {
75
- throw { reason: FailReason.INVALID_RESPONSE, extra: json };
66
+ throw apiError(FailReason.INVALID_RESPONSE, json);
76
67
  }
77
68
  return json;
78
69
  }
79
70
  export async function sortCourses(s, courseIDs) {
80
- const json = await (await s.fetchWithToken(URLS.LEARN_SORT_COURSES, {
71
+ const json = await s.fetchJsonWithToken(URLS.LEARN_SORT_COURSES, {
81
72
  method: 'POST',
82
73
  body: JSON.stringify(courseIDs.map((id, index) => ({ wlkcid: id, xh: index + 1 }))),
83
74
  headers: {
84
75
  'Content-Type': 'application/json',
85
76
  },
86
- })).json();
87
- if (json.result !== 'success') {
88
- return Promise.reject({
89
- reason: FailReason.OPERATION_FAILED,
90
- extra: json,
91
- });
92
- }
77
+ });
78
+ expectSuccess(json, FailReason.OPERATION_FAILED);
93
79
  }
94
80
  //# sourceMappingURL=courses.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"courses.js","sourceRoot":"","sources":["../src/courses.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"courses.js","sourceRoot":"","sources":["../src/courses.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAIzB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,CAAU;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAClE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,SAAS,GAAG,IAAgB,CAAC;IACnC,oCAAoC;IACpC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,CAAU;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACrE,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,SAAS,EAAE,MAAM,CAAC,IAAI;QACtB,OAAO,EAAE,MAAM,CAAC,IAAI;QACpB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACxC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED,uGAAuG;AACvG,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,CAAU,EACV,UAAkB,EAClB,UAAU,GAAe,UAAU,CAAC,OAAO,EAC3C,IAAI,GAAG,CAAC,CAAC,IAAI,EACb,OAAO,GAAsB,EAAE;IAE/B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9F,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,MAAM,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAmB,CAAC;IAExC,OAAO,OAAO,CAAC,GAAG,CAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QACrB,IAAI,eAAqC,CAAC;QAC1C,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,eAAe,GAAG,MAAM,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YAChE,CAAC;YAAC,MAAM,CAAC;gBACP,uGAAuG;YACzG,CAAC;QACH,CAAC;QACD,OAAO;YACL,EAAE,EAAE,CAAC,CAAC,MAAM;YACZ,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1B,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9B,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;YAChC,eAAe;YACf,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC;YACjD,WAAW,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,6BAA6B;YACvD,aAAa,EAAE,CAAC,CAAC,GAAG;YACpB,YAAY,EAAE,CAAC,CAAC,GAAG;YACnB,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,gEAAgE;YAC5F,UAAU;SACU,CAAC;IACzB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,CAAU,EAAE,QAAgB;IACzE,4DAA4D;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,CAAU,EAAE,SAAmB;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,kBAAkB,EAAE;QAC/D,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACnF,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;IACH,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"discussions.d.ts","sourceRoot":"","sources":["../src/discussions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,UAAU,EAAmB,QAAQ,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAIpD,0DAA0D;AAC1D,wBAAsB,iBAAiB,CACrC,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,UAA+B,GAC1C,OAAO,CAAC,UAAU,EAAE,CAAC,CAmBvB;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,UAA+B,GAC1C,OAAO,CAAC,QAAQ,EAAE,CAAC,CAmBrB"}
1
+ {"version":3,"file":"discussions.d.ts","sourceRoot":"","sources":["../src/discussions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAIpD,0DAA0D;AAC1D,wBAAsB,iBAAiB,CACrC,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,UAA+B,GAC1C,OAAO,CAAC,UAAU,EAAE,CAAC,CAcvB;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,UAA+B,GAC1C,OAAO,CAAC,QAAQ,EAAE,CAAC,CAcrB"}
@@ -1,18 +1,12 @@
1
1
  // Discussions (课程讨论) and answered questions (课程答疑).
2
2
  import { Base64 } from 'js-base64';
3
- import { YES } from './request.js';
4
3
  import { CourseType, FailReason } from './types.js';
5
4
  import * as URLS from './urls.js';
6
- import { decodeHTML } from './utils.js';
5
+ import { YES, decodeHTML, expectSuccess, toRequiredServerTime } from './utils.js';
7
6
  /** Get all discussions (课程讨论) of the specified course. */
8
7
  export async function getDiscussionList(s, courseID, courseType = CourseType.STUDENT) {
9
- const json = await (await s.fetchWithToken(URLS.LEARN_DISCUSSION_LIST(courseID, courseType))).json();
10
- if (json.result !== 'success') {
11
- return Promise.reject({
12
- reason: FailReason.INVALID_RESPONSE,
13
- extra: json,
14
- });
15
- }
8
+ const json = await s.fetchJsonWithToken(URLS.LEARN_DISCUSSION_LIST(courseID, courseType));
9
+ expectSuccess(json, FailReason.INVALID_RESPONSE);
16
10
  const result = (json.object?.resultsList ?? []);
17
11
  return result.map((d) => ({
18
12
  ...parseDiscussionBase(d),
@@ -25,17 +19,12 @@ export async function getDiscussionList(s, courseID, courseType = CourseType.STU
25
19
  * The student version supports only answered questions, while the teacher version supports all questions.
26
20
  */
27
21
  export async function getAnsweredQuestionList(s, courseID, courseType = CourseType.STUDENT) {
28
- const json = await (await s.fetchWithToken(URLS.LEARN_QUESTION_LIST_ANSWERED(courseID, courseType))).json();
29
- if (json.result !== 'success') {
30
- return Promise.reject({
31
- reason: FailReason.INVALID_RESPONSE,
32
- extra: json,
33
- });
34
- }
22
+ const json = await s.fetchJsonWithToken(URLS.LEARN_QUESTION_LIST_ANSWERED(courseID, courseType));
23
+ expectSuccess(json, FailReason.INVALID_RESPONSE);
35
24
  const result = (json.object?.resultsList ?? []);
36
25
  return result.map((q) => ({
37
26
  ...parseDiscussionBase(q),
38
- question: Base64.decode(q.wtnr),
27
+ question: Base64.decode(q.wtnr ?? ''),
39
28
  url: URLS.LEARN_QUESTION_DETAIL(q.wlkcid, q.id, courseType),
40
29
  }));
41
30
  }
@@ -44,8 +33,8 @@ function parseDiscussionBase(d) {
44
33
  id: d.id,
45
34
  title: decodeHTML(d.bt),
46
35
  publisherName: d.fbrxm,
47
- publishTime: d.fbsj,
48
- lastReplyTime: d.zhhfsj,
36
+ publishTime: toRequiredServerTime(d.fbsj),
37
+ lastReplyTime: toRequiredServerTime(d.zhhfsj),
49
38
  lastReplierName: d.zhhfrxm,
50
39
  visitCount: d.djs ?? 0, // teacher cannot fetch this
51
40
  replyCount: d.hfcs,
@@ -1 +1 @@
1
- {"version":3,"file":"discussions.js","sourceRoot":"","sources":["../src/discussions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discussions.js","sourceRoot":"","sources":["../src/discussions.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAInC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElF,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,CAAU,EACV,QAAgB,EAChB,UAAU,GAAe,UAAU,CAAC,OAAO;IAE3C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IAC1F,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAU,CAAC;IAEzD,OAAO,MAAM,CAAC,GAAG,CACf,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC;QACC,GAAG,mBAAmB,CAAC,CAAC,CAAC;QACzB,OAAO,EAAE,CAAC,CAAC,IAAI;QACf,GAAG,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC;KACtE,CAAsB,CAC1B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,CAAU,EACV,QAAgB,EAChB,UAAU,GAAe,UAAU,CAAC,OAAO;IAE3C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,4BAA4B,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IACjG,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAU,CAAC;IAEzD,OAAO,MAAM,CAAC,GAAG,CACf,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC;QACC,GAAG,mBAAmB,CAAC,CAAC,CAAC;QACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QACrC,GAAG,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC;KAC5D,CAAoB,CACxB,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,CAAM;IACjC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACvB,aAAa,EAAE,CAAC,CAAC,KAAK;QACtB,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,aAAa,EAAE,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7C,eAAe,EAAE,CAAC,CAAC,OAAO;QAC1B,UAAU,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,4BAA4B;QACpD,UAAU,EAAE,CAAC,CAAC,IAAI;QAClB,UAAU,EAAE,CAAC,CAAC,IAAI,KAAK,GAAG;QAC1B,OAAO,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;KAC7B,CAAC;AACJ,CAAC"}
@@ -3,6 +3,7 @@ import type { CommentItem, FavoriteItem } from './types.ts';
3
3
  import { ContentType } from './types.ts';
4
4
  /**
5
5
  * Add an item to favorites. (收藏)
6
+ * Success is `result: 'success'`; the message is in the website's language ("收藏成功", "Added successfully.").
6
7
  */
7
8
  export declare function addToFavorites(s: Session, type: ContentType, id: string): Promise<void>;
8
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"favorites.d.ts","sourceRoot":"","sources":["../src/favorites.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAIrD;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ7F;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ/E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAmC7G;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa3E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa7E;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa1G;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA+B3G"}
1
+ {"version":3,"file":"favorites.d.ts","sourceRoot":"","sources":["../src/favorites.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAWrD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG7F;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA8B7G;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1G;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAwB3G"}