bsuir-iis-api 0.10.1 → 0.11.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 CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.11.0] - 2026-05-24
4
+
5
+ ### Added
6
+
7
+ - `schedule.getGroupBySubgroup()` and `schedule.getEmployeeBySubgroup()` accept `rawEnvelope: true` for envelope-preserving raw subgroup output.
8
+ - `announcements.byEmployee()` / `byDepartment()` accept `treat404AsEmpty` (default `true`) to opt out of mapping IIS `404`/`400` empty-announcement responses to `[]`.
9
+ - Optional `onInvalidTime` hook for `sortLessonsByTime()`, `getCurrentLesson()`, `getNextLesson()`, and `buildScheduleDays()`.
10
+
11
+ ### Changed
12
+
13
+ - `schedule.getGroup()` / `getEmployee()` now always return normalized payloads; use `getGroupRaw()`, `getEmployeeRaw()`, `getGroupEnvelope()`, or `getEmployeeEnvelope()` for raw API envelopes.
14
+ - Response cache stores deep-frozen JSON values, returns the cached frozen reference on hits, and rejects non-JSON cache writes with `BsuirConfigurationError`.
15
+ - `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.
16
+ - 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.
17
+ - Request bodies pass through native `BodyInit` shapes (`FormData`, `URLSearchParams`, `Blob`, `ArrayBuffer`, `ReadableStream`) instead of being JSON-stringified.
18
+ - `Retry-After` numeric values now use the same internal cap as date-based values.
19
+ - `allowInsecureHttp: true` rejects non-loopback hosts in `allowedBaseUrlHosts`.
20
+ - `normalizeSchedule` clones lessons once, always performs a minimal envelope check, and delegates full validation to `assertScheduleResponse`.
21
+ - `mergeSignalsManual` cleanup is idempotent and records listeners before registration to avoid leaks.
22
+
23
+ ### Documentation
24
+
25
+ - README now documents explicit raw schedule helpers, `validateResponses` as opt-in, `BsuirResponsePayloadTooLargeError` for oversized payloads, and the Changesets release flow.
26
+
27
+ ### Potentially Breaking
28
+
29
+ - Removed `defaultRaw` and per-call `raw` selection from `schedule.getGroup()` / `getEmployee()`; callers should use explicit raw helpers instead.
30
+ - Cached responses are frozen shared references; callers that need mutation should clone returned values first.
31
+ - Native `BodyInit` request bodies are no longer JSON-stringified.
32
+ - `allowInsecureHttp: true` is limited to loopback hosts.
33
+
3
34
  ## [0.10.1] - 2026-05-13
4
35
 
5
36
  ### 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 (`defaultRaw: false`). That shape includes `lessons`, `lessonsByDay`, `scheduleLessons`, and `examLessons` (see types). With `{ raw: true }` you get the API’s raw `ScheduleResponse` instead—no `lessons` field; use `schedules` / `exams` and match examples to the option you use.
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 (when no per-request signal is passed).
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 (enabled by default).
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
- - `BsuirApiError` is also used when response body size exceeds configured `maxResponseBytes`.
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 `BsuirApiError`.
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.getGroup("053503", { raw: true });
154
+ const raw = await client.schedule.getGroupRaw("053503");
156
155
  ```
157
156
 
158
- Use `defaultRaw: true` in `createBsuirClient` to change global behavior.
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. Update version and `CHANGELOG.md` in the same release commit.
222
- 3. Push to `main` to trigger GitHub Actions release workflow.
223
- 4. Verify published package in a clean project:
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 keeps `CHANGELOG.md` manually curated for stable release notes.
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