bsuir-iis-api 0.9.0 → 0.10.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/CHANGELOG.md +34 -8
- package/README.md +9 -2
- package/dist/_tsup-dts-rollup.d.ts +285 -106
- package/dist/index.js +239 -210
- package/dist/index.js.map +1 -1
- package/package.json +16 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,18 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## [0.10.0] - 2026-05-13
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `createBsuirClient` options: `allowedBaseUrlHosts`, `allowInsecureHttp`, and `maxResponseBytes`.
|
|
8
|
+
- HTTP internals split into focused modules under `src/client/http/*` (`requestJson`, `response`, `cache`, `retry`, `url`).
|
|
9
|
+
- Schedule internals split into `scheduleApi`, `scheduleFilter`, and `scheduleNormalize`.
|
|
10
|
+
- Shared `createListModule` used by catalog modules to remove duplicated list/read logic.
|
|
11
|
+
- CI/release workflows now generate CycloneDX SBOM (`sbom.cdx.json`) on Node 24.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- `createBsuirClient` now validates and normalizes `baseUrl` strictly (absolute URL, no credentials/query/hash, host allowlist, HTTPS by default).
|
|
16
|
+
- `validateResponses` is now enabled by default.
|
|
17
|
+
- Example scripts now fail with non-zero exit code on unhandled errors.
|
|
18
|
+
- GitHub Actions in CI/release workflows are pinned to commit SHAs.
|
|
19
|
+
- Dev dependencies in `package.json` are now pinned to exact versions.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Response parser now enforces `maxResponseBytes` for both `Content-Length` pre-checks and streamed body reads.
|
|
24
|
+
- `BsuirTimeoutError` now preserves upstream abort timeout cause.
|
|
25
|
+
- Public API report updates for schedule typings (`FlattenedLessonsByDay` and `lessonTypeAbbrev`) and utility export documentation.
|
|
26
|
+
|
|
27
|
+
## [0.9.1] - 2026-05-10
|
|
6
28
|
|
|
7
|
-
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- `http.ts`: cache eviction now performs true LRU — entries are sorted by `accessedAt` timestamp before eviction instead of relying on Map insertion order (which produced FIFO behaviour, not LRU).
|
|
32
|
+
- `http.ts`: `setCache` now removes the key before re-inserting on a cache refresh, ensuring Map insertion order stays consistent with actual last-write time.
|
|
33
|
+
- `http.ts`: `canUseCaching` and `canUseDedup` now check `config.signal?.aborted` in addition to per-request `options.signal`; previously a globally aborted client signal did not suppress cache reads, which could return stale data after cancellation.
|
|
8
34
|
|
|
9
|
-
|
|
35
|
+
### Documentation
|
|
10
36
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
37
|
+
- `types.ts`: all `BsuirClientOptions` fields now have full JSDoc — description, `@defaultValue`, `@example`, and side-effect notes where applicable.
|
|
38
|
+
- `types.ts`: `validateResponses` JSDoc explicitly recommends `process.env.NODE_ENV !== "production"` as a sensible default pattern and clarifies the performance trade-off.
|
|
39
|
+
- `types.ts`: `signal` JSDoc clarifies that an aborted global signal suppresses both cache reads and in-flight deduplication.
|
|
14
40
|
|
|
15
|
-
## [0.
|
|
41
|
+
## [0.9.0] - 2026-05-10
|
|
16
42
|
|
|
17
43
|
### Added
|
|
18
44
|
|
package/README.md
CHANGED
|
@@ -33,6 +33,8 @@ console.log(schedule.lessons.length);
|
|
|
33
33
|
```ts
|
|
34
34
|
const client = createBsuirClient({
|
|
35
35
|
baseUrl: "https://iis.bsuir.by/api/v1",
|
|
36
|
+
allowedBaseUrlHosts: ["iis.bsuir.by"],
|
|
37
|
+
allowInsecureHttp: false,
|
|
36
38
|
timeoutMs: 10000,
|
|
37
39
|
retries: 2,
|
|
38
40
|
retryDelayMs: 300,
|
|
@@ -40,7 +42,8 @@ const client = createBsuirClient({
|
|
|
40
42
|
retryJitter: true,
|
|
41
43
|
cache: { ttlMs: 60_000, maxEntries: 200 },
|
|
42
44
|
dedupeInFlight: true,
|
|
43
|
-
|
|
45
|
+
maxResponseBytes: 5_000_000,
|
|
46
|
+
validateResponses: true,
|
|
44
47
|
hooks: {
|
|
45
48
|
onRetry: ({ endpoint, delayMs, reason }) => {
|
|
46
49
|
console.log("retry", endpoint, delayMs, reason);
|
|
@@ -51,10 +54,14 @@ const client = createBsuirClient({
|
|
|
51
54
|
```
|
|
52
55
|
|
|
53
56
|
- `fetch` can be passed for custom runtime/testing.
|
|
57
|
+
- `baseUrl` is normalized and validated (absolute URL, no credentials/query/hash, host allowlist).
|
|
58
|
+
- `allowedBaseUrlHosts` controls which hosts are allowed for `baseUrl` (defaults to `["iis.bsuir.by"]`).
|
|
59
|
+
- `allowInsecureHttp` enables `http://` only for trusted local/test endpoints.
|
|
54
60
|
- `signal` in `createBsuirClient({ signal })` acts as a global cancellation signal for all requests made by that client.
|
|
55
61
|
- `cache` stores successful GET responses in-memory for the configured TTL.
|
|
56
62
|
- `dedupeInFlight` reuses the same in-flight GET request for concurrent callers (when no per-request signal is passed).
|
|
57
|
-
- `
|
|
63
|
+
- `maxResponseBytes` limits body size per response to protect against memory spikes.
|
|
64
|
+
- `validateResponses` enables runtime payload-shape checks for key endpoints (enabled by default).
|
|
58
65
|
- `hooks` provides lifecycle callbacks (`onRequest`, `onRetry`, `onResponse`, `onError`) for observability.
|
|
59
66
|
- `AbortSignal` is supported by all read methods.
|
|
60
67
|
|
|
@@ -88,43 +88,205 @@ export { BsuirClient as BsuirClient_alias_1 }
|
|
|
88
88
|
* Options accepted by `createBsuirClient`.
|
|
89
89
|
*/
|
|
90
90
|
declare interface BsuirClientOptions {
|
|
91
|
+
/**
|
|
92
|
+
* Base URL of the BSUIR IIS API.
|
|
93
|
+
*
|
|
94
|
+
* @defaultValue "https://iis.bsuir.by/api/v1"
|
|
95
|
+
*/
|
|
91
96
|
baseUrl?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Allows using `http://` for `baseUrl`.
|
|
99
|
+
*
|
|
100
|
+
* Keep disabled unless you explicitly need local/non-TLS endpoints in tests.
|
|
101
|
+
*
|
|
102
|
+
* @defaultValue false
|
|
103
|
+
*/
|
|
104
|
+
allowInsecureHttp?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Allowed hostnames for `baseUrl`.
|
|
107
|
+
*
|
|
108
|
+
* Requests are rejected if `baseUrl` hostname is not in this list.
|
|
109
|
+
*
|
|
110
|
+
* @defaultValue ["iis.bsuir.by"]
|
|
111
|
+
*/
|
|
112
|
+
allowedBaseUrlHosts?: string[];
|
|
113
|
+
/**
|
|
114
|
+
* Custom `fetch` implementation. Useful for environments where the global
|
|
115
|
+
* `fetch` is unavailable (older Node.js versions) or when you want to wrap
|
|
116
|
+
* requests with a proxy, MSW handler, or test mock.
|
|
117
|
+
*
|
|
118
|
+
* @defaultValue globalThis.fetch
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* import nodeFetch from "node-fetch";
|
|
122
|
+
* const client = createBsuirClient({ fetch: nodeFetch as typeof fetch });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
92
125
|
fetch?: typeof globalThis.fetch;
|
|
93
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Global `AbortSignal` that cancels **all** requests made by this client
|
|
128
|
+
* instance. Per-call signals are combined with this one.
|
|
129
|
+
*
|
|
130
|
+
* Note: caching and in-flight deduplication are disabled for requests that
|
|
131
|
+
* carry a signal (per-call or global) to prevent stale data from being
|
|
132
|
+
* returned after cancellation.
|
|
133
|
+
*/
|
|
94
134
|
signal?: AbortSignal;
|
|
95
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Request timeout per attempt, in milliseconds.
|
|
137
|
+
*
|
|
138
|
+
* If a single fetch attempt does not complete within this window it is
|
|
139
|
+
* aborted and a `BsuirTimeoutError` is thrown (or the request is retried
|
|
140
|
+
* if retries remain).
|
|
141
|
+
*
|
|
142
|
+
* @defaultValue 10_000 (10 seconds)
|
|
143
|
+
*/
|
|
96
144
|
timeoutMs?: number;
|
|
97
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* Number of additional retry attempts for retriable GET failures (HTTP 429,
|
|
147
|
+
* 500, 502, 503, 504 and network errors). Set to `0` to disable retries.
|
|
148
|
+
*
|
|
149
|
+
* @defaultValue 1
|
|
150
|
+
*/
|
|
98
151
|
retries?: number;
|
|
99
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* Base delay before the first retry, in milliseconds. Subsequent retries use
|
|
154
|
+
* exponential backoff: `retryDelayMs * 2^attempt`, capped by `retryMaxDelayMs`.
|
|
155
|
+
*
|
|
156
|
+
* @defaultValue 300
|
|
157
|
+
*/
|
|
100
158
|
retryDelayMs?: number;
|
|
101
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* Upper bound for the retry delay after backoff, in milliseconds.
|
|
161
|
+
*
|
|
162
|
+
* @defaultValue 3_000 (3 seconds)
|
|
163
|
+
*/
|
|
102
164
|
retryMaxDelayMs?: number;
|
|
103
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* When `true`, a random jitter factor (±25 %) is applied to each retry delay
|
|
167
|
+
* to avoid synchronized retries from multiple clients hitting the API at the
|
|
168
|
+
* same time.
|
|
169
|
+
*
|
|
170
|
+
* @defaultValue true
|
|
171
|
+
*/
|
|
104
172
|
retryJitter?: boolean;
|
|
105
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* Value sent as the `User-Agent` request header. Mainly useful in Node.js
|
|
175
|
+
* environments where servers can log the client identity.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* const client = createBsuirClient({ userAgent: "my-app/1.0.0" });
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
106
182
|
userAgent?: string;
|
|
107
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* In-memory response cache configuration for successful GET requests.
|
|
185
|
+
*
|
|
186
|
+
* When configured, responses are stored in a `Map` keyed by the full request
|
|
187
|
+
* URL. Cache hits skip the network entirely and fire `onResponse` with
|
|
188
|
+
* `fromCache: true`. The cache uses a true LRU eviction policy — the
|
|
189
|
+
* least-recently-*read* entry is evicted first when `maxEntries` is exceeded.
|
|
190
|
+
*
|
|
191
|
+
* Caching is automatically skipped for requests that carry an `AbortSignal`
|
|
192
|
+
* (per-call or global) to prevent serving stale data after cancellation.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* // Cache for 5 minutes, keep at most 500 entries
|
|
197
|
+
* const client = createBsuirClient({
|
|
198
|
+
* cache: { ttlMs: 5 * 60 * 1000, maxEntries: 500 },
|
|
199
|
+
* });
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
108
202
|
cache?: CacheOptions;
|
|
109
|
-
/**
|
|
203
|
+
/**
|
|
204
|
+
* Enables in-flight GET request deduplication by full URL.
|
|
205
|
+
*
|
|
206
|
+
* When two identical GET requests are made concurrently, only the first one
|
|
207
|
+
* hits the network; the second one awaits the same `Promise`. This prevents
|
|
208
|
+
* duplicate API calls in scenarios like parallel component rendering.
|
|
209
|
+
*
|
|
210
|
+
* Disabled automatically when the request carries an `AbortSignal`.
|
|
211
|
+
*
|
|
212
|
+
* @defaultValue true
|
|
213
|
+
*/
|
|
110
214
|
dedupeInFlight?: boolean;
|
|
111
|
-
/**
|
|
215
|
+
/**
|
|
216
|
+
* Maximum allowed response body size (in bytes) for a single request.
|
|
217
|
+
*
|
|
218
|
+
* Helps prevent excessive memory usage on unexpectedly large payloads.
|
|
219
|
+
*
|
|
220
|
+
* @defaultValue 5_000_000 (5 MB)
|
|
221
|
+
*/
|
|
222
|
+
maxResponseBytes?: number;
|
|
223
|
+
/**
|
|
224
|
+
* Enables runtime shape validation of API responses.
|
|
225
|
+
*
|
|
226
|
+
* When `true`, each response is checked against the expected TypeScript type
|
|
227
|
+
* at runtime. An `BsuirApiError` is thrown if the payload does not match,
|
|
228
|
+
* which makes integration issues with the upstream API visible immediately
|
|
229
|
+
* instead of causing silent type-cast bugs later.
|
|
230
|
+
*
|
|
231
|
+
* **Recommended to enable during development and in test environments.**
|
|
232
|
+
* Can be left `false` in production for a small performance gain.
|
|
233
|
+
*
|
|
234
|
+
* @defaultValue true
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```ts
|
|
238
|
+
* // Enable only in non-production environments
|
|
239
|
+
* const client = createBsuirClient({
|
|
240
|
+
* validateResponses: process.env.NODE_ENV !== "production",
|
|
241
|
+
* });
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
112
244
|
validateResponses?: boolean;
|
|
113
|
-
/**
|
|
245
|
+
/**
|
|
246
|
+
* Lifecycle hooks called at various stages of the request pipeline.
|
|
247
|
+
*
|
|
248
|
+
* Useful for logging, metrics collection, or custom error reporting.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* const client = createBsuirClient({
|
|
253
|
+
* hooks: {
|
|
254
|
+
* onRequest: ({ method, path }) => console.log(`→ ${method} ${path}`),
|
|
255
|
+
* onResponse: ({ path, durationMs, fromCache }) =>
|
|
256
|
+
* console.log(`← ${path} ${durationMs}ms${fromCache ? " (cache)" : ""}`),
|
|
257
|
+
* onRetry: ({ path, attempt, reason }) =>
|
|
258
|
+
* console.warn(`↺ ${path} retry #${attempt} (${reason})`),
|
|
259
|
+
* onError: ({ path, error }) => console.error(`✗ ${path}`, error),
|
|
260
|
+
* },
|
|
261
|
+
* });
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
114
264
|
hooks?: ClientHooks;
|
|
115
265
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
266
|
+
* Controls the default return type of `schedule.getGroup` and
|
|
267
|
+
* `schedule.getEmployee` when the per-call `raw` option is omitted.
|
|
268
|
+
*
|
|
269
|
+
* - `false` (default) — returns `NormalizedScheduleResponse` with flattened
|
|
270
|
+
* `lessons`, `lessonsByDay`, `scheduleLessons`, and `examLessons` arrays.
|
|
271
|
+
* - `true` — returns the raw `ScheduleResponse` exactly as received from the
|
|
272
|
+
* BSUIR IIS API.
|
|
118
273
|
*
|
|
119
|
-
*
|
|
274
|
+
* A per-call `raw` option always takes precedence over this default.
|
|
275
|
+
*
|
|
276
|
+
* @defaultValue false
|
|
120
277
|
*
|
|
121
278
|
* @example
|
|
122
279
|
* ```ts
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* const
|
|
126
|
-
*
|
|
127
|
-
*
|
|
280
|
+
* // Normalized (default):
|
|
281
|
+
* const client = createBsuirClient();
|
|
282
|
+
* const norm = await client.schedule.getGroup("053503"); // NormalizedScheduleResponse
|
|
283
|
+
*
|
|
284
|
+
* // Raw by default:
|
|
285
|
+
* const rawClient = createBsuirClient({ defaultRaw: true });
|
|
286
|
+
* const raw = await rawClient.schedule.getGroup("053503"); // ScheduleResponse
|
|
287
|
+
*
|
|
288
|
+
* // Per-call override (always wins):
|
|
289
|
+
* const override = await client.schedule.getGroup("053503", { raw: true }); // ScheduleResponse
|
|
128
290
|
* ```
|
|
129
291
|
*/
|
|
130
292
|
defaultRaw?: boolean;
|
|
@@ -210,13 +372,32 @@ export { BuildingNumber }
|
|
|
210
372
|
export { BuildingNumber as BuildingNumber_alias_1 }
|
|
211
373
|
export { BuildingNumber as BuildingNumber_alias_2 }
|
|
212
374
|
|
|
375
|
+
/**
|
|
376
|
+
* Builds absolute endpoint URL from base URL, path and query params.
|
|
377
|
+
*/
|
|
378
|
+
export declare function buildUrl(baseUrl: string, path: string, query?: QueryParams): string;
|
|
379
|
+
|
|
213
380
|
declare interface CacheOptions {
|
|
214
381
|
/**
|
|
215
382
|
* Cache TTL for successful GET responses, in milliseconds.
|
|
383
|
+
*
|
|
384
|
+
* After this duration has elapsed the cached entry is considered stale and
|
|
385
|
+
* the next request will hit the network again.
|
|
386
|
+
*
|
|
387
|
+
* @example
|
|
388
|
+
* ```ts
|
|
389
|
+
* // Cache responses for 5 minutes
|
|
390
|
+
* const client = createBsuirClient({ cache: { ttlMs: 5 * 60 * 1000 } });
|
|
391
|
+
* ```
|
|
216
392
|
*/
|
|
217
393
|
ttlMs: number;
|
|
218
394
|
/**
|
|
219
|
-
* Maximum number of
|
|
395
|
+
* Maximum number of entries kept in the in-memory cache.
|
|
396
|
+
*
|
|
397
|
+
* When the limit is exceeded the least-recently-used (LRU) entries are evicted
|
|
398
|
+
* first. Expired entries are always removed before LRU eviction runs.
|
|
399
|
+
*
|
|
400
|
+
* @defaultValue 200
|
|
220
401
|
*/
|
|
221
402
|
maxEntries?: number;
|
|
222
403
|
}
|
|
@@ -245,15 +426,10 @@ declare function createAnnouncementsModule(config: Readonly<InternalClientConfig
|
|
|
245
426
|
export { createAnnouncementsModule }
|
|
246
427
|
export { createAnnouncementsModule as createAnnouncementsModule_alias_1 }
|
|
247
428
|
|
|
429
|
+
/**
|
|
430
|
+
* Creates API module for `/auditories`.
|
|
431
|
+
*/
|
|
248
432
|
declare function createAuditoriesModule(config: Readonly<InternalClientConfig>): {
|
|
249
|
-
/**
|
|
250
|
-
* Returns the full list of auditories from `/auditories`.
|
|
251
|
-
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
252
|
-
*
|
|
253
|
-
* @throws {BsuirApiError} When the API returns a non-success HTTP status
|
|
254
|
-
* @throws {BsuirNetworkError} On transport failures after retries
|
|
255
|
-
* @throws {BsuirTimeoutError} When the request exceeds `timeoutMs`
|
|
256
|
-
*/
|
|
257
433
|
listAll(options?: ReadOptions): Promise<Auditory[]>;
|
|
258
434
|
};
|
|
259
435
|
export { createAuditoriesModule }
|
|
@@ -288,57 +464,37 @@ declare function createBsuirClient(options?: BsuirClientOptions & {
|
|
|
288
464
|
export { createBsuirClient }
|
|
289
465
|
export { createBsuirClient as createBsuirClient_alias_1 }
|
|
290
466
|
|
|
467
|
+
/**
|
|
468
|
+
* Creates API module for `/departments`.
|
|
469
|
+
*/
|
|
291
470
|
declare function createDepartmentsModule(config: Readonly<InternalClientConfig>): {
|
|
292
|
-
/**
|
|
293
|
-
* Returns the full list of departments from `/departments`.
|
|
294
|
-
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
295
|
-
*
|
|
296
|
-
* @throws {BsuirApiError} When the API returns a non-success HTTP status
|
|
297
|
-
* @throws {BsuirNetworkError} On transport failures after retries
|
|
298
|
-
* @throws {BsuirTimeoutError} When the request exceeds `timeoutMs`
|
|
299
|
-
*/
|
|
300
471
|
listAll(options?: ReadOptions): Promise<Department[]>;
|
|
301
472
|
};
|
|
302
473
|
export { createDepartmentsModule }
|
|
303
474
|
export { createDepartmentsModule as createDepartmentsModule_alias_1 }
|
|
304
475
|
|
|
476
|
+
/**
|
|
477
|
+
* Creates API module for `/employees/all`.
|
|
478
|
+
*/
|
|
305
479
|
declare function createEmployeesModule(config: Readonly<InternalClientConfig>): {
|
|
306
|
-
/**
|
|
307
|
-
* Returns the full list of employees from `/employees/all`.
|
|
308
|
-
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
309
|
-
*
|
|
310
|
-
* @throws {BsuirApiError} When the API returns a non-success HTTP status
|
|
311
|
-
* @throws {BsuirNetworkError} On transport failures after retries
|
|
312
|
-
* @throws {BsuirTimeoutError} When the request exceeds `timeoutMs`
|
|
313
|
-
*/
|
|
314
480
|
listAll(options?: ReadOptions): Promise<EmployeeCatalogItem[]>;
|
|
315
481
|
};
|
|
316
482
|
export { createEmployeesModule }
|
|
317
483
|
export { createEmployeesModule as createEmployeesModule_alias_1 }
|
|
318
484
|
|
|
485
|
+
/**
|
|
486
|
+
* Creates API module for `/faculties`.
|
|
487
|
+
*/
|
|
319
488
|
declare function createFacultiesModule(config: Readonly<InternalClientConfig>): {
|
|
320
|
-
/**
|
|
321
|
-
* Returns the full list of faculties from `/faculties`.
|
|
322
|
-
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
323
|
-
*
|
|
324
|
-
* @throws {BsuirApiError} When the API returns a non-success HTTP status
|
|
325
|
-
* @throws {BsuirNetworkError} On transport failures after retries
|
|
326
|
-
* @throws {BsuirTimeoutError} When the request exceeds `timeoutMs`
|
|
327
|
-
*/
|
|
328
489
|
listAll(options?: ReadOptions): Promise<Faculty[]>;
|
|
329
490
|
};
|
|
330
491
|
export { createFacultiesModule }
|
|
331
492
|
export { createFacultiesModule as createFacultiesModule_alias_1 }
|
|
332
493
|
|
|
494
|
+
/**
|
|
495
|
+
* Creates API module for `/student-groups`.
|
|
496
|
+
*/
|
|
333
497
|
declare function createGroupsModule(config: Readonly<InternalClientConfig>): {
|
|
334
|
-
/**
|
|
335
|
-
* Returns the full list of student groups from `/student-groups`.
|
|
336
|
-
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
337
|
-
*
|
|
338
|
-
* @throws {BsuirApiError} When the API returns a non-success HTTP status
|
|
339
|
-
* @throws {BsuirNetworkError} On transport failures after retries
|
|
340
|
-
* @throws {BsuirTimeoutError} When the request exceeds `timeoutMs`
|
|
341
|
-
*/
|
|
342
498
|
listAll(options?: ReadOptions): Promise<StudentGroupCatalogItem[]>;
|
|
343
499
|
};
|
|
344
500
|
export { createGroupsModule }
|
|
@@ -346,6 +502,19 @@ export { createGroupsModule as createGroupsModule_alias_1 }
|
|
|
346
502
|
|
|
347
503
|
export declare function createJsonResponse({ status, headers, body }: MockResponseInit): Response;
|
|
348
504
|
|
|
505
|
+
/**
|
|
506
|
+
* Creates a simple catalog-like module exposing `listAll()` for a fixed endpoint.
|
|
507
|
+
*/
|
|
508
|
+
export declare function createListModule<T>(config: Readonly<InternalClientConfig>, endpoint: string): {
|
|
509
|
+
/**
|
|
510
|
+
* Returns all items from the configured endpoint.
|
|
511
|
+
*/
|
|
512
|
+
listAll(options?: ReadOptions): Promise<T[]>;
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Creates schedule API module with raw/normalized response support.
|
|
517
|
+
*/
|
|
349
518
|
declare function createScheduleModule<TRawDefault extends boolean>(config: Readonly<InternalClientConfig<TRawDefault>>): {
|
|
350
519
|
getGroup: <TRaw extends boolean | undefined = undefined>(groupNumber: string, options?: ReadOptions & {
|
|
351
520
|
raw?: TRaw;
|
|
@@ -355,14 +524,25 @@ declare function createScheduleModule<TRawDefault extends boolean>(config: Reado
|
|
|
355
524
|
}) => Promise<ScheduleResponseByRawOption<TRaw, TRawDefault>>;
|
|
356
525
|
getGroupFiltered: (groupNumber: string, filter: ScheduleFilterOptions, options?: ReadOptions) => Promise<FlattenedScheduleItem[]>;
|
|
357
526
|
getEmployeeFiltered: (urlId: string, filter: ScheduleFilterOptions, options?: ReadOptions) => Promise<FlattenedScheduleItem[]>;
|
|
527
|
+
/**
|
|
528
|
+
* Returns exams for a group.
|
|
529
|
+
*/
|
|
358
530
|
getGroupExams(groupNumber: string, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
531
|
+
/**
|
|
532
|
+
* Returns exams for an employee.
|
|
533
|
+
*/
|
|
359
534
|
getEmployeeExams(urlId: string, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
535
|
+
/**
|
|
536
|
+
* Returns regular schedule lessons of a specific subgroup for a group.
|
|
537
|
+
*/
|
|
360
538
|
getGroupBySubgroup(groupNumber: string, subgroup: number, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
539
|
+
/**
|
|
540
|
+
* Returns regular schedule lessons of a specific subgroup for an employee.
|
|
541
|
+
*/
|
|
361
542
|
getEmployeeBySubgroup(urlId: string, subgroup: number, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
362
543
|
getCurrentWeek: (options?: ReadOptions) => Promise<number>;
|
|
363
544
|
/**
|
|
364
|
-
* Calls IIS `/last-update-date/student-group`.
|
|
365
|
-
* it may return an error for newer group numbers (e.g. six-digit `524404`).
|
|
545
|
+
* Calls IIS `/last-update-date/student-group`.
|
|
366
546
|
*/
|
|
367
547
|
getLastUpdateByGroup(params: {
|
|
368
548
|
groupNumber: string;
|
|
@@ -370,8 +550,7 @@ declare function createScheduleModule<TRawDefault extends boolean>(config: Reado
|
|
|
370
550
|
id: number;
|
|
371
551
|
}, options?: ReadOptions): Promise<ApiDateResponse>;
|
|
372
552
|
/**
|
|
373
|
-
* Calls IIS `/last-update-date/employee`.
|
|
374
|
-
* not relying on it for critical cache logic.
|
|
553
|
+
* Calls IIS `/last-update-date/employee`.
|
|
375
554
|
*/
|
|
376
555
|
getLastUpdateByEmployee(params: {
|
|
377
556
|
urlId: string;
|
|
@@ -381,16 +560,12 @@ declare function createScheduleModule<TRawDefault extends boolean>(config: Reado
|
|
|
381
560
|
};
|
|
382
561
|
export { createScheduleModule }
|
|
383
562
|
export { createScheduleModule as createScheduleModule_alias_1 }
|
|
563
|
+
export { createScheduleModule as createScheduleModule_alias_2 }
|
|
384
564
|
|
|
565
|
+
/**
|
|
566
|
+
* Creates API module for `/specialities`.
|
|
567
|
+
*/
|
|
385
568
|
declare function createSpecialitiesModule(config: Readonly<InternalClientConfig>): {
|
|
386
|
-
/**
|
|
387
|
-
* Returns the full list of specialities from `/specialities`.
|
|
388
|
-
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
389
|
-
*
|
|
390
|
-
* @throws {BsuirApiError} When the API returns a non-success HTTP status
|
|
391
|
-
* @throws {BsuirNetworkError} On transport failures after retries
|
|
392
|
-
* @throws {BsuirTimeoutError} When the request exceeds `timeoutMs`
|
|
393
|
-
*/
|
|
394
569
|
listAll(options?: ReadOptions): Promise<Speciality[]>;
|
|
395
570
|
};
|
|
396
571
|
export { createSpecialitiesModule }
|
|
@@ -469,24 +644,12 @@ export { Faculty as Faculty_alias_1 }
|
|
|
469
644
|
export { Faculty as Faculty_alias_2 }
|
|
470
645
|
|
|
471
646
|
/**
|
|
472
|
-
* Filters normalized schedule lessons by
|
|
473
|
-
*
|
|
474
|
-
* @param response - Normalized schedule response containing lessons
|
|
475
|
-
* @param filter - Filter options with optional fields: source, weekday, weekNumber, subgroup,
|
|
476
|
-
* lessonTypeAbbrev, subjectQuery, employeeUrlId, auditory
|
|
477
|
-
* @returns Array of lessons matching all provided filter criteria
|
|
478
|
-
*
|
|
479
|
-
* @example
|
|
480
|
-
* ```ts
|
|
481
|
-
* const schedule = await client.schedule.getGroup("053503");
|
|
482
|
-
* const mondayLessons = filterLessons(schedule, { weekday: "Понедельник" });
|
|
483
|
-
* const practiceLessons = filterLessons(schedule, { lessonTypeAbbrev: "пр" });
|
|
484
|
-
* const lectureLessons = filterLessons(schedule, { lessonTypeAbbrev: ["лк", "лекция"] });
|
|
485
|
-
* ```
|
|
647
|
+
* Filters normalized schedule lessons by criteria.
|
|
486
648
|
*/
|
|
487
649
|
declare function filterLessons(response: NormalizedScheduleResponse, filter: ScheduleFilterOptions): FlattenedScheduleItem[];
|
|
488
650
|
export { filterLessons }
|
|
489
651
|
export { filterLessons as filterLessons_alias_1 }
|
|
652
|
+
export { filterLessons as filterLessons_alias_2 }
|
|
490
653
|
|
|
491
654
|
declare type FlattenedLessonsByDay = Record<Weekday, FlattenedScheduleItem[]>;
|
|
492
655
|
export { FlattenedLessonsByDay }
|
|
@@ -501,6 +664,11 @@ export { FlattenedScheduleItem }
|
|
|
501
664
|
export { FlattenedScheduleItem as FlattenedScheduleItem_alias_1 }
|
|
502
665
|
export { FlattenedScheduleItem as FlattenedScheduleItem_alias_2 }
|
|
503
666
|
|
|
667
|
+
/**
|
|
668
|
+
* Calculates retry delay using `Retry-After` when present, otherwise exponential backoff.
|
|
669
|
+
*/
|
|
670
|
+
export declare function getRetryDelayMs(config: Readonly<InternalClientConfig>, attempt: number, retryAfterHeader?: string | null): number;
|
|
671
|
+
|
|
504
672
|
export declare interface InternalClientConfig<TRawDefault extends boolean = boolean> {
|
|
505
673
|
baseUrl: string;
|
|
506
674
|
fetchImpl: typeof globalThis.fetch;
|
|
@@ -514,6 +682,7 @@ export declare interface InternalClientConfig<TRawDefault extends boolean = bool
|
|
|
514
682
|
cacheTtlMs: number | undefined;
|
|
515
683
|
cacheMaxEntries: number;
|
|
516
684
|
dedupeInFlight: boolean;
|
|
685
|
+
maxResponseBytes: number;
|
|
517
686
|
validateResponses: boolean;
|
|
518
687
|
hooks: ClientHooks;
|
|
519
688
|
responseCache: Map<string, {
|
|
@@ -581,29 +750,18 @@ export { NormalizedScheduleResponse as NormalizedScheduleResponse_alias_1 }
|
|
|
581
750
|
export { NormalizedScheduleResponse as NormalizedScheduleResponse_alias_2 }
|
|
582
751
|
|
|
583
752
|
/**
|
|
584
|
-
* Transforms raw
|
|
585
|
-
*
|
|
586
|
-
* Raw API response contains lessons grouped by weekday (`schedules` object with day keys)
|
|
587
|
-
* and exams in a separate array. This function flattens them into a single `lessons` array
|
|
588
|
-
* for easier filtering and iteration, while preserving day-grouped view in `lessonsByDay`.
|
|
589
|
-
*
|
|
590
|
-
* @param response - Raw schedule response from API
|
|
591
|
-
* @returns Normalized schedule with additional computed fields: `lessons` (flattened array),
|
|
592
|
-
* `lessonsByDay` (grouped by weekday), `scheduleLessons`, and `examLessons`
|
|
593
|
-
*
|
|
594
|
-
* @example
|
|
595
|
-
* ```ts
|
|
596
|
-
* const rawSchedule = await client.schedule.getGroup("053503", { raw: true });
|
|
597
|
-
* const normalized = normalizeSchedule(rawSchedule);
|
|
598
|
-
* console.log(normalized.lessons.length); // All lessons + exams flattened
|
|
599
|
-
* console.log(normalized.lessonsByDay["Понедельник"]); // Monday-only lessons
|
|
600
|
-
* console.log(normalized.scheduleLessons.length); // Only regular schedule
|
|
601
|
-
* console.log(normalized.examLessons.length); // Only exams
|
|
602
|
-
* ```
|
|
753
|
+
* Transforms raw schedule response into normalized structure with flattened lessons.
|
|
603
754
|
*/
|
|
604
755
|
declare function normalizeSchedule(response: ScheduleResponse): NormalizedScheduleResponse;
|
|
605
756
|
export { normalizeSchedule }
|
|
606
757
|
export { normalizeSchedule as normalizeSchedule_alias_1 }
|
|
758
|
+
export { normalizeSchedule as normalizeSchedule_alias_2 }
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Parses response body as JSON when possible, otherwise returns text.
|
|
762
|
+
* Throws `BsuirApiError` for declared JSON payloads that are empty/invalid.
|
|
763
|
+
*/
|
|
764
|
+
export declare function parseBody(response: Response, maxResponseBytes: number): Promise<unknown>;
|
|
607
765
|
|
|
608
766
|
/**
|
|
609
767
|
* Normalizes current week payload from API to a positive integer.
|
|
@@ -644,7 +802,12 @@ declare interface RequestHookContext {
|
|
|
644
802
|
export { RequestHookContext }
|
|
645
803
|
export { RequestHookContext as RequestHookContext_alias_1 }
|
|
646
804
|
|
|
647
|
-
|
|
805
|
+
/**
|
|
806
|
+
* Executes JSON HTTP request with timeout, retry/backoff, deduplication and cache support.
|
|
807
|
+
*/
|
|
808
|
+
declare function requestJson<T>(config: Readonly<InternalClientConfig>, path: string, options?: RequestOptions): Promise<T>;
|
|
809
|
+
export { requestJson }
|
|
810
|
+
export { requestJson as requestJson_alias_1 }
|
|
648
811
|
|
|
649
812
|
export declare type RequestMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
650
813
|
|
|
@@ -684,6 +847,9 @@ declare interface ResponseHookContext extends RequestHookContext {
|
|
|
684
847
|
export { ResponseHookContext }
|
|
685
848
|
export { ResponseHookContext as ResponseHookContext_alias_1 }
|
|
686
849
|
|
|
850
|
+
/** HTTP status codes retriable by the request pipeline. */
|
|
851
|
+
export declare const RETRIABLE_STATUS_CODES: Set<number>;
|
|
852
|
+
|
|
687
853
|
declare interface RetryHookContext extends RequestHookContext {
|
|
688
854
|
delayMs: number;
|
|
689
855
|
reason: "http_status" | "network_error";
|
|
@@ -744,6 +910,14 @@ export { ScheduleResponse as ScheduleResponse_alias_2 }
|
|
|
744
910
|
|
|
745
911
|
declare type ScheduleResponseByRawOption<TRaw extends boolean | undefined, TRawDefault extends boolean> = TRaw extends true ? ScheduleResponse : TRaw extends false ? NormalizedScheduleResponse : TRawDefault extends true ? ScheduleResponse : NormalizedScheduleResponse;
|
|
746
912
|
|
|
913
|
+
/**
|
|
914
|
+
* Writes response value to cache and performs eviction when size approaches capacity.
|
|
915
|
+
*/
|
|
916
|
+
export declare function setCache(config: Readonly<InternalClientConfig>, key: string, value: unknown): void;
|
|
917
|
+
|
|
918
|
+
/** Delays execution for a specified number of milliseconds. */
|
|
919
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
920
|
+
|
|
747
921
|
declare interface Speciality {
|
|
748
922
|
id: number;
|
|
749
923
|
name: string;
|
|
@@ -781,6 +955,11 @@ export { StudentGroupShort }
|
|
|
781
955
|
export { StudentGroupShort as StudentGroupShort_alias_1 }
|
|
782
956
|
export { StudentGroupShort as StudentGroupShort_alias_2 }
|
|
783
957
|
|
|
958
|
+
/**
|
|
959
|
+
* Reads a cached response value by key, applying TTL validation and LRU touch update.
|
|
960
|
+
*/
|
|
961
|
+
export declare function tryReadCache(config: Readonly<InternalClientConfig>, key: string): unknown;
|
|
962
|
+
|
|
784
963
|
declare type Weekday = "Понедельник" | "Вторник" | "Среда" | "Четверг" | "Пятница" | "Суббота";
|
|
785
964
|
export { Weekday }
|
|
786
965
|
export { Weekday as Weekday_alias_1 }
|