bsuir-iis-api 0.10.1 → 0.12.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 +54 -0
- package/README.md +29 -18
- package/dist/_tsup-dts-rollup.d.ts +659 -186
- package/dist/index.d.ts +40 -12
- package/dist/index.js +1011 -211
- package/dist/index.js.map +1 -1
- package/package.json +11 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b77c694: Code review follow-ups across HTTP client, cache, schedule modules, and helpers.
|
|
8
|
+
- normalizeSchedule clones each lesson once instead of re-cloning during flattening.
|
|
9
|
+
- Response cache stores deep-frozen JSON values; reads return the frozen reference instead of cloning on every hit. setCache now rejects non-JSON values with `BsuirConfigurationError`.
|
|
10
|
+
- `requestJson` no longer disables response caching when a non-aborted `AbortSignal` is passed; only an already-aborted signal skips cache. In-flight deduplication remains disabled for per-call signals to avoid cross-caller cancellation semantics.
|
|
11
|
+
- README now documents `validateResponses` as opt-in and oversized payloads as `BsuirResponsePayloadTooLargeError`.
|
|
12
|
+
- Query keys are sorted deterministically in `buildUrl` for stable cache keys.
|
|
13
|
+
- Relaxed query key validation: any non-control, non-whitespace, non-URL-structural character is allowed.
|
|
14
|
+
- Private-header detection switched from substring sniffing to an explicit denylist.
|
|
15
|
+
- Request body now passes through `BodyInit` shapes (`FormData`/`URLSearchParams`/`Blob`/`ArrayBuffer`/`ReadableStream`) instead of being JSON-stringified.
|
|
16
|
+
- `Retry-After` numeric branch now applies the same internal cap as the date branch.
|
|
17
|
+
- `allowInsecureHttp: true` rejects any non-loopback host in `allowedBaseUrlHosts`.
|
|
18
|
+
- `mergeSignalsManual` cleanup is idempotent and listeners are recorded before registration to avoid leaks.
|
|
19
|
+
- `normalizeSchedule` always performs a minimal envelope check; full validation delegates to the single `assertScheduleResponse` source of truth.
|
|
20
|
+
- `schedule.getGroupBySubgroup` and `schedule.getEmployeeBySubgroup` accept `rawEnvelope: true` for envelope-preserving raw output (existing `raw` and default behaviors unchanged).
|
|
21
|
+
- `schedule.getGroup` / `getEmployee` now always return normalized payloads; explicit raw helpers (`getGroupRaw`, `getEmployeeRaw`, `getGroupEnvelope`, `getEmployeeEnvelope`) provide raw API envelopes.
|
|
22
|
+
- Removed `defaultRaw` and per-call `raw` selection from `getGroup` / `getEmployee` to make response shapes explicit.
|
|
23
|
+
- `announcements.byEmployee` / `byDepartment` accept `treat404AsEmpty` (default `true`) instead of relying on a body-marker heuristic to detect "no announcements" 404 responses.
|
|
24
|
+
- Added optional `onInvalidTime` hook to `sortLessonsByTime` / `getCurrentLesson` / `getNextLesson` / `buildScheduleDays` for surfacing malformed `HH:MM` lesson times.
|
|
25
|
+
|
|
26
|
+
## [0.11.0] - 2026-05-24
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- `schedule.getGroupBySubgroup()` and `schedule.getEmployeeBySubgroup()` accept `rawEnvelope: true` for envelope-preserving raw subgroup output.
|
|
31
|
+
- `announcements.byEmployee()` / `byDepartment()` accept `treat404AsEmpty` (default `true`) to opt out of mapping IIS `404`/`400` empty-announcement responses to `[]`.
|
|
32
|
+
- Optional `onInvalidTime` hook for `sortLessonsByTime()`, `getCurrentLesson()`, `getNextLesson()`, and `buildScheduleDays()`.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- `schedule.getGroup()` / `getEmployee()` now always return normalized payloads; use `getGroupRaw()`, `getEmployeeRaw()`, `getGroupEnvelope()`, or `getEmployeeEnvelope()` for raw API envelopes.
|
|
37
|
+
- Response cache stores deep-frozen JSON values, returns the cached frozen reference on hits, and rejects non-JSON cache writes with `BsuirConfigurationError`.
|
|
38
|
+
- `requestJson` keeps response caching enabled for non-aborted `AbortSignal`s; in-flight deduplication remains disabled for per-call signals to avoid cross-caller cancellation semantics.
|
|
39
|
+
- Query keys are sorted deterministically for stable cache keys, query key validation is relaxed for safe non-structural characters, and private-header detection now uses an explicit denylist.
|
|
40
|
+
- Request bodies pass through native `BodyInit` shapes (`FormData`, `URLSearchParams`, `Blob`, `ArrayBuffer`, `ReadableStream`) instead of being JSON-stringified.
|
|
41
|
+
- `Retry-After` numeric values now use the same internal cap as date-based values.
|
|
42
|
+
- `allowInsecureHttp: true` rejects non-loopback hosts in `allowedBaseUrlHosts`.
|
|
43
|
+
- `normalizeSchedule` clones lessons once, always performs a minimal envelope check, and delegates full validation to `assertScheduleResponse`.
|
|
44
|
+
- `mergeSignalsManual` cleanup is idempotent and records listeners before registration to avoid leaks.
|
|
45
|
+
|
|
46
|
+
### Documentation
|
|
47
|
+
|
|
48
|
+
- README now documents explicit raw schedule helpers, `validateResponses` as opt-in, `BsuirResponsePayloadTooLargeError` for oversized payloads, and the Changesets release flow.
|
|
49
|
+
|
|
50
|
+
### Potentially Breaking
|
|
51
|
+
|
|
52
|
+
- Removed `defaultRaw` and per-call `raw` selection from `schedule.getGroup()` / `getEmployee()`; callers should use explicit raw helpers instead.
|
|
53
|
+
- Cached responses are frozen shared references; callers that need mutation should clone returned values first.
|
|
54
|
+
- Native `BodyInit` request bodies are no longer JSON-stringified.
|
|
55
|
+
- `allowInsecureHttp: true` is limited to loopback hosts.
|
|
56
|
+
|
|
3
57
|
## [0.10.1] - 2026-05-13
|
|
4
58
|
|
|
5
59
|
### Documentation
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npm install bsuir-iis-api
|
|
|
16
16
|
|
|
17
17
|
## Quick start
|
|
18
18
|
|
|
19
|
-
Default schedule calls return a **normalized** payload
|
|
19
|
+
Default schedule calls return a **normalized** payload. That shape includes `lessons`, `lessonsByDay`, `scheduleLessons`, and `examLessons` (see types). Use explicit raw helpers such as `client.schedule.getGroupRaw()` / `getEmployeeRaw()` to obtain the API’s raw `ScheduleResponse` (which has `schedules` / `exams` and may omit `lessons`).
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
22
|
import { createBsuirClient } from "bsuir-iis-api";
|
|
@@ -50,8 +50,7 @@ const client = createBsuirClient({
|
|
|
50
50
|
onRetry: ({ endpoint, delayMs, reason }) => {
|
|
51
51
|
console.log("retry", endpoint, delayMs, reason);
|
|
52
52
|
}
|
|
53
|
-
}
|
|
54
|
-
defaultRaw: false
|
|
53
|
+
}
|
|
55
54
|
});
|
|
56
55
|
```
|
|
57
56
|
|
|
@@ -60,10 +59,10 @@ const client = createBsuirClient({
|
|
|
60
59
|
- `allowedBaseUrlHosts` controls which hosts are allowed for `baseUrl` (defaults to `["iis.bsuir.by"]`).
|
|
61
60
|
- `allowInsecureHttp` enables `http://` only for trusted local/test endpoints.
|
|
62
61
|
- `signal` in `createBsuirClient({ signal })` acts as a global cancellation signal for all requests made by that client.
|
|
63
|
-
- `cache` stores successful GET responses in-memory for the configured TTL.
|
|
64
|
-
- `dedupeInFlight` reuses the same in-flight GET request for concurrent callers
|
|
62
|
+
- `cache` stores successful GET responses in-memory for the configured TTL. A live `AbortSignal` can still use cache; an already-aborted signal skips cache.
|
|
63
|
+
- `dedupeInFlight` reuses the same in-flight GET request for concurrent callers. It is disabled for per-request signals, non-default cache modes, private credential headers, and already-aborted signals.
|
|
65
64
|
- `maxResponseBytes` limits body size per response to protect against memory spikes.
|
|
66
|
-
- `validateResponses` enables runtime payload-shape checks for key endpoints
|
|
65
|
+
- `validateResponses` enables opt-in runtime payload-shape checks for key endpoints.
|
|
67
66
|
- `hooks` provides lifecycle callbacks (`onRequest`, `onRetry`, `onResponse`, `onError`) for observability.
|
|
68
67
|
- `AbortSignal` is supported by all read methods.
|
|
69
68
|
|
|
@@ -105,8 +104,8 @@ When IIS responds with HTTP `404` or `400` (no list, missing resource, or endpoi
|
|
|
105
104
|
|
|
106
105
|
- Core runtime API: `createBsuirClient`, `BsuirClient`
|
|
107
106
|
- Client/runtime option types: `BsuirClientOptions`, `CacheOptions`, `ClientHooks`, `RequestOptions`, `ReadOptions`, `RequestHookContext`, `RetryHookContext`, `ResponseHookContext`, `ErrorHookContext`
|
|
108
|
-
- Schedule utilities: `normalizeSchedule`, `filterLessons`, `ScheduleFilterOptions`
|
|
109
|
-
- Error classes: `BsuirApiError`, `BsuirNetworkError`, `BsuirTimeoutError`, `BsuirValidationError`, `BsuirResponseValidationError`, `BsuirConfigurationError`
|
|
107
|
+
- Schedule utilities: `normalizeSchedule`, `filterLessons`, `getLessonsForDate`, `getTodayLessons`, `getTomorrowLessons`, `getLessonsForWeek`, `sortLessonsByTime`, `groupLessonsByDay`, `getCurrentLesson`, `getNextLesson`, `buildScheduleDays`, `ScheduleFilterOptions`
|
|
108
|
+
- Error classes: `BsuirApiError`, `BsuirNetworkError`, `BsuirTimeoutError`, `BsuirValidationError`, `BsuirResponseValidationError`, `BsuirResponsePayloadTooLargeError`, `BsuirConfigurationError`
|
|
110
109
|
- Domain types: `Announcement`, `ApiDateResponse`, `Auditory`, `AuditoryDepartment`, `AuditoryType`, `BuildingNumber`, `Department`, `EducationForm`, `Employee`, `EmployeeCatalogItem`, `Faculty`, `FlattenedLessonsByDay`, `FlattenedScheduleItem`, `LessonStudentGroup`, `Maybe`, `NormalizedScheduleResponse`, `ScheduleItem`, `ScheduleResponse`, `Speciality`, `StudentGroupCatalogItem`, `StudentGroupShort`, `Weekday`, `WeekScheduleMap`
|
|
111
110
|
|
|
112
111
|
## Errors
|
|
@@ -114,7 +113,7 @@ When IIS responds with HTTP `404` or `400` (no list, missing resource, or endpoi
|
|
|
114
113
|
SDK throws typed errors:
|
|
115
114
|
|
|
116
115
|
- `BsuirApiError` for HTTP errors (contains `status`, `endpoint`, `body`). **Exception:** `client.announcements.byEmployee` / `byDepartment` resolve to `[]` on IIS HTTP `404` or `400` instead of throwing (see Announcements above).
|
|
117
|
-
- `
|
|
116
|
+
- `BsuirResponsePayloadTooLargeError` when response body size exceeds configured `maxResponseBytes`.
|
|
118
117
|
- `BsuirNetworkError` for transport errors (contains `endpoint` and standard `cause`)
|
|
119
118
|
- `BsuirResponseValidationError` for invalid payload shapes when `validateResponses: true`
|
|
120
119
|
- `BsuirTimeoutError` for timeouts (contains `endpoint`, `timeoutMs`)
|
|
@@ -126,7 +125,7 @@ Validation rules:
|
|
|
126
125
|
- `groupNumber` must contain digits only
|
|
127
126
|
- `urlId` must be a slug with letters/digits/hyphens (for example `s-nesterenkov`)
|
|
128
127
|
- `id` and `subgroup` parameters must be positive integers
|
|
129
|
-
Retry and abort behavior:
|
|
128
|
+
Retry and abort behavior:
|
|
130
129
|
|
|
131
130
|
- Retries are applied to GET requests for transport/network errors and HTTP `429`, `500`, `502`, `503`, `504`
|
|
132
131
|
- `Retry-After` is respected for retriable responses
|
|
@@ -142,7 +141,7 @@ For **2xx** responses the client reads the body as text, then applies `JSON.pars
|
|
|
142
141
|
- Valid JSON is returned even when `Content-Type` does **not** include `application/json` (mislabeled responses still parse).
|
|
143
142
|
- If `Content-Type` indicates **`application/json`** but the body is empty or not valid JSON, the client throws `BsuirApiError` (`Invalid JSON response payload`), same as for a truncated `{` payload.
|
|
144
143
|
- If the body is **empty** and the content type does **not** indicate JSON, the result is an empty string `""` (analogous to reading plain text). Typical IIS catalog JSON endpoints return a non-empty body.
|
|
145
|
-
- If response body size exceeds `maxResponseBytes`, the client throws `
|
|
144
|
+
- If response body size exceeds `maxResponseBytes`, the client throws `BsuirResponsePayloadTooLargeError`.
|
|
146
145
|
|
|
147
146
|
## Raw vs normalized schedule response
|
|
148
147
|
|
|
@@ -152,11 +151,10 @@ By default, schedule methods return a **normalized** `NormalizedScheduleResponse
|
|
|
152
151
|
import { createBsuirClient } from "bsuir-iis-api";
|
|
153
152
|
|
|
154
153
|
const client = createBsuirClient();
|
|
155
|
-
const raw = await client.schedule.
|
|
154
|
+
const raw = await client.schedule.getGroupRaw("053503");
|
|
156
155
|
```
|
|
157
156
|
|
|
158
|
-
Use
|
|
159
|
-
When `raw` is omitted, `getGroup()` and `getEmployee()` follow client `defaultRaw` (`false` by default, so normalized unless explicitly changed to `true`).
|
|
157
|
+
Use explicit helpers `getGroupRaw` / `getEmployeeRaw` to obtain raw envelopes. `getGroup()` / `getEmployee()` return normalized payloads by default.
|
|
160
158
|
In raw mode API may return `schedules: null`; normalized mode always converts it to `{}`.
|
|
161
159
|
In raw mode some lesson fields may also be nullable (`weekNumber`, `lessonTypeAbbrev`), so keep null checks if you consume raw payload directly.
|
|
162
160
|
README examples match the installed package version; if types and docs ever diverge, rely on `NormalizedScheduleResponse` / `ScheduleResponse` from the same release.
|
|
@@ -185,6 +183,17 @@ const client = createBsuirClient();
|
|
|
185
183
|
const subgroupLessons = await client.schedule.getEmployeeBySubgroup("s-nesterenkov", 1);
|
|
186
184
|
```
|
|
187
185
|
|
|
186
|
+
## Schedule helpers for UI
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
import { buildScheduleDays, getTodayLessons } from "bsuir-iis-api";
|
|
190
|
+
|
|
191
|
+
const todayLessons = getTodayLessons(schedule, new Date());
|
|
192
|
+
const days = buildScheduleDays(schedule, { days: 7, includeEmptyDays: false });
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Use `getCurrentLesson(days[0].lessons)` / `getNextLesson(days[0].lessons)` for in-day progress indicators.
|
|
196
|
+
|
|
188
197
|
## Development
|
|
189
198
|
|
|
190
199
|
```bash
|
|
@@ -218,9 +227,11 @@ CI has a manual `workflow_dispatch` path that also runs live contracts (`live-co
|
|
|
218
227
|
## Release checklist
|
|
219
228
|
|
|
220
229
|
1. Run `npm run check:full`.
|
|
221
|
-
2.
|
|
222
|
-
3.
|
|
223
|
-
4.
|
|
230
|
+
2. Add or update a `.changeset/*.md` entry for user-visible changes.
|
|
231
|
+
3. Run `npx changeset version` to bump `package.json`, update `CHANGELOG.md`, and consume changesets.
|
|
232
|
+
4. Run `npm run api:report:check` and `npm run release:dry`.
|
|
233
|
+
5. Push to `main` to trigger GitHub Actions release workflow.
|
|
234
|
+
6. Verify published package in a clean project:
|
|
224
235
|
|
|
225
236
|
```bash
|
|
226
237
|
mkdir bsuir-iis-smoke && cd bsuir-iis-smoke
|
|
@@ -229,7 +240,7 @@ npm install bsuir-iis-api@latest
|
|
|
229
240
|
node -e "import('bsuir-iis-api').then(m=>console.log(typeof m.createBsuirClient))"
|
|
230
241
|
```
|
|
231
242
|
|
|
232
|
-
The project
|
|
243
|
+
The project uses Changesets for version bumps and changelog generation; edit pending changeset text before versioning when release notes need refinement.
|
|
233
244
|
|
|
234
245
|
## License
|
|
235
246
|
|