juno-erp-client 1.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.
package/dist/index.js ADDED
@@ -0,0 +1,642 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
+ };
38
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
39
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
40
+ return new (P || (P = Promise))(function (resolve, reject) {
41
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
42
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
43
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
44
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
45
+ });
46
+ };
47
+ var __importDefault = (this && this.__importDefault) || function (mod) {
48
+ return (mod && mod.__esModule) ? mod : { "default": mod };
49
+ };
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.JunoClient = void 0;
52
+ const axios_1 = __importDefault(require("axios"));
53
+ const axios_cookiejar_support_1 = require("axios-cookiejar-support");
54
+ const tough_cookie_1 = require("tough-cookie");
55
+ const qs = __importStar(require("querystring"));
56
+ const fs = __importStar(require("fs"));
57
+ const path = __importStar(require("path"));
58
+ /**
59
+ * JunoClient is a high-level API wrapper for the Juno ERP system.
60
+ * It handles session management, cookie persistence, and provides
61
+ * type-safe methods to access student data.
62
+ */
63
+ class JunoClient {
64
+ /**
65
+ * Creates a new instance of the Juno API client.
66
+ * @param config - Configuration options for the client.
67
+ */
68
+ constructor(config = {}) {
69
+ var _a, _b;
70
+ this.debug = (_a = config.debug) !== null && _a !== void 0 ? _a : false;
71
+ this.sessionPath = config.sessionPath;
72
+ this.autoSave = (_b = config.autoSave) !== null && _b !== void 0 ? _b : (!!this.sessionPath);
73
+ this.jar = new tough_cookie_1.CookieJar();
74
+ if (this.sessionPath) {
75
+ this.loadSessionFromFile();
76
+ }
77
+ if (this.debug) {
78
+ console.log('[DEBUG] Initializing JunoClient with debug mode ON');
79
+ console.log('[DEBUG] Base URL:', config.baseUrl || 'https://erp.mgmu.ac.in');
80
+ }
81
+ this.api = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({
82
+ baseURL: config.baseUrl || 'https://erp.mgmu.ac.in',
83
+ jar: this.jar,
84
+ withCredentials: true,
85
+ headers: {
86
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
87
+ 'Accept': 'application/json, text/javascript, */*; q=0.01',
88
+ 'X-Requested-With': 'XMLHttpRequest',
89
+ },
90
+ }));
91
+ }
92
+ /**
93
+ * Internal utility for logging debug information.
94
+ * @param method - The name of the method being logged.
95
+ * @param data - The data to log.
96
+ */
97
+ logDebug(method, data) {
98
+ if (this.debug) {
99
+ console.log(`\n[DEBUG] ${method}:`);
100
+ console.log('[DEBUG] Response type:', typeof data);
101
+ console.log('[DEBUG] Is Array:', Array.isArray(data));
102
+ if (typeof data === 'object') {
103
+ const jsonStr = JSON.stringify(data, null, 2);
104
+ console.log('[DEBUG] Data:', jsonStr.length > 2000 ? jsonStr.substring(0, 2000) + '...' : jsonStr);
105
+ }
106
+ else {
107
+ console.log('[DEBUG] Data:', data);
108
+ }
109
+ }
110
+ }
111
+ /**
112
+ * Saves the current session cookies to the configured sessionPath.
113
+ */
114
+ saveSessionToFile() {
115
+ if (!this.sessionPath)
116
+ return;
117
+ try {
118
+ const dir = path.dirname(this.sessionPath);
119
+ if (!fs.existsSync(dir)) {
120
+ fs.mkdirSync(dir, { recursive: true });
121
+ }
122
+ const cookies = this.jar.toJSON();
123
+ fs.writeFileSync(this.sessionPath, JSON.stringify(cookies, null, 2));
124
+ if (this.debug)
125
+ console.log('[DEBUG] Session saved to:', this.sessionPath);
126
+ }
127
+ catch (error) {
128
+ console.error('[DEBUG] Failed to save session:', error);
129
+ }
130
+ }
131
+ /**
132
+ * Loads session cookies from the configured sessionPath and re-initializes the API instance.
133
+ */
134
+ loadSessionFromFile() {
135
+ if (!this.sessionPath || !fs.existsSync(this.sessionPath))
136
+ return;
137
+ try {
138
+ const data = fs.readFileSync(this.sessionPath, 'utf8');
139
+ const jsonData = JSON.parse(data);
140
+ this.importSession(jsonData);
141
+ if (this.debug)
142
+ console.log('[DEBUG] Session loaded from:', this.sessionPath);
143
+ }
144
+ catch (error) {
145
+ console.error('[DEBUG] Failed to load session:', error);
146
+ }
147
+ }
148
+ /**
149
+ * Exports the current session data as a JSON-serializable object.
150
+ * Use this for manual session management (e.g., storing in a database).
151
+ * @returns The serialized session object.
152
+ */
153
+ exportSession() {
154
+ return this.jar.toJSON();
155
+ }
156
+ /**
157
+ * Imports session data from a previously exported session object.
158
+ * @param data - The serialized session object.
159
+ */
160
+ importSession(data) {
161
+ this.jar = tough_cookie_1.CookieJar.fromJSON(data);
162
+ // Re-wrap axios after reloading jar
163
+ this.api = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create(Object.assign(Object.assign({}, this.api.defaults), { jar: this.jar })));
164
+ }
165
+ /**
166
+ * Checks if the client is currently logged in and has a valid session.
167
+ * This method verifies the session by attempting to fetch the student ID.
168
+ * @returns A promise that resolves to true if logged in, false otherwise.
169
+ */
170
+ isLoggedIn() {
171
+ return __awaiter(this, void 0, void 0, function* () {
172
+ try {
173
+ const response = yield this.api.get('/stu_getStudentIdFromSession.json', {
174
+ validateStatus: (status) => status === 200
175
+ });
176
+ const studentId = parseInt(response.data, 10);
177
+ return !isNaN(studentId) && studentId > 0;
178
+ }
179
+ catch (error) {
180
+ return false;
181
+ }
182
+ });
183
+ }
184
+ // ============================================
185
+ // Authentication
186
+ // ============================================
187
+ /**
188
+ * Performs a multi-step login process to authenticate with the Juno ERP system.
189
+ * The process involves:
190
+ * 1. Acquiring an initial JSESSIONID from the login page.
191
+ * 2. Posting credentials to the security check endpoint.
192
+ * 3. Following redirects to activate the session.
193
+ * 4. Visiting the dashboard to prime the server-side context.
194
+ *
195
+ * @param username - The Juno ERP username.
196
+ * @param password - The Juno ERP password.
197
+ * @returns A promise that resolves to true if login was successful, false otherwise.
198
+ */
199
+ login(username, password) {
200
+ return __awaiter(this, void 0, void 0, function* () {
201
+ try {
202
+ // Step 1: Get the login page to obtain initial JSESSIONID
203
+ if (this.debug)
204
+ console.log('[DEBUG] Step 1: Getting login page to acquire JSESSIONID...');
205
+ const loginPageResponse = yield this.api.get('/login.htm');
206
+ if (this.debug) {
207
+ console.log('[DEBUG] Login page response status:', loginPageResponse.status);
208
+ const cookies = yield this.jar.getCookies(this.api.defaults.baseURL || 'https://erp.mgmu.ac.in');
209
+ console.log('[DEBUG] Cookies after login page:', cookies.map(c => `${c.key}=${c.value}`).join('; '));
210
+ }
211
+ // Step 2: POST credentials
212
+ if (this.debug)
213
+ console.log('[DEBUG] Step 2: Posting credentials for user:', username);
214
+ const data = qs.stringify({
215
+ j_username: username,
216
+ j_password: password,
217
+ });
218
+ const response = yield this.api.post('/j_spring_security_check', data, {
219
+ headers: {
220
+ 'Content-Type': 'application/x-www-form-urlencoded',
221
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
222
+ 'Referer': `${this.api.defaults.baseURL}/login.htm`,
223
+ },
224
+ maxRedirects: 0,
225
+ validateStatus: (status) => status >= 200 && status < 400,
226
+ });
227
+ let success = response.status === 302 || response.status === 200;
228
+ if (this.debug) {
229
+ console.log('[DEBUG] Login POST response status:', response.status);
230
+ console.log('[DEBUG] Login POST headers:', response.headers);
231
+ }
232
+ // Step 3: Follow redirect to activate session (home.htm)
233
+ if (success && (response.status === 302 || response.headers.location)) {
234
+ let redirectUrl = response.headers.location || '/home.htm';
235
+ if (!redirectUrl.startsWith('http')) {
236
+ redirectUrl = redirectUrl.startsWith('/') ? redirectUrl : '/' + redirectUrl;
237
+ }
238
+ if (this.debug)
239
+ console.log(`[DEBUG] Step 3: Following redirect to ${redirectUrl}...`);
240
+ yield this.api.get(redirectUrl, {
241
+ headers: {
242
+ 'Referer': `${this.api.defaults.baseURL}/login.htm`,
243
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
244
+ }
245
+ });
246
+ // Step 4: Visit dashboard page to prime session context
247
+ if (this.debug)
248
+ console.log('[DEBUG] Step 4: Visiting stu_myDashBoard.htm to prime session context...');
249
+ yield this.api.get('/stu_myDashBoard.htm', {
250
+ headers: {
251
+ 'Referer': `${this.api.defaults.baseURL}/home.htm`,
252
+ }
253
+ });
254
+ }
255
+ if (this.debug) {
256
+ const cookiesAfterLogin = yield this.jar.getCookies(this.api.defaults.baseURL || 'https://erp.mgmu.ac.in');
257
+ console.log('[DEBUG] Cookies after session activation:', cookiesAfterLogin.map(c => `${c.key}=${c.value}`).join('; '));
258
+ console.log('[DEBUG] Login process complete, success:', success);
259
+ if (success && this.autoSave) {
260
+ this.saveSessionToFile();
261
+ }
262
+ }
263
+ return success;
264
+ }
265
+ catch (error) {
266
+ console.error('Login failed:', error);
267
+ if (this.debug && error instanceof Error) {
268
+ console.error('[DEBUG] Error details:', error.message);
269
+ }
270
+ return false;
271
+ }
272
+ });
273
+ }
274
+ // ============================================
275
+ // Student & Profile
276
+ // ============================================
277
+ /**
278
+ * Fetches the student's basic profile information.
279
+ * @returns A promise that resolves to an array containing the student profile.
280
+ */
281
+ getStudentProfile() {
282
+ return __awaiter(this, void 0, void 0, function* () {
283
+ const response = yield this.api.get('/stu_getStudentPersonalinfo.json', {
284
+ headers: {
285
+ 'Referer': `${this.api.defaults.baseURL}/stu_studentProfile.htm`,
286
+ }
287
+ });
288
+ const responseData = response.data;
289
+ this.logDebug('getStudentProfile', responseData);
290
+ return responseData;
291
+ });
292
+ }
293
+ /**
294
+ * Fetches detailed personal contact and address information.
295
+ * @returns A promise resolving to an object containing PersonalInfo.
296
+ */
297
+ getPersonalInformation() {
298
+ return __awaiter(this, void 0, void 0, function* () {
299
+ const response = yield this.api.get('/stu_getPersonalInformation.json', {
300
+ headers: {
301
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
302
+ }
303
+ });
304
+ const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
305
+ this.logDebug('getPersonalInformation', data);
306
+ return data;
307
+ });
308
+ }
309
+ /**
310
+ * Fetches academic enrollment details like course, department, and semester.
311
+ * @returns A promise resolving to an array of AcademicInfo objects.
312
+ */
313
+ getAcademicInfo() {
314
+ return __awaiter(this, void 0, void 0, function* () {
315
+ const response = yield this.api.get('/stu_getAcademicInformationForBothCources.json', {
316
+ headers: {
317
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
318
+ }
319
+ });
320
+ const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
321
+ this.logDebug('getAcademicInfo', data);
322
+ return data.map((item) => item.AcademicInfo);
323
+ });
324
+ }
325
+ /**
326
+ * Fetches admission-related details and document submission status.
327
+ * @returns A promise resolving to an object containing AdmissionDetail.
328
+ */
329
+ getAdmissionDetails() {
330
+ return __awaiter(this, void 0, void 0, function* () {
331
+ const response = yield this.api.get('/stu_getAdmissionDetails.json', {
332
+ headers: {
333
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
334
+ }
335
+ });
336
+ const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
337
+ this.logDebug('getAdmissionDetails', data);
338
+ return data;
339
+ });
340
+ }
341
+ /**
342
+ * Fetches a list of all available castes from the system.
343
+ * @returns A promise resolving to an array of Caste objects.
344
+ */
345
+ getAllCastes() {
346
+ return __awaiter(this, void 0, void 0, function* () {
347
+ const response = yield this.api.get('/stu_getAllCaste.json', {
348
+ headers: {
349
+ 'Referer': `${this.api.defaults.baseURL}/stu_studentProfile.htm`,
350
+ }
351
+ });
352
+ this.logDebug('getAllCastes', response.data);
353
+ return response.data;
354
+ });
355
+ }
356
+ /**
357
+ * Fetches a list of all countries for nationality selection.
358
+ * @returns A promise resolving to an array of Country objects.
359
+ */
360
+ getCountryList() {
361
+ return __awaiter(this, void 0, void 0, function* () {
362
+ const response = yield this.api.get('/stu_getStudentCountrylist.json', {
363
+ headers: {
364
+ 'Referer': `${this.api.defaults.baseURL}/stu_studentProfile.htm`,
365
+ }
366
+ });
367
+ this.logDebug('getCountryList', response.data);
368
+ return response.data;
369
+ });
370
+ }
371
+ // ============================================
372
+ // Courses & Attendance
373
+ // ============================================
374
+ /**
375
+ * Fetches the list of courses for a given term (semester).
376
+ * @param termId - The internal ID for the term.
377
+ * @param params - Optional search and filtering parameters.
378
+ * @returns A promise resolving to an array of Course objects.
379
+ */
380
+ getCourses(termId, params) {
381
+ return __awaiter(this, void 0, void 0, function* () {
382
+ var _a;
383
+ const queryParams = new URLSearchParams(Object.assign(Object.assign(Object.assign({ termId: termId.toString(), refreshData: ((_a = params === null || params === void 0 ? void 0 : params.refreshData) !== null && _a !== void 0 ? _a : 0).toString() }, ((params === null || params === void 0 ? void 0 : params.subjectwisestudentids) && { subjectwisestudentids: params.subjectwisestudentids })), ((params === null || params === void 0 ? void 0 : params.subejctwiseBatchIds) && { subejctwiseBatchIds: params.subejctwiseBatchIds })), ((params === null || params === void 0 ? void 0 : params.batchsemestercapacity) && { batchsemestercapacity: params.batchsemestercapacity.toString() })));
384
+ const response = yield this.api.get(`/stu_getSubjectOnChangeWithSemId1.json?${queryParams}`, {
385
+ headers: {
386
+ 'Referer': `${this.api.defaults.baseURL}/studentCourseFileNew.htm`,
387
+ }
388
+ });
389
+ this.logDebug('getCourses', response.data);
390
+ return response.data;
391
+ });
392
+ }
393
+ /**
394
+ * Fetches high-level attendance summary statistics.
395
+ * @returns A promise resolving to AttendanceDetails.
396
+ */
397
+ getAttendanceDetails() {
398
+ return __awaiter(this, void 0, void 0, function* () {
399
+ const response = yield this.api.get('/stu_getAttendanceDetails.json', {
400
+ headers: {
401
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
402
+ }
403
+ });
404
+ const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
405
+ this.logDebug('getAttendanceDetails', data);
406
+ return data;
407
+ });
408
+ }
409
+ /**
410
+ * Fetches attendance distribution data for visualization/graphing.
411
+ * @param termId - The term to filter by. Defaults to 'All'.
412
+ * @returns A promise resolving to an array of AttendanceGraph data points.
413
+ */
414
+ getAttendanceGraph() {
415
+ return __awaiter(this, arguments, void 0, function* (termId = 'All') {
416
+ const response = yield this.api.post('/stu_getGraphForStudentAttendence.json', qs.stringify({ termId }), {
417
+ headers: {
418
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
419
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
420
+ },
421
+ });
422
+ this.logDebug('getAttendanceGraph', response.data);
423
+ return response.data;
424
+ });
425
+ }
426
+ // ============================================
427
+ // Results & Exams
428
+ // ============================================
429
+ /**
430
+ * Fetches detailed marks and results for a specific examination.
431
+ * @param params - Parameters defining the specific exam schedule and syllabus.
432
+ * @returns A promise resolving to an array of ResultDetail objects.
433
+ */
434
+ getStudentResults(params) {
435
+ return __awaiter(this, void 0, void 0, function* () {
436
+ const queryParams = new URLSearchParams({
437
+ examScheduleId: params.examScheduleId,
438
+ examSemesterId: params.examSemesterId,
439
+ universitySyllabusId: params.universitySyllabusId.toString(),
440
+ });
441
+ const response = yield this.api.get(`/stu_getStudentSideResult.json?${queryParams}`, {
442
+ headers: {
443
+ 'Referer': `${this.api.defaults.baseURL}/stu_studentSideResult.htm`,
444
+ }
445
+ });
446
+ this.logDebug('getStudentResults', response.data);
447
+ return response.data;
448
+ });
449
+ }
450
+ /**
451
+ * Fetches overall examination performance and marks statistics.
452
+ * @returns A promise resolving to ExamDetails.
453
+ */
454
+ getExamDetails() {
455
+ return __awaiter(this, void 0, void 0, function* () {
456
+ const response = yield this.api.get('/stu_getExamDetails.json', {
457
+ headers: {
458
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
459
+ }
460
+ });
461
+ const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
462
+ this.logDebug('getExamDetails', data);
463
+ return data;
464
+ });
465
+ }
466
+ // ============================================
467
+ // Finance & Fees
468
+ // ============================================
469
+ /**
470
+ * Fetches the current fee invoice and structure summary.
471
+ * @returns A promise resolving to FeesDetails.
472
+ */
473
+ getFeesDetails() {
474
+ return __awaiter(this, void 0, void 0, function* () {
475
+ const response = yield this.api.get('/stu_getFeesDetails.json', {
476
+ headers: {
477
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
478
+ }
479
+ });
480
+ const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
481
+ this.logDebug('getFeesDetails', data);
482
+ return data;
483
+ });
484
+ }
485
+ /**
486
+ * Fetches the detailed fee break-up for the current student.
487
+ * @returns A promise resolving to an array of fee items.
488
+ */
489
+ getFeeStructureByStudentId() {
490
+ return __awaiter(this, void 0, void 0, function* () {
491
+ const response = yield this.api.get('/stu_getfeestructureDetailsbyStudentId.json', {
492
+ headers: {
493
+ 'Referer': `${this.api.defaults.baseURL}/stu_getfeestructureDetailsbyStudentId.htm`,
494
+ }
495
+ });
496
+ this.logDebug('getFeeStructureByStudentId', response.data);
497
+ return response.data;
498
+ });
499
+ }
500
+ /**
501
+ * Alternative method to fetch fee structure from the student-side view.
502
+ * @returns A promise resolving to an array of fee items.
503
+ */
504
+ getFeeStructureByStudentIdOfStudentSide() {
505
+ return __awaiter(this, void 0, void 0, function* () {
506
+ const response = yield this.api.get('/stu_getfeestructureDetailsbyStudentIdofstudentSide.json', {
507
+ headers: {
508
+ 'Referer': `${this.api.defaults.baseURL}/stu_getfeestructureDetailsbyStudentIdofstudentSide.htm`,
509
+ }
510
+ });
511
+ this.logDebug('getFeeStructureByStudentIdOfStudentSide', response.data);
512
+ return response.data;
513
+ });
514
+ }
515
+ /**
516
+ * Fetches the total receivables, including academic, hostel, and miscellaneous fees.
517
+ * @returns A promise resolving to StudentReceivable details.
518
+ */
519
+ getStudentReceivable() {
520
+ return __awaiter(this, void 0, void 0, function* () {
521
+ const response = yield this.api.get('/stu_getStudentReceivableDetailsNew.json', {
522
+ headers: {
523
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
524
+ }
525
+ });
526
+ this.logDebug('getStudentReceivable', response.data);
527
+ return response.data;
528
+ });
529
+ }
530
+ // ============================================
531
+ // Timetable
532
+ // ============================================
533
+ /**
534
+ * Fetches the student's schedule for a specific date.
535
+ * @param date - The date to fetch for (standard format).
536
+ * @returns A promise resolving to an array of TodaySchedule objects.
537
+ */
538
+ getTodaySchedule(date) {
539
+ return __awaiter(this, void 0, void 0, function* () {
540
+ const response = yield this.api.get(`/stu_getTodaysScheduleForStudentLoggedIn.json?date=${encodeURIComponent(date)}`, {
541
+ headers: {
542
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
543
+ }
544
+ });
545
+ this.logDebug('getTodaySchedule', response.data);
546
+ return response.data;
547
+ });
548
+ }
549
+ /**
550
+ * Fetches the timetable entries between two dates.
551
+ * @param params - Date range and optional term filter.
552
+ * @returns A promise resolving to an array of DetailedTimetableEntry objects.
553
+ */
554
+ getTimetableBetweenDates(params) {
555
+ return __awaiter(this, void 0, void 0, function* () {
556
+ var _a;
557
+ const queryParams = new URLSearchParams({
558
+ startDate: params.startDate,
559
+ endDate: params.endDate,
560
+ termId: ((_a = params.termId) !== null && _a !== void 0 ? _a : 0).toString(),
561
+ });
562
+ const response = yield this.api.get(`/stu_getBetweenDatesTimetableForStudentSP.json?${queryParams}`, {
563
+ headers: {
564
+ 'Referer': `${this.api.defaults.baseURL}/stu_getBetweenDatesTimetableForStudentSP.htm`,
565
+ }
566
+ });
567
+ this.logDebug('getTimetableBetweenDates', response.data);
568
+ return response.data;
569
+ });
570
+ }
571
+ // ============================================
572
+ // Search
573
+ // ============================================
574
+ /**
575
+ * Performs a global search across student and faculty records.
576
+ * @param query - The search string (e.g., name or ID).
577
+ * @returns A promise resolving to an array of SearchResult objects.
578
+ */
579
+ search(query) {
580
+ return __awaiter(this, void 0, void 0, function* () {
581
+ const response = yield this.api.get(`/populateAllforStudentPost.json?q=${encodeURIComponent(query)}`, {
582
+ headers: {
583
+ 'Referer': `${this.api.defaults.baseURL}/home.htm`,
584
+ }
585
+ });
586
+ this.logDebug('search', response.data);
587
+ return response.data;
588
+ });
589
+ }
590
+ // ============================================
591
+ // Utility Methods
592
+ // ============================================
593
+ /**
594
+ * Retrieves the internal student ID from the current active session.
595
+ * @returns A promise resolving to the student ID.
596
+ */
597
+ getStudentIdFromSession() {
598
+ return __awaiter(this, void 0, void 0, function* () {
599
+ const response = yield this.api.get('/stu_getStudentIdFromSession.json', {
600
+ headers: {
601
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
602
+ }
603
+ });
604
+ this.logDebug('getStudentIdFromSession', response.data);
605
+ return parseInt(response.data, 10);
606
+ });
607
+ }
608
+ /**
609
+ * Fetches details of any course transfer requests made by the student.
610
+ * @returns A promise resolving to an object with transfer details.
611
+ */
612
+ getTransferDetails() {
613
+ return __awaiter(this, void 0, void 0, function* () {
614
+ const response = yield this.api.get('/stu_getTransferDetails.json', {
615
+ headers: {
616
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
617
+ }
618
+ });
619
+ const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
620
+ this.logDebug('getTransferDetails', data);
621
+ return data;
622
+ });
623
+ }
624
+ /**
625
+ * Fetches the historical transfer record of the student.
626
+ * @returns A promise resolving to an array of TransferDetailsOfStudent objects.
627
+ */
628
+ getTransferDetailsOfStudent() {
629
+ return __awaiter(this, void 0, void 0, function* () {
630
+ const response = yield this.api.get('/stu_getTransferDetailsOfStudent.json', {
631
+ headers: {
632
+ 'Referer': `${this.api.defaults.baseURL}/stu_myDashBoard.htm`,
633
+ }
634
+ });
635
+ this.logDebug('getTransferDetailsOfStudent', response.data);
636
+ return response.data;
637
+ });
638
+ }
639
+ }
640
+ exports.JunoClient = JunoClient;
641
+ // Export types for convenience
642
+ __exportStar(require("./types"), exports);