webuntis-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.
Files changed (62) hide show
  1. package/README.md +5 -0
  2. package/dist/Credentials.d.ts +16 -0
  3. package/dist/Credentials.d.ts.map +1 -0
  4. package/dist/Credentials.js +34 -0
  5. package/dist/WebUntis.d.ts +108 -0
  6. package/dist/WebUntis.d.ts.map +1 -0
  7. package/dist/WebUntis.js +192 -0
  8. package/dist/clients/Api.d.ts +28 -0
  9. package/dist/clients/Api.d.ts.map +1 -0
  10. package/dist/clients/Api.js +58 -0
  11. package/dist/clients/Http.d.ts +22 -0
  12. package/dist/clients/Http.d.ts.map +1 -0
  13. package/dist/clients/Http.js +71 -0
  14. package/dist/clients/JsonRpc.d.ts +23 -0
  15. package/dist/clients/JsonRpc.d.ts.map +1 -0
  16. package/dist/clients/JsonRpc.js +62 -0
  17. package/dist/errors/Authentication.d.ts +5 -0
  18. package/dist/errors/Authentication.d.ts.map +1 -0
  19. package/dist/errors/Authentication.js +8 -0
  20. package/dist/errors/Network.d.ts +6 -0
  21. package/dist/errors/Network.d.ts.map +1 -0
  22. package/dist/errors/Network.js +10 -0
  23. package/dist/errors/Validation.d.ts +5 -0
  24. package/dist/errors/Validation.d.ts.map +1 -0
  25. package/dist/errors/Validation.js +8 -0
  26. package/dist/errors/WebUntis.d.ts +5 -0
  27. package/dist/errors/WebUntis.d.ts.map +1 -0
  28. package/dist/errors/WebUntis.js +9 -0
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +2 -0
  32. package/dist/managers/Authentication.d.ts +37 -0
  33. package/dist/managers/Authentication.d.ts.map +1 -0
  34. package/dist/managers/Authentication.js +65 -0
  35. package/dist/managers/Token.d.ts +43 -0
  36. package/dist/managers/Token.d.ts.map +1 -0
  37. package/dist/managers/Token.js +92 -0
  38. package/dist/services/AppData.d.ts +76 -0
  39. package/dist/services/AppData.d.ts.map +1 -0
  40. package/dist/services/AppData.js +130 -0
  41. package/dist/services/Profile.d.ts +14 -0
  42. package/dist/services/Profile.d.ts.map +1 -0
  43. package/dist/services/Profile.js +16 -0
  44. package/dist/services/Timetable.d.ts +24 -0
  45. package/dist/services/Timetable.d.ts.map +1 -0
  46. package/dist/services/Timetable.js +46 -0
  47. package/dist/types/app-data.d.ts +72 -0
  48. package/dist/types/app-data.d.ts.map +1 -0
  49. package/dist/types/app-data.js +1 -0
  50. package/dist/types/jsonrpc.d.ts +11 -0
  51. package/dist/types/jsonrpc.d.ts.map +1 -0
  52. package/dist/types/jsonrpc.js +1 -0
  53. package/dist/types/profile.d.ts +31 -0
  54. package/dist/types/profile.d.ts.map +1 -0
  55. package/dist/types/profile.js +1 -0
  56. package/dist/types/session.d.ts +7 -0
  57. package/dist/types/session.d.ts.map +1 -0
  58. package/dist/types/session.js +1 -0
  59. package/dist/types/timetable.d.ts +86 -0
  60. package/dist/types/timetable.d.ts.map +1 -0
  61. package/dist/types/timetable.js +1 -0
  62. package/package.json +49 -0
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Web Untis Client
2
+
3
+ A Web Untis API Client to interact with [Web Untis](https://webuntis.com).
4
+
5
+ > 🚧 WIP 🚧
@@ -0,0 +1,16 @@
1
+ export declare class Credentials {
2
+ private readonly _identity;
3
+ private readonly _school;
4
+ private readonly _username;
5
+ private readonly _password;
6
+ private readonly _url;
7
+ private readonly _schoolBase64;
8
+ constructor(_identity: string, _school: string, _username: string, _password: string);
9
+ get identity(): string;
10
+ get school(): string;
11
+ get username(): string;
12
+ get password(): string;
13
+ get url(): string;
14
+ get schoolBase64(): string;
15
+ }
16
+ //# sourceMappingURL=Credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Credentials.d.ts","sourceRoot":"","sources":["../src/Credentials.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW;IAKhB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAGlB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM;IAMtC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;CACJ"}
@@ -0,0 +1,34 @@
1
+ export class Credentials {
2
+ _identity;
3
+ _school;
4
+ _username;
5
+ _password;
6
+ _url;
7
+ _schoolBase64;
8
+ constructor(_identity, _school, _username, _password) {
9
+ this._identity = _identity;
10
+ this._school = _school;
11
+ this._username = _username;
12
+ this._password = _password;
13
+ this._url = `https://${_school}.webuntis.com`;
14
+ this._schoolBase64 = "_" + Buffer.from(_school).toString("base64");
15
+ }
16
+ get identity() {
17
+ return this._identity;
18
+ }
19
+ get school() {
20
+ return this._school;
21
+ }
22
+ get username() {
23
+ return this._username;
24
+ }
25
+ get password() {
26
+ return this._password;
27
+ }
28
+ get url() {
29
+ return this._url;
30
+ }
31
+ get schoolBase64() {
32
+ return this._schoolBase64;
33
+ }
34
+ }
@@ -0,0 +1,108 @@
1
+ import { Credentials } from "./Credentials";
2
+ import { AppData, CurrentSchoolYear, Holiday, OneDriveData, Tenant, User } from './types/app-data';
3
+ import { Profile } from "./types/profile";
4
+ import { SessionInfo } from "./types/session";
5
+ import { TimetableResponse } from "./types/timetable";
6
+ export declare class WebUntisClient {
7
+ private readonly _httpClient;
8
+ private readonly _apiClient;
9
+ private readonly _rpcClient;
10
+ private readonly _authManager;
11
+ private readonly _tokenManager;
12
+ private readonly _appDataService;
13
+ private readonly _profileService;
14
+ private readonly _timetableService;
15
+ constructor(credentials: Credentials);
16
+ /**
17
+ * Login to WebUntis
18
+ */
19
+ login(): Promise<SessionInfo>;
20
+ /**
21
+ * Logout and end session
22
+ */
23
+ logout(): Promise<void>;
24
+ /**
25
+ * Check if currently authenticated
26
+ */
27
+ isAuthenticated(): boolean;
28
+ /**
29
+ * Get current session info
30
+ */
31
+ getSession(): SessionInfo | null;
32
+ /**
33
+ * Get app data
34
+ */
35
+ getAppData(): Promise<AppData>;
36
+ /**
37
+ * Get current school year from cache
38
+ */
39
+ getCurrentSchoolYear(): CurrentSchoolYear;
40
+ /**
41
+ * Get current school year id from cache
42
+ */
43
+ getCurrentSchoolYearId(): string;
44
+ /**
45
+ * Get departments from cache
46
+ */
47
+ getDepartments(): unknown[];
48
+ /**
49
+ * Check if playground mode is enabled
50
+ */
51
+ isPlayground(): boolean;
52
+ /**
53
+ * Get OneDrive data from cache
54
+ */
55
+ getOneDriveData(): OneDriveData;
56
+ /**
57
+ * Get tenant information from cache
58
+ */
59
+ getTenant(): Tenant;
60
+ /**
61
+ * Check if UI 2020 is enabled
62
+ */
63
+ isUi2020(): boolean;
64
+ /**
65
+ * Get user information from cache
66
+ */
67
+ getUser(): User;
68
+ /**
69
+ * Get user permissions from cache
70
+ */
71
+ getPermissions(): string[];
72
+ /**
73
+ * Get settings from cache
74
+ */
75
+ getSettings(): string[];
76
+ /**
77
+ * Get polling jobs from cache
78
+ */
79
+ getPollingJobs(): unknown[];
80
+ /**
81
+ * Check if support access is open
82
+ */
83
+ isSupportAccessOpen(): boolean;
84
+ /**
85
+ * Get license expiration date from cache
86
+ */
87
+ getLicenceExpiresAt(): string;
88
+ /**
89
+ * Get holidays from cache
90
+ */
91
+ getHolidays(): Holiday[];
92
+ /**
93
+ * Get current user's profile
94
+ */
95
+ getProfile(): Promise<Profile>;
96
+ /**
97
+ * Get own timetable for date range
98
+ *
99
+ * @param start - Start date
100
+ * @param end - End date
101
+ */
102
+ getOwnTimetable(start: Date, end: Date): Promise<TimetableResponse>;
103
+ /**
104
+ * Ensure user is authenticated
105
+ */
106
+ private _ensureAuthenticated;
107
+ }
108
+ //# sourceMappingURL=WebUntis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebUntis.d.ts","sourceRoot":"","sources":["../src/WebUntis.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5C,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAG3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAG7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;gBAEzC,WAAW,EAAE,WAAW;IAgCpC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IASnC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;OAEG;IACH,UAAU,IAAI,WAAW,GAAG,IAAI;IAQhC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAKpC;;OAEG;IACH,oBAAoB,IAAI,iBAAiB;IAIzC;;OAEG;IACH,sBAAsB,IAAI,MAAM;IAIhC;;OAEG;IACH,cAAc,IAAI,OAAO,EAAE;IAI3B;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;OAEG;IACH,cAAc,IAAI,OAAO,EAAE;IAI3B;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;OAEG;IACH,WAAW,IAAI,OAAO,EAAE;IAQxB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IASpC;;;;;OAKG;IACG,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC;IASzE;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAS/B"}
@@ -0,0 +1,192 @@
1
+ import { ApiClient } from "./clients/Api";
2
+ import { HttpClient } from "./clients/Http";
3
+ import { JsonRpcClient } from "./clients/JsonRpc";
4
+ import { ValidationError } from "./errors/Validation";
5
+ import { AuthenticationManager } from "./managers/Authentication";
6
+ import { TokenManager } from "./managers/Token";
7
+ import { AppDataService } from "./services/AppData";
8
+ import { ProfileService } from "./services/Profile";
9
+ import { TimetableService } from "./services/Timetable";
10
+ export class WebUntisClient {
11
+ // Clients
12
+ _httpClient;
13
+ _apiClient;
14
+ _rpcClient;
15
+ // Managers
16
+ _authManager;
17
+ _tokenManager;
18
+ // Services
19
+ _appDataService;
20
+ _profileService;
21
+ _timetableService;
22
+ constructor(credentials) {
23
+ const { identity, url } = credentials;
24
+ // Clients
25
+ this._httpClient = new HttpClient(url);
26
+ this._rpcClient = new JsonRpcClient(identity, url);
27
+ // Managers
28
+ this._authManager = new AuthenticationManager(credentials, this._rpcClient);
29
+ this._tokenManager = new TokenManager(this._httpClient, () => this._authManager.getCookies());
30
+ // Clients
31
+ this._apiClient = new ApiClient(this._httpClient, () => this._authManager.getCookies(), () => this._tokenManager.getToken(), () => this._tokenManager.getTenantId(), () => this.getCurrentSchoolYearId());
32
+ // Services
33
+ this._appDataService = new AppDataService(this._apiClient);
34
+ this._profileService = new ProfileService(this._apiClient);
35
+ this._timetableService = new TimetableService(this._apiClient, this._authManager);
36
+ }
37
+ //#region Authentication
38
+ /**
39
+ * Login to WebUntis
40
+ */
41
+ async login() {
42
+ const session = await this._authManager.login();
43
+ await this._tokenManager.getToken();
44
+ await this._appDataService.getAppData();
45
+ return session;
46
+ }
47
+ /**
48
+ * Logout and end session
49
+ */
50
+ async logout() {
51
+ await this._authManager.logout();
52
+ this._tokenManager.clearToken();
53
+ this._appDataService.clearCache();
54
+ }
55
+ /**
56
+ * Check if currently authenticated
57
+ */
58
+ isAuthenticated() {
59
+ return this._authManager.isAuthenticated();
60
+ }
61
+ /**
62
+ * Get current session info
63
+ */
64
+ getSession() {
65
+ return this._authManager.getSession();
66
+ }
67
+ //#endregion
68
+ //#region App Data
69
+ /**
70
+ * Get app data
71
+ */
72
+ async getAppData() {
73
+ this._ensureAuthenticated();
74
+ return await this._appDataService.getAppData();
75
+ }
76
+ /**
77
+ * Get current school year from cache
78
+ */
79
+ getCurrentSchoolYear() {
80
+ return this._appDataService.getCurrentSchoolYear();
81
+ }
82
+ /**
83
+ * Get current school year id from cache
84
+ */
85
+ getCurrentSchoolYearId() {
86
+ return this._appDataService.getCurrentSchoolYearId();
87
+ }
88
+ /**
89
+ * Get departments from cache
90
+ */
91
+ getDepartments() {
92
+ return this._appDataService.getDepartments();
93
+ }
94
+ /**
95
+ * Check if playground mode is enabled
96
+ */
97
+ isPlayground() {
98
+ return this._appDataService.isPlayground();
99
+ }
100
+ /**
101
+ * Get OneDrive data from cache
102
+ */
103
+ getOneDriveData() {
104
+ return this._appDataService.getOneDriveData();
105
+ }
106
+ /**
107
+ * Get tenant information from cache
108
+ */
109
+ getTenant() {
110
+ return this._appDataService.getTenant();
111
+ }
112
+ /**
113
+ * Check if UI 2020 is enabled
114
+ */
115
+ isUi2020() {
116
+ return this._appDataService.isUi2020();
117
+ }
118
+ /**
119
+ * Get user information from cache
120
+ */
121
+ getUser() {
122
+ return this._appDataService.getUser();
123
+ }
124
+ /**
125
+ * Get user permissions from cache
126
+ */
127
+ getPermissions() {
128
+ return this._appDataService.getPermissions();
129
+ }
130
+ /**
131
+ * Get settings from cache
132
+ */
133
+ getSettings() {
134
+ return this._appDataService.getSettings();
135
+ }
136
+ /**
137
+ * Get polling jobs from cache
138
+ */
139
+ getPollingJobs() {
140
+ return this._appDataService.getPollingJobs();
141
+ }
142
+ /**
143
+ * Check if support access is open
144
+ */
145
+ isSupportAccessOpen() {
146
+ return this._appDataService.isSupportAccessOpen();
147
+ }
148
+ /**
149
+ * Get license expiration date from cache
150
+ */
151
+ getLicenceExpiresAt() {
152
+ return this._appDataService.getLicenceExpiresAt();
153
+ }
154
+ /**
155
+ * Get holidays from cache
156
+ */
157
+ getHolidays() {
158
+ return this._appDataService.getHolidays();
159
+ }
160
+ //#endregion
161
+ //#region User's Profile
162
+ /**
163
+ * Get current user's profile
164
+ */
165
+ async getProfile() {
166
+ this._ensureAuthenticated();
167
+ return await this._profileService.getProfile();
168
+ }
169
+ //#endregion
170
+ //#region Own Timetable
171
+ /**
172
+ * Get own timetable for date range
173
+ *
174
+ * @param start - Start date
175
+ * @param end - End date
176
+ */
177
+ async getOwnTimetable(start, end) {
178
+ this._ensureAuthenticated();
179
+ return await this._timetableService.getOwnTimetable(start, end);
180
+ }
181
+ //#endregion
182
+ //#region Helpers
183
+ /**
184
+ * Ensure user is authenticated
185
+ */
186
+ _ensureAuthenticated() {
187
+ const isNotAuthenticated = !this._authManager.isAuthenticated();
188
+ if (isNotAuthenticated) {
189
+ throw new ValidationError('Not authenticated. Please call login() first.');
190
+ }
191
+ }
192
+ }
@@ -0,0 +1,28 @@
1
+ import { AppData } from '../types/app-data';
2
+ import { ProfileResponse } from '../types/profile';
3
+ import { TimetableResponse } from '../types/timetable';
4
+ import { HttpClient } from './Http';
5
+ /**
6
+ * Client for WebUntis REST API endpoints
7
+ */
8
+ export declare class ApiClient {
9
+ private readonly _httpClient;
10
+ private readonly _getCookies;
11
+ private readonly _getToken;
12
+ private readonly _getTenantId;
13
+ private readonly _getSchoolYearId;
14
+ constructor(_httpClient: HttpClient, _getCookies: () => string, _getToken: () => Promise<string>, _getTenantId: () => string | null, _getSchoolYearId: () => string);
15
+ /**
16
+ * Fetch app data
17
+ */
18
+ fetchAppData(): Promise<AppData>;
19
+ /**
20
+ * Fetch user profile data
21
+ */
22
+ fetchProfile(): Promise<ProfileResponse>;
23
+ /**
24
+ * Fetch timetable entries
25
+ */
26
+ fetchOwnTimetable(params: URLSearchParams): Promise<TimetableResponse>;
27
+ }
28
+ //# sourceMappingURL=Api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Api.d.ts","sourceRoot":"","sources":["../../src/clients/Api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;GAEG;AACH,qBAAa,SAAS;IAEd,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAJhB,WAAW,EAAE,UAAU,EACvB,WAAW,EAAE,MAAM,MAAM,EACzB,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAChC,YAAY,EAAE,MAAM,MAAM,GAAG,IAAI,EACjC,gBAAgB,EAAE,MAAM,MAAM;IAGnD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAmBtC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;IAS9C;;OAEG;IACG,iBAAiB,CACnB,MAAM,EAAE,eAAe,GACxB,OAAO,CAAC,iBAAiB,CAAC;CAoBhC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Client for WebUntis REST API endpoints
3
+ */
4
+ export class ApiClient {
5
+ _httpClient;
6
+ _getCookies;
7
+ _getToken;
8
+ _getTenantId;
9
+ _getSchoolYearId;
10
+ constructor(_httpClient, _getCookies, _getToken, _getTenantId, _getSchoolYearId) {
11
+ this._httpClient = _httpClient;
12
+ this._getCookies = _getCookies;
13
+ this._getToken = _getToken;
14
+ this._getTenantId = _getTenantId;
15
+ this._getSchoolYearId = _getSchoolYearId;
16
+ }
17
+ /**
18
+ * Fetch app data
19
+ */
20
+ async fetchAppData() {
21
+ const token = await this._getToken();
22
+ const tenantId = this._getTenantId();
23
+ const cookies = this._getCookies();
24
+ if (!tenantId) {
25
+ throw new Error('Tenant ID not available');
26
+ }
27
+ return this._httpClient.get('/WebUntis/api/rest/view/v1/app/data', {
28
+ Authorization: `Bearer ${token}`,
29
+ 'tenant-id': tenantId,
30
+ Cookie: cookies,
31
+ });
32
+ }
33
+ /**
34
+ * Fetch user profile data
35
+ */
36
+ async fetchProfile() {
37
+ const cookies = this._getCookies();
38
+ return this._httpClient.get('/WebUntis/api/profile/general', { Cookie: cookies });
39
+ }
40
+ /**
41
+ * Fetch timetable entries
42
+ */
43
+ async fetchOwnTimetable(params) {
44
+ const token = await this._getToken();
45
+ const tenantId = this._getTenantId();
46
+ const cookies = this._getCookies();
47
+ const schoolYearId = this._getSchoolYearId();
48
+ if (!tenantId) {
49
+ throw new Error('Tenant ID not available');
50
+ }
51
+ return await this._httpClient.get(`/WebUntis/api/rest/view/v1/timetable/entries?${params}`, {
52
+ Authorization: `Bearer ${token}`,
53
+ 'tenant-id': tenantId,
54
+ 'x-webuntis-api-school-year-id': schoolYearId,
55
+ Cookie: cookies,
56
+ });
57
+ }
58
+ }
@@ -0,0 +1,22 @@
1
+ export declare class HttpClient {
2
+ private readonly _url;
3
+ private readonly _defaultHeaders;
4
+ constructor(_url: string);
5
+ /**
6
+ * Make a GET request
7
+ */
8
+ get<T>(endpoint: string, headers?: Record<string, string>): Promise<T>;
9
+ /**
10
+ * Make a POST request
11
+ */
12
+ post<T>(endpoint: string, body?: Record<string, unknown>, headers?: Record<string, string>): Promise<T>;
13
+ /**
14
+ * Make a GET request that returns text
15
+ */
16
+ getText(endpoint: string, headers?: Record<string, string>): Promise<string>;
17
+ /**
18
+ * Handle HTTP response and errors
19
+ */
20
+ private _handleResponse;
21
+ }
22
+ //# sourceMappingURL=Http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../src/clients/Http.ts"],"names":[],"mappings":"AAGA,qBAAa,UAAU;IAQP,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAK9B;gBAE2B,IAAI,EAAE,MAAM;IAEzC;;OAEG;IACG,GAAG,CAAC,CAAC,EACP,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC;IAeb;;OAEG;IACG,IAAI,CAAC,CAAC,EACR,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC;IAkBb;;OAEG;IACG,OAAO,CACT,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;IAsBlB;;OAEG;YACW,eAAe;CAgBhC"}
@@ -0,0 +1,71 @@
1
+ import { NetworkError } from "../errors/Network";
2
+ export class HttpClient {
3
+ _url;
4
+ _defaultHeaders = {
5
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36',
6
+ 'Cache-Control': 'no-cache',
7
+ 'X-Requested-With': 'XMLHttpRequest',
8
+ Pragma: 'no-cache',
9
+ };
10
+ constructor(_url) {
11
+ this._url = _url;
12
+ }
13
+ /**
14
+ * Make a GET request
15
+ */
16
+ async get(endpoint, headers) {
17
+ const response = await fetch(`${this._url}${endpoint}`, {
18
+ method: 'GET',
19
+ headers: {
20
+ ...this._defaultHeaders,
21
+ ...headers,
22
+ },
23
+ });
24
+ return this._handleResponse(response);
25
+ }
26
+ /**
27
+ * Make a POST request
28
+ */
29
+ async post(endpoint, body, headers) {
30
+ const response = await fetch(`${this._url}${endpoint}`, {
31
+ method: 'POST',
32
+ headers: {
33
+ ...this._defaultHeaders,
34
+ 'Content-Type': 'application/json',
35
+ ...headers,
36
+ },
37
+ body: body ? JSON.stringify(body) : undefined,
38
+ redirect: 'manual',
39
+ });
40
+ return this._handleResponse(response);
41
+ }
42
+ /**
43
+ * Make a GET request that returns text
44
+ */
45
+ async getText(endpoint, headers) {
46
+ const response = await fetch(`${this._url}${endpoint}`, {
47
+ method: 'GET',
48
+ headers: {
49
+ ...this._defaultHeaders,
50
+ ...headers,
51
+ },
52
+ });
53
+ if (!response.ok) {
54
+ throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`, response.status);
55
+ }
56
+ return response.text();
57
+ }
58
+ /**
59
+ * Handle HTTP response and errors
60
+ */
61
+ async _handleResponse(response) {
62
+ if (response.status < 200 || response.status >= 303) {
63
+ throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`, response.status);
64
+ }
65
+ const contentType = response.headers.get('content-type');
66
+ if (contentType?.includes('application/json')) {
67
+ return response.json();
68
+ }
69
+ return response.text();
70
+ }
71
+ }
@@ -0,0 +1,23 @@
1
+ import { SessionInfo } from '../types/session';
2
+ /**
3
+ * JSON-RPC client for WebUntis API
4
+ */
5
+ export declare class JsonRpcClient {
6
+ private readonly _identity;
7
+ private readonly _httpClient;
8
+ private readonly _endpoint;
9
+ constructor(_identity: string, url: string);
10
+ /**
11
+ * Authenticate user and get session
12
+ */
13
+ authenticate(username: string, password: string, client: string): Promise<SessionInfo>;
14
+ /**
15
+ * Logout and end session
16
+ */
17
+ logout(cookies: string): Promise<void>;
18
+ /**
19
+ * Make a JSON-RPC call
20
+ */
21
+ private _call;
22
+ }
23
+ //# sourceMappingURL=JsonRpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonRpc.d.ts","sourceRoot":"","sources":["../../src/clients/JsonRpc.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C;;GAEG;AACH,qBAAa,aAAa;IAKlB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;gBAG/B,SAAS,EAAE,MAAM,EAClC,GAAG,EAAE,MAAM;IAKf;;OAEG;IACG,YAAY,CACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC;IAyBvB;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;YACW,KAAK;CAiCtB"}
@@ -0,0 +1,62 @@
1
+ import { AuthenticationError } from '../errors/Authentication';
2
+ import { HttpClient } from './Http';
3
+ /**
4
+ * JSON-RPC client for WebUntis API
5
+ */
6
+ export class JsonRpcClient {
7
+ _identity;
8
+ _httpClient;
9
+ _endpoint = '/WebUntis/jsonrpc.do';
10
+ constructor(_identity, url) {
11
+ this._identity = _identity;
12
+ this._httpClient = new HttpClient(url);
13
+ }
14
+ /**
15
+ * Authenticate user and get session
16
+ */
17
+ async authenticate(username, password, client) {
18
+ try {
19
+ const result = await this._call('authenticate', {
20
+ user: username,
21
+ password: password,
22
+ client: client,
23
+ });
24
+ if (!result.sessionId) {
25
+ throw new AuthenticationError('Authentication failed: No session ID returned');
26
+ }
27
+ return result;
28
+ }
29
+ catch (error) {
30
+ if (error instanceof AuthenticationError) {
31
+ throw error;
32
+ }
33
+ throw new AuthenticationError(`Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
34
+ }
35
+ }
36
+ /**
37
+ * Logout and end session
38
+ */
39
+ async logout(cookies) {
40
+ await this._call('logout', {}, cookies);
41
+ }
42
+ /**
43
+ * Make a JSON-RPC call
44
+ */
45
+ async _call(method, params, cookies) {
46
+ const headers = {};
47
+ if (cookies) {
48
+ headers.Cookie = cookies;
49
+ }
50
+ const body = {
51
+ id: this._identity,
52
+ jsonrpc: '2.0',
53
+ method,
54
+ params,
55
+ };
56
+ const response = await this._httpClient.post(this._endpoint, body, headers);
57
+ if (response.error) {
58
+ throw new AuthenticationError(`${response.error.message} (${response.error.code})`, response.error.code.toString());
59
+ }
60
+ return response.result;
61
+ }
62
+ }
@@ -0,0 +1,5 @@
1
+ import { WebUntisError } from "./WebUntis";
2
+ export declare class AuthenticationError extends WebUntisError {
3
+ constructor(message: string, code?: string);
4
+ }
5
+ //# sourceMappingURL=Authentication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Authentication.d.ts","sourceRoot":"","sources":["../../src/errors/Authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,mBAAoB,SAAQ,aAAa;gBACtC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAK7C"}
@@ -0,0 +1,8 @@
1
+ import { WebUntisError } from "./WebUntis";
2
+ export class AuthenticationError extends WebUntisError {
3
+ constructor(message, code) {
4
+ super(message, code);
5
+ this.name = 'AuthenticationError';
6
+ Object.setPrototypeOf(this, AuthenticationError.prototype);
7
+ }
8
+ }
@@ -0,0 +1,6 @@
1
+ import { WebUntisError } from "./WebUntis";
2
+ export declare class NetworkError extends WebUntisError {
3
+ readonly statusCode?: number | undefined;
4
+ constructor(message: string, statusCode?: number | undefined, code?: string);
5
+ }
6
+ //# sourceMappingURL=Network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Network.d.ts","sourceRoot":"","sources":["../../src/errors/Network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,YAAa,SAAQ,aAAa;aAGvB,UAAU,CAAC,EAAE,MAAM;gBADnC,OAAO,EAAE,MAAM,EACC,UAAU,CAAC,EAAE,MAAM,YAAA,EACnC,IAAI,CAAC,EAAE,MAAM;CAMpB"}