bsuir-iis-api 0.7.0 → 0.9.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 +39 -1
- package/README.md +16 -1
- package/dist/_tsup-dts-rollup.d.ts +279 -76
- package/dist/index.d.ts +10 -1
- package/dist/index.js +528 -134
- package/dist/index.js.map +1 -1
- package/package.json +15 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,50 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 323feb4: New public APIs, cache, hooks, deps versions update, new JSdoc, etc.
|
|
8
|
+
|
|
3
9
|
All notable changes to this project are documented in this file.
|
|
4
10
|
|
|
5
11
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
12
|
and the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
13
|
This changelog is maintained manually and updated in release commits.
|
|
8
14
|
|
|
9
|
-
## [
|
|
15
|
+
## [0.8.0] - 2026-05-10
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Public exports for schedule utilities: `normalizeSchedule` and `filterLessons`.
|
|
20
|
+
- Public re-export of `ScheduleFilterOptions` type from `src/index.ts`.
|
|
21
|
+
- Global cancellation support via `createBsuirClient({ signal })`.
|
|
22
|
+
- `src/modules/index.ts` barrel for module factory imports.
|
|
23
|
+
- In-memory GET cache via `createBsuirClient({ cache: { ttlMs, maxEntries } })`.
|
|
24
|
+
- In-flight GET request deduplication via `dedupeInFlight`.
|
|
25
|
+
- Opt-in runtime response-shape validation via `validateResponses` and `BsuirResponseValidationError`.
|
|
26
|
+
- Request lifecycle hooks via `createBsuirClient({ hooks })`: `onRequest`, `onRetry`, `onResponse`, `onError`.
|
|
27
|
+
- API Extractor configuration (`api-extractor.json`) and npm scripts for local/update and CI checks.
|
|
28
|
+
- `POST` method support in `requestJson` via `options.method` and `options.body`.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- `schedule.getGroup/getEmployee` return typing now follows client-level `defaultRaw` when `raw` is omitted.
|
|
33
|
+
- `normalizeSchedule` no longer duplicates day-item flattening work and avoids repeated `auditories` normalization per lesson.
|
|
34
|
+
- Strict date parsing in `parseDdMmYyyy` now rejects non-existent calendar dates (for example `31.02.2026`).
|
|
35
|
+
- `BsuirNetworkError` now relies on standard `Error.cause` instead of duplicate `causeError` field.
|
|
36
|
+
- Client option validation now rejects invalid timeout/retry configuration values early.
|
|
37
|
+
- `week.ts`: passing an empty string now throws a clear `BsuirValidationError` ("is an empty string") instead of a misleading "must be a positive integer" message.
|
|
38
|
+
- `filterLessons`: `weekNumber: 0` is now rejected with `assertPositiveInt` instead of silently passing.
|
|
39
|
+
- `http.ts`: cache eviction now uses pseudo-LRU (oldest-inserted Map key, O(1)) instead of an O(n) scan; `inFlightPromise` is typed as `Promise<T>` to eliminate unsafe `as Promise<unknown>` cast.
|
|
40
|
+
- `http.ts`: restored file integrity after shell heredoc substitution corrupted ES module imports; fixed `@typescript-eslint/no-unsafe-call` error on `inFlight` read by shifting the `as T` cast to the Promise type before `await`.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- JSDoc for `defaultRaw` client option now clarifies that a per-call `raw` option takes priority and includes an `@example` for both cases.
|
|
45
|
+
- Dev tooling: bumped TypeScript to 6.0.3, ESLint to ^10.2.1, Vitest and `@vitest/coverage-v8` to ^4.1.4, `@types/node` to ^25.6.0, `@typescript-eslint/*` and `typescript-eslint` to ^8.58.2, `@changesets/cli` to ^2.31.0, `@microsoft/api-extractor` to ^7.58.5, Prettier to ^3.8.3, `globals` to ^17.5.0; regenerated `package-lock.json`.
|
|
46
|
+
- CI now validates API report compatibility via `npm run api:report:check` (Node 24 job in matrix).
|
|
47
|
+
- `vitest.config.ts`: added coverage thresholds (`lines: 80`, `functions: 80`) to enforce minimum test coverage on CI.
|
|
10
48
|
|
|
11
49
|
## [0.7.0] - 2026-04-19
|
|
12
50
|
|
package/README.md
CHANGED
|
@@ -38,11 +38,24 @@ const client = createBsuirClient({
|
|
|
38
38
|
retryDelayMs: 300,
|
|
39
39
|
retryMaxDelayMs: 3000,
|
|
40
40
|
retryJitter: true,
|
|
41
|
+
cache: { ttlMs: 60_000, maxEntries: 200 },
|
|
42
|
+
dedupeInFlight: true,
|
|
43
|
+
validateResponses: false,
|
|
44
|
+
hooks: {
|
|
45
|
+
onRetry: ({ endpoint, delayMs, reason }) => {
|
|
46
|
+
console.log("retry", endpoint, delayMs, reason);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
41
49
|
defaultRaw: false
|
|
42
50
|
});
|
|
43
51
|
```
|
|
44
52
|
|
|
45
53
|
- `fetch` can be passed for custom runtime/testing.
|
|
54
|
+
- `signal` in `createBsuirClient({ signal })` acts as a global cancellation signal for all requests made by that client.
|
|
55
|
+
- `cache` stores successful GET responses in-memory for the configured TTL.
|
|
56
|
+
- `dedupeInFlight` reuses the same in-flight GET request for concurrent callers (when no per-request signal is passed).
|
|
57
|
+
- `validateResponses` enables runtime payload-shape checks for key endpoints.
|
|
58
|
+
- `hooks` provides lifecycle callbacks (`onRequest`, `onRetry`, `onResponse`, `onError`) for observability.
|
|
46
59
|
- `AbortSignal` is supported by all read methods.
|
|
47
60
|
|
|
48
61
|
## API
|
|
@@ -84,7 +97,8 @@ When IIS responds with HTTP `404` or `400` (no list, missing resource, or endpoi
|
|
|
84
97
|
SDK throws typed errors:
|
|
85
98
|
|
|
86
99
|
- `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).
|
|
87
|
-
- `BsuirNetworkError` for transport errors (contains `endpoint
|
|
100
|
+
- `BsuirNetworkError` for transport errors (contains `endpoint` and standard `cause`)
|
|
101
|
+
- `BsuirResponseValidationError` for invalid payload shapes when `validateResponses: true`
|
|
88
102
|
- `BsuirTimeoutError` for timeouts (contains `endpoint`, `timeoutMs`)
|
|
89
103
|
- `BsuirValidationError` for invalid input parameters
|
|
90
104
|
- `BsuirConfigurationError` when the runtime has no `fetch` and none was passed to `createBsuirClient({ fetch })`
|
|
@@ -151,6 +165,7 @@ npm run lint
|
|
|
151
165
|
npm run lint:fix
|
|
152
166
|
npm run check
|
|
153
167
|
npm run build
|
|
168
|
+
npm run api:report
|
|
154
169
|
```
|
|
155
170
|
|
|
156
171
|
`npm run build` uses [tsup](https://tsup.egoist.dev/) with [`experimentalDts`](https://tsup.egoist.dev/) so `.d.ts` output is produced via `@microsoft/api-extractor` rather than the legacy Rollup declaration path (which is awkward with TypeScript 6’s `baseUrl` deprecation). TypeScript’s handbook notes that [`paths` can be used without `baseUrl`](https://www.typescriptlang.org/docs/handbook/modules/reference.html) when you need path mapping.
|
|
@@ -21,6 +21,10 @@ export { ApiDateResponse }
|
|
|
21
21
|
export { ApiDateResponse as ApiDateResponse_alias_1 }
|
|
22
22
|
export { ApiDateResponse as ApiDateResponse_alias_2 }
|
|
23
23
|
|
|
24
|
+
export declare function assertApiDateResponse(payload: unknown, endpoint: string): asserts payload is ApiDateResponse;
|
|
25
|
+
|
|
26
|
+
export declare function assertArrayResponse(payload: unknown, endpoint: string): asserts payload is unknown[];
|
|
27
|
+
|
|
24
28
|
export declare function assertEmployeeUrlId(value: unknown, fieldName?: string): asserts value is string;
|
|
25
29
|
|
|
26
30
|
export declare function assertGroupNumber(value: unknown, fieldName?: string): asserts value is string;
|
|
@@ -29,6 +33,8 @@ export declare function assertNonEmptyString(value: unknown, fieldName: string):
|
|
|
29
33
|
|
|
30
34
|
export declare function assertPositiveInt(value: unknown, fieldName: string): asserts value is number;
|
|
31
35
|
|
|
36
|
+
export declare function assertScheduleResponse(payload: unknown, endpoint: string): asserts payload is ScheduleResponse;
|
|
37
|
+
|
|
32
38
|
declare interface Auditory {
|
|
33
39
|
id: number;
|
|
34
40
|
name: string;
|
|
@@ -71,18 +77,21 @@ export { BsuirApiError }
|
|
|
71
77
|
export { BsuirApiError as BsuirApiError_alias_1 }
|
|
72
78
|
|
|
73
79
|
/**
|
|
74
|
-
* Public client contract returned by
|
|
80
|
+
* Public client contract returned by `createBsuirClient`.
|
|
81
|
+
* Use `BsuirClientShape<true>` or `BsuirClientShape<false>` for typed overloads.
|
|
75
82
|
*/
|
|
76
83
|
declare type BsuirClient = ReturnType<typeof createBsuirClient>;
|
|
77
84
|
export { BsuirClient }
|
|
78
85
|
export { BsuirClient as BsuirClient_alias_1 }
|
|
79
86
|
|
|
80
87
|
/**
|
|
81
|
-
* Options accepted by
|
|
88
|
+
* Options accepted by `createBsuirClient`.
|
|
82
89
|
*/
|
|
83
90
|
declare interface BsuirClientOptions {
|
|
84
91
|
baseUrl?: string;
|
|
85
92
|
fetch?: typeof globalThis.fetch;
|
|
93
|
+
/** Optional global signal to cancel all client requests. */
|
|
94
|
+
signal?: AbortSignal;
|
|
86
95
|
/** Request timeout per attempt, in milliseconds. */
|
|
87
96
|
timeoutMs?: number;
|
|
88
97
|
/** Number of retry attempts for retriable GET failures. */
|
|
@@ -95,12 +104,70 @@ declare interface BsuirClientOptions {
|
|
|
95
104
|
retryJitter?: boolean;
|
|
96
105
|
/** Optional User-Agent header (used mainly in Node.js runtimes). */
|
|
97
106
|
userAgent?: string;
|
|
98
|
-
/**
|
|
107
|
+
/** In-memory cache configuration for successful GET responses. */
|
|
108
|
+
cache?: CacheOptions;
|
|
109
|
+
/** Enables in-flight GET request deduplication by URL. */
|
|
110
|
+
dedupeInFlight?: boolean;
|
|
111
|
+
/** Enables runtime validation of API response shapes. */
|
|
112
|
+
validateResponses?: boolean;
|
|
113
|
+
/** Lifecycle hooks for request/response/retry/error events. */
|
|
114
|
+
hooks?: ClientHooks;
|
|
115
|
+
/**
|
|
116
|
+
* Force raw API payload for schedule endpoints by default.
|
|
117
|
+
* This changes return types for `schedule.getGroup/getEmployee` when `raw` is omitted.
|
|
118
|
+
*
|
|
119
|
+
* Per-call `raw` option always takes precedence over this default.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const client = createBsuirClient({ defaultRaw: true });
|
|
124
|
+
* // Returns ScheduleResponse (raw)
|
|
125
|
+
* const raw = await client.schedule.getGroup("053503");
|
|
126
|
+
* // Returns NormalizedScheduleResponse (per-call override)
|
|
127
|
+
* const normalized = await client.schedule.getGroup("053503", { raw: false });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
99
130
|
defaultRaw?: boolean;
|
|
100
131
|
}
|
|
101
132
|
export { BsuirClientOptions }
|
|
102
133
|
export { BsuirClientOptions as BsuirClientOptions_alias_1 }
|
|
103
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Fully-typed public shape of the BSUIR API client.
|
|
137
|
+
* All module types are inlined so API Extractor never needs to reach into private helpers.
|
|
138
|
+
*
|
|
139
|
+
* `TRawDefault` controls the default return type of
|
|
140
|
+
* `schedule.getGroup` / `schedule.getEmployee` when the per-call `raw` option is omitted:
|
|
141
|
+
* - `false` (default) → returns `NormalizedScheduleResponse`
|
|
142
|
+
* - `true` → returns `ScheduleResponse` (raw API payload)
|
|
143
|
+
*
|
|
144
|
+
* Per-call `raw` always takes precedence over this default.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* // Default (normalized):
|
|
149
|
+
* const client = createBsuirClient();
|
|
150
|
+
* const norm = await client.schedule.getGroup("053503"); // NormalizedScheduleResponse
|
|
151
|
+
*
|
|
152
|
+
* // Raw by default:
|
|
153
|
+
* const rawClient = createBsuirClient({ defaultRaw: true });
|
|
154
|
+
* const raw = await rawClient.schedule.getGroup("053503"); // ScheduleResponse
|
|
155
|
+
*
|
|
156
|
+
* // Per-call override (always wins):
|
|
157
|
+
* const override = await client.schedule.getGroup("053503", { raw: true }); // ScheduleResponse
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export declare interface BsuirClientShape<TRawDefault extends boolean> {
|
|
161
|
+
schedule: ReturnType<typeof createScheduleModule<TRawDefault>>;
|
|
162
|
+
groups: ReturnType<typeof createGroupsModule>;
|
|
163
|
+
employees: ReturnType<typeof createEmployeesModule>;
|
|
164
|
+
faculties: ReturnType<typeof createFacultiesModule>;
|
|
165
|
+
departments: ReturnType<typeof createDepartmentsModule>;
|
|
166
|
+
specialities: ReturnType<typeof createSpecialitiesModule>;
|
|
167
|
+
announcements: ReturnType<typeof createAnnouncementsModule>;
|
|
168
|
+
auditories: ReturnType<typeof createAuditoriesModule>;
|
|
169
|
+
}
|
|
170
|
+
|
|
104
171
|
declare class BsuirConfigurationError extends Error {
|
|
105
172
|
constructor(message: string);
|
|
106
173
|
}
|
|
@@ -109,16 +176,22 @@ export { BsuirConfigurationError as BsuirConfigurationError_alias_1 }
|
|
|
109
176
|
|
|
110
177
|
declare class BsuirNetworkError extends Error {
|
|
111
178
|
readonly endpoint: string;
|
|
112
|
-
|
|
113
|
-
constructor(message: string, endpoint: string, causeError: unknown);
|
|
179
|
+
constructor(message: string, endpoint: string, cause: unknown);
|
|
114
180
|
}
|
|
115
181
|
export { BsuirNetworkError }
|
|
116
182
|
export { BsuirNetworkError as BsuirNetworkError_alias_1 }
|
|
117
183
|
|
|
184
|
+
declare class BsuirResponseValidationError extends Error {
|
|
185
|
+
readonly endpoint: string;
|
|
186
|
+
constructor(message: string, endpoint: string);
|
|
187
|
+
}
|
|
188
|
+
export { BsuirResponseValidationError }
|
|
189
|
+
export { BsuirResponseValidationError as BsuirResponseValidationError_alias_1 }
|
|
190
|
+
|
|
118
191
|
declare class BsuirTimeoutError extends Error {
|
|
119
192
|
readonly endpoint: string;
|
|
120
193
|
readonly timeoutMs: number;
|
|
121
|
-
constructor(message: string, endpoint: string, timeoutMs: number);
|
|
194
|
+
constructor(message: string, endpoint: string, timeoutMs: number, cause?: unknown);
|
|
122
195
|
}
|
|
123
196
|
export { BsuirTimeoutError }
|
|
124
197
|
export { BsuirTimeoutError as BsuirTimeoutError_alias_1 }
|
|
@@ -137,7 +210,29 @@ export { BuildingNumber }
|
|
|
137
210
|
export { BuildingNumber as BuildingNumber_alias_1 }
|
|
138
211
|
export { BuildingNumber as BuildingNumber_alias_2 }
|
|
139
212
|
|
|
140
|
-
|
|
213
|
+
declare interface CacheOptions {
|
|
214
|
+
/**
|
|
215
|
+
* Cache TTL for successful GET responses, in milliseconds.
|
|
216
|
+
*/
|
|
217
|
+
ttlMs: number;
|
|
218
|
+
/**
|
|
219
|
+
* Maximum number of cached entries kept in memory.
|
|
220
|
+
*/
|
|
221
|
+
maxEntries?: number;
|
|
222
|
+
}
|
|
223
|
+
export { CacheOptions }
|
|
224
|
+
export { CacheOptions as CacheOptions_alias_1 }
|
|
225
|
+
|
|
226
|
+
declare interface ClientHooks {
|
|
227
|
+
onRequest?: (context: RequestHookContext) => void;
|
|
228
|
+
onRetry?: (context: RetryHookContext) => void;
|
|
229
|
+
onResponse?: (context: ResponseHookContext) => void;
|
|
230
|
+
onError?: (context: ErrorHookContext) => void;
|
|
231
|
+
}
|
|
232
|
+
export { ClientHooks }
|
|
233
|
+
export { ClientHooks as ClientHooks_alias_1 }
|
|
234
|
+
|
|
235
|
+
declare function createAnnouncementsModule(config: Readonly<InternalClientConfig>): {
|
|
141
236
|
/**
|
|
142
237
|
* Lists announcements for an employee. IIS may return HTTP `404` or `400` (no list / endpoint quirks); the SDK maps those to `[]`.
|
|
143
238
|
*/
|
|
@@ -147,8 +242,10 @@ export declare function createAnnouncementsModule(config: InternalClientConfig):
|
|
|
147
242
|
*/
|
|
148
243
|
byDepartment(id: number, options?: ReadOptions): Promise<Announcement[]>;
|
|
149
244
|
};
|
|
245
|
+
export { createAnnouncementsModule }
|
|
246
|
+
export { createAnnouncementsModule as createAnnouncementsModule_alias_1 }
|
|
150
247
|
|
|
151
|
-
|
|
248
|
+
declare function createAuditoriesModule(config: Readonly<InternalClientConfig>): {
|
|
152
249
|
/**
|
|
153
250
|
* Returns the full list of auditories from `/auditories`.
|
|
154
251
|
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
@@ -159,63 +256,39 @@ export declare function createAuditoriesModule(config: InternalClientConfig): {
|
|
|
159
256
|
*/
|
|
160
257
|
listAll(options?: ReadOptions): Promise<Auditory[]>;
|
|
161
258
|
};
|
|
259
|
+
export { createAuditoriesModule }
|
|
260
|
+
export { createAuditoriesModule as createAuditoriesModule_alias_1 }
|
|
162
261
|
|
|
163
262
|
/**
|
|
164
263
|
* Creates a configured BSUIR IIS API client.
|
|
264
|
+
*
|
|
265
|
+
* Pass `{ defaultRaw: true }` to switch the default return shape of
|
|
266
|
+
* `schedule.getGroup` and `schedule.getEmployee` from `NormalizedScheduleResponse`
|
|
267
|
+
* to the raw `ScheduleResponse`. Per-call `raw` option always takes precedence.
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```ts
|
|
271
|
+
* // Normalized (default):
|
|
272
|
+
* const client = createBsuirClient();
|
|
273
|
+
*
|
|
274
|
+
* // Raw by default:
|
|
275
|
+
* const rawClient = createBsuirClient({ defaultRaw: true });
|
|
276
|
+
*
|
|
277
|
+
* // Custom fetch + timeout:
|
|
278
|
+
* const client = createBsuirClient({ fetch: myFetch, timeoutMs: 5_000 });
|
|
279
|
+
* ```
|
|
165
280
|
*/
|
|
166
|
-
declare function createBsuirClient(options
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}) => Promise<TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse>;
|
|
174
|
-
getGroupFiltered: (groupNumber: string, filter: ScheduleFilterOptions, options?: ReadOptions) => Promise<FlattenedScheduleItem[]>;
|
|
175
|
-
getEmployeeFiltered: (urlId: string, filter: ScheduleFilterOptions, options?: ReadOptions) => Promise<FlattenedScheduleItem[]>;
|
|
176
|
-
getGroupExams(groupNumber: string, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
177
|
-
getEmployeeExams(urlId: string, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
178
|
-
getGroupBySubgroup(groupNumber: string, subgroup: number, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
179
|
-
getEmployeeBySubgroup(urlId: string, subgroup: number, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
180
|
-
getCurrentWeek: (options?: ReadOptions) => Promise<number>;
|
|
181
|
-
getLastUpdateByGroup(params: {
|
|
182
|
-
groupNumber: string;
|
|
183
|
-
} | {
|
|
184
|
-
id: number;
|
|
185
|
-
}, options?: ReadOptions): Promise<ApiDateResponse>;
|
|
186
|
-
getLastUpdateByEmployee(params: {
|
|
187
|
-
urlId: string;
|
|
188
|
-
} | {
|
|
189
|
-
id: number;
|
|
190
|
-
}, options?: ReadOptions): Promise<ApiDateResponse>;
|
|
191
|
-
};
|
|
192
|
-
groups: {
|
|
193
|
-
listAll(options?: ReadOptions): Promise<StudentGroupCatalogItem[]>;
|
|
194
|
-
};
|
|
195
|
-
employees: {
|
|
196
|
-
listAll(options?: ReadOptions): Promise<EmployeeCatalogItem[]>;
|
|
197
|
-
};
|
|
198
|
-
faculties: {
|
|
199
|
-
listAll(options?: ReadOptions): Promise<Faculty[]>;
|
|
200
|
-
};
|
|
201
|
-
departments: {
|
|
202
|
-
listAll(options?: ReadOptions): Promise<Department[]>;
|
|
203
|
-
};
|
|
204
|
-
specialities: {
|
|
205
|
-
listAll(options?: ReadOptions): Promise<Speciality[]>;
|
|
206
|
-
};
|
|
207
|
-
announcements: {
|
|
208
|
-
byEmployee(urlId: string, options?: ReadOptions): Promise<Announcement[]>;
|
|
209
|
-
byDepartment(id: number, options?: ReadOptions): Promise<Announcement[]>;
|
|
210
|
-
};
|
|
211
|
-
auditories: {
|
|
212
|
-
listAll(options?: ReadOptions): Promise<Auditory[]>;
|
|
213
|
-
};
|
|
214
|
-
};
|
|
281
|
+
declare function createBsuirClient(options: BsuirClientOptions & {
|
|
282
|
+
defaultRaw: true;
|
|
283
|
+
}): BsuirClientShape<true>;
|
|
284
|
+
|
|
285
|
+
declare function createBsuirClient(options?: BsuirClientOptions & {
|
|
286
|
+
defaultRaw?: false | undefined;
|
|
287
|
+
}): BsuirClientShape<false>;
|
|
215
288
|
export { createBsuirClient }
|
|
216
289
|
export { createBsuirClient as createBsuirClient_alias_1 }
|
|
217
290
|
|
|
218
|
-
|
|
291
|
+
declare function createDepartmentsModule(config: Readonly<InternalClientConfig>): {
|
|
219
292
|
/**
|
|
220
293
|
* Returns the full list of departments from `/departments`.
|
|
221
294
|
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
@@ -226,8 +299,10 @@ export declare function createDepartmentsModule(config: InternalClientConfig): {
|
|
|
226
299
|
*/
|
|
227
300
|
listAll(options?: ReadOptions): Promise<Department[]>;
|
|
228
301
|
};
|
|
302
|
+
export { createDepartmentsModule }
|
|
303
|
+
export { createDepartmentsModule as createDepartmentsModule_alias_1 }
|
|
229
304
|
|
|
230
|
-
|
|
305
|
+
declare function createEmployeesModule(config: Readonly<InternalClientConfig>): {
|
|
231
306
|
/**
|
|
232
307
|
* Returns the full list of employees from `/employees/all`.
|
|
233
308
|
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
@@ -238,8 +313,10 @@ export declare function createEmployeesModule(config: InternalClientConfig): {
|
|
|
238
313
|
*/
|
|
239
314
|
listAll(options?: ReadOptions): Promise<EmployeeCatalogItem[]>;
|
|
240
315
|
};
|
|
316
|
+
export { createEmployeesModule }
|
|
317
|
+
export { createEmployeesModule as createEmployeesModule_alias_1 }
|
|
241
318
|
|
|
242
|
-
|
|
319
|
+
declare function createFacultiesModule(config: Readonly<InternalClientConfig>): {
|
|
243
320
|
/**
|
|
244
321
|
* Returns the full list of faculties from `/faculties`.
|
|
245
322
|
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
@@ -250,8 +327,10 @@ export declare function createFacultiesModule(config: InternalClientConfig): {
|
|
|
250
327
|
*/
|
|
251
328
|
listAll(options?: ReadOptions): Promise<Faculty[]>;
|
|
252
329
|
};
|
|
330
|
+
export { createFacultiesModule }
|
|
331
|
+
export { createFacultiesModule as createFacultiesModule_alias_1 }
|
|
253
332
|
|
|
254
|
-
|
|
333
|
+
declare function createGroupsModule(config: Readonly<InternalClientConfig>): {
|
|
255
334
|
/**
|
|
256
335
|
* Returns the full list of student groups from `/student-groups`.
|
|
257
336
|
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
@@ -262,16 +341,18 @@ export declare function createGroupsModule(config: InternalClientConfig): {
|
|
|
262
341
|
*/
|
|
263
342
|
listAll(options?: ReadOptions): Promise<StudentGroupCatalogItem[]>;
|
|
264
343
|
};
|
|
344
|
+
export { createGroupsModule }
|
|
345
|
+
export { createGroupsModule as createGroupsModule_alias_1 }
|
|
265
346
|
|
|
266
347
|
export declare function createJsonResponse({ status, headers, body }: MockResponseInit): Response;
|
|
267
348
|
|
|
268
|
-
|
|
349
|
+
declare function createScheduleModule<TRawDefault extends boolean>(config: Readonly<InternalClientConfig<TRawDefault>>): {
|
|
269
350
|
getGroup: <TRaw extends boolean | undefined = undefined>(groupNumber: string, options?: ReadOptions & {
|
|
270
351
|
raw?: TRaw;
|
|
271
|
-
}) => Promise<TRaw
|
|
352
|
+
}) => Promise<ScheduleResponseByRawOption<TRaw, TRawDefault>>;
|
|
272
353
|
getEmployee: <TRaw extends boolean | undefined = undefined>(urlId: string, options?: ReadOptions & {
|
|
273
354
|
raw?: TRaw;
|
|
274
|
-
}) => Promise<TRaw
|
|
355
|
+
}) => Promise<ScheduleResponseByRawOption<TRaw, TRawDefault>>;
|
|
275
356
|
getGroupFiltered: (groupNumber: string, filter: ScheduleFilterOptions, options?: ReadOptions) => Promise<FlattenedScheduleItem[]>;
|
|
276
357
|
getEmployeeFiltered: (urlId: string, filter: ScheduleFilterOptions, options?: ReadOptions) => Promise<FlattenedScheduleItem[]>;
|
|
277
358
|
getGroupExams(groupNumber: string, options?: ReadOptions): Promise<FlattenedScheduleItem[]>;
|
|
@@ -298,8 +379,10 @@ export declare function createScheduleModule(config: InternalClientConfig): {
|
|
|
298
379
|
id: number;
|
|
299
380
|
}, options?: ReadOptions): Promise<ApiDateResponse>;
|
|
300
381
|
};
|
|
382
|
+
export { createScheduleModule }
|
|
383
|
+
export { createScheduleModule as createScheduleModule_alias_1 }
|
|
301
384
|
|
|
302
|
-
|
|
385
|
+
declare function createSpecialitiesModule(config: Readonly<InternalClientConfig>): {
|
|
303
386
|
/**
|
|
304
387
|
* Returns the full list of specialities from `/specialities`.
|
|
305
388
|
* If the caller aborts `options.signal`, the platform propagates `AbortError` (not wrapped by the SDK).
|
|
@@ -310,6 +393,8 @@ export declare function createSpecialitiesModule(config: InternalClientConfig):
|
|
|
310
393
|
*/
|
|
311
394
|
listAll(options?: ReadOptions): Promise<Speciality[]>;
|
|
312
395
|
};
|
|
396
|
+
export { createSpecialitiesModule }
|
|
397
|
+
export { createSpecialitiesModule as createSpecialitiesModule_alias_1 }
|
|
313
398
|
|
|
314
399
|
export declare const default_alias: Options | Options[] | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
|
|
315
400
|
|
|
@@ -367,6 +452,13 @@ export { EmployeeCatalogItem }
|
|
|
367
452
|
export { EmployeeCatalogItem as EmployeeCatalogItem_alias_1 }
|
|
368
453
|
export { EmployeeCatalogItem as EmployeeCatalogItem_alias_2 }
|
|
369
454
|
|
|
455
|
+
declare interface ErrorHookContext extends RequestHookContext {
|
|
456
|
+
durationMs: number;
|
|
457
|
+
error: unknown;
|
|
458
|
+
}
|
|
459
|
+
export { ErrorHookContext }
|
|
460
|
+
export { ErrorHookContext as ErrorHookContext_alias_1 }
|
|
461
|
+
|
|
370
462
|
declare interface Faculty {
|
|
371
463
|
id: number;
|
|
372
464
|
name: string;
|
|
@@ -376,7 +468,27 @@ export { Faculty }
|
|
|
376
468
|
export { Faculty as Faculty_alias_1 }
|
|
377
469
|
export { Faculty as Faculty_alias_2 }
|
|
378
470
|
|
|
379
|
-
|
|
471
|
+
/**
|
|
472
|
+
* Filters normalized schedule lessons by specified criteria.
|
|
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
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
declare function filterLessons(response: NormalizedScheduleResponse, filter: ScheduleFilterOptions): FlattenedScheduleItem[];
|
|
488
|
+
export { filterLessons }
|
|
489
|
+
export { filterLessons as filterLessons_alias_1 }
|
|
490
|
+
|
|
491
|
+
declare type FlattenedLessonsByDay = Record<Weekday, FlattenedScheduleItem[]>;
|
|
380
492
|
export { FlattenedLessonsByDay }
|
|
381
493
|
export { FlattenedLessonsByDay as FlattenedLessonsByDay_alias_1 }
|
|
382
494
|
export { FlattenedLessonsByDay as FlattenedLessonsByDay_alias_2 }
|
|
@@ -389,16 +501,28 @@ export { FlattenedScheduleItem }
|
|
|
389
501
|
export { FlattenedScheduleItem as FlattenedScheduleItem_alias_1 }
|
|
390
502
|
export { FlattenedScheduleItem as FlattenedScheduleItem_alias_2 }
|
|
391
503
|
|
|
392
|
-
export declare interface InternalClientConfig {
|
|
504
|
+
export declare interface InternalClientConfig<TRawDefault extends boolean = boolean> {
|
|
393
505
|
baseUrl: string;
|
|
394
506
|
fetchImpl: typeof globalThis.fetch;
|
|
507
|
+
signal: AbortSignal | undefined;
|
|
395
508
|
timeoutMs: number;
|
|
396
509
|
retries: number;
|
|
397
510
|
retryDelayMs: number;
|
|
398
511
|
retryMaxDelayMs: number;
|
|
399
512
|
retryJitter: boolean;
|
|
400
513
|
userAgent: string | undefined;
|
|
401
|
-
|
|
514
|
+
cacheTtlMs: number | undefined;
|
|
515
|
+
cacheMaxEntries: number;
|
|
516
|
+
dedupeInFlight: boolean;
|
|
517
|
+
validateResponses: boolean;
|
|
518
|
+
hooks: ClientHooks;
|
|
519
|
+
responseCache: Map<string, {
|
|
520
|
+
expiresAt: number;
|
|
521
|
+
value: unknown;
|
|
522
|
+
accessedAt: number;
|
|
523
|
+
}>;
|
|
524
|
+
inFlightRequests: Map<string, Promise<unknown>>;
|
|
525
|
+
defaultRaw: TRawDefault;
|
|
402
526
|
}
|
|
403
527
|
|
|
404
528
|
export declare function isAbortError(error: unknown): boolean;
|
|
@@ -420,14 +544,21 @@ export { Maybe as Maybe_alias_1 }
|
|
|
420
544
|
export { Maybe as Maybe_alias_2 }
|
|
421
545
|
|
|
422
546
|
/**
|
|
423
|
-
* Combines
|
|
547
|
+
* Combines multiple abort signals and/or a timeout into a single signal.
|
|
424
548
|
* When `AbortSignal.any` exists at runtime, delegates to the platform implementation.
|
|
425
|
-
* Otherwise uses a manual merge so
|
|
549
|
+
* Otherwise uses a manual merge so all signals are respected.
|
|
550
|
+
*
|
|
551
|
+
* @param signalsOrFirst - Array of signals to merge, or a single signal (legacy signature)
|
|
552
|
+
* @param timeoutMs - Optional timeout in milliseconds to include as an additional signal
|
|
553
|
+
*
|
|
554
|
+
* @remarks
|
|
555
|
+
* Calling with no signals and no timeout (e.g. `mergeSignals([])`) returns a signal
|
|
556
|
+
* that is never aborted — the caller is responsible for not doing this intentionally.
|
|
426
557
|
*/
|
|
427
|
-
export declare function mergeSignals(
|
|
558
|
+
export declare function mergeSignals(signalsOrFirst: AbortSignal[] | (AbortSignal | undefined), timeoutMs?: number): AbortSignal;
|
|
428
559
|
|
|
429
560
|
/** Used when `AbortSignal.any` is unavailable; exposed for unit tests. */
|
|
430
|
-
export declare function mergeSignalsManual(
|
|
561
|
+
export declare function mergeSignalsManual(signals: AbortSignal[], timeoutMs?: number): AbortSignal;
|
|
431
562
|
|
|
432
563
|
export declare function mockFetchSequence(responses: Array<Response | Error>): typeof globalThis.fetch;
|
|
433
564
|
|
|
@@ -449,6 +580,31 @@ export { NormalizedScheduleResponse }
|
|
|
449
580
|
export { NormalizedScheduleResponse as NormalizedScheduleResponse_alias_1 }
|
|
450
581
|
export { NormalizedScheduleResponse as NormalizedScheduleResponse_alias_2 }
|
|
451
582
|
|
|
583
|
+
/**
|
|
584
|
+
* Transforms raw API schedule response into a normalized structure with flattened lessons.
|
|
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
|
+
* ```
|
|
603
|
+
*/
|
|
604
|
+
declare function normalizeSchedule(response: ScheduleResponse): NormalizedScheduleResponse;
|
|
605
|
+
export { normalizeSchedule }
|
|
606
|
+
export { normalizeSchedule as normalizeSchedule_alias_1 }
|
|
607
|
+
|
|
452
608
|
/**
|
|
453
609
|
* Normalizes current week payload from API to a positive integer.
|
|
454
610
|
* API can return plain text (`"1\n"`) or number.
|
|
@@ -464,7 +620,11 @@ export declare type QueryValue = string | number | boolean | null | undefined;
|
|
|
464
620
|
/**
|
|
465
621
|
* Read options used by all module methods.
|
|
466
622
|
*/
|
|
467
|
-
declare interface ReadOptions
|
|
623
|
+
declare interface ReadOptions {
|
|
624
|
+
/**
|
|
625
|
+
* Optional signal to cancel request from the caller side.
|
|
626
|
+
*/
|
|
627
|
+
signal?: AbortSignal | undefined;
|
|
468
628
|
/**
|
|
469
629
|
* When true, return raw API payload where supported.
|
|
470
630
|
*/
|
|
@@ -473,10 +633,23 @@ declare interface ReadOptions extends RequestOptions {
|
|
|
473
633
|
export { ReadOptions }
|
|
474
634
|
export { ReadOptions as ReadOptions_alias_1 }
|
|
475
635
|
|
|
476
|
-
|
|
636
|
+
declare interface RequestHookContext {
|
|
637
|
+
method: RequestMethod;
|
|
638
|
+
path: string;
|
|
639
|
+
endpoint: string;
|
|
640
|
+
attempt: number;
|
|
641
|
+
maxAttempts: number;
|
|
642
|
+
query: QueryParams | undefined;
|
|
643
|
+
}
|
|
644
|
+
export { RequestHookContext }
|
|
645
|
+
export { RequestHookContext as RequestHookContext_alias_1 }
|
|
646
|
+
|
|
647
|
+
export declare function requestJson<T>(config: Readonly<InternalClientConfig>, path: string, options?: RequestOptions): Promise<T>;
|
|
648
|
+
|
|
649
|
+
export declare type RequestMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
477
650
|
|
|
478
651
|
/**
|
|
479
|
-
*
|
|
652
|
+
* Low-level HTTP request options used by internal request pipeline.
|
|
480
653
|
*/
|
|
481
654
|
declare interface RequestOptions {
|
|
482
655
|
/**
|
|
@@ -487,10 +660,38 @@ declare interface RequestOptions {
|
|
|
487
660
|
* Optional signal to cancel request from the caller side.
|
|
488
661
|
*/
|
|
489
662
|
signal?: AbortSignal | undefined;
|
|
663
|
+
/**
|
|
664
|
+
* HTTP method. Defaults to `GET`.
|
|
665
|
+
*/
|
|
666
|
+
method?: RequestMethod | undefined;
|
|
667
|
+
/**
|
|
668
|
+
* JSON body payload for mutating requests.
|
|
669
|
+
*/
|
|
670
|
+
body?: unknown;
|
|
671
|
+
/**
|
|
672
|
+
* Additional request headers.
|
|
673
|
+
*/
|
|
674
|
+
headers?: HeadersInit | undefined;
|
|
490
675
|
}
|
|
491
676
|
export { RequestOptions }
|
|
492
677
|
export { RequestOptions as RequestOptions_alias_1 }
|
|
493
678
|
|
|
679
|
+
declare interface ResponseHookContext extends RequestHookContext {
|
|
680
|
+
status: number;
|
|
681
|
+
durationMs: number;
|
|
682
|
+
fromCache: boolean;
|
|
683
|
+
}
|
|
684
|
+
export { ResponseHookContext }
|
|
685
|
+
export { ResponseHookContext as ResponseHookContext_alias_1 }
|
|
686
|
+
|
|
687
|
+
declare interface RetryHookContext extends RequestHookContext {
|
|
688
|
+
delayMs: number;
|
|
689
|
+
reason: "http_status" | "network_error";
|
|
690
|
+
status: number | undefined;
|
|
691
|
+
}
|
|
692
|
+
export { RetryHookContext }
|
|
693
|
+
export { RetryHookContext as RetryHookContext_alias_1 }
|
|
694
|
+
|
|
494
695
|
declare interface ScheduleFilterOptions {
|
|
495
696
|
source?: "schedules" | "exams";
|
|
496
697
|
weekday?: Weekday;
|
|
@@ -515,7 +716,7 @@ declare interface ScheduleItem {
|
|
|
515
716
|
subject: string;
|
|
516
717
|
subjectFullName: string;
|
|
517
718
|
note: Maybe<string>;
|
|
518
|
-
lessonTypeAbbrev: string
|
|
719
|
+
lessonTypeAbbrev: Maybe<string>;
|
|
519
720
|
dateLesson: Maybe<string>;
|
|
520
721
|
startLessonDate: Maybe<string>;
|
|
521
722
|
endLessonDate: Maybe<string>;
|
|
@@ -541,6 +742,8 @@ export { ScheduleResponse }
|
|
|
541
742
|
export { ScheduleResponse as ScheduleResponse_alias_1 }
|
|
542
743
|
export { ScheduleResponse as ScheduleResponse_alias_2 }
|
|
543
744
|
|
|
745
|
+
declare type ScheduleResponseByRawOption<TRaw extends boolean | undefined, TRawDefault extends boolean> = TRaw extends true ? ScheduleResponse : TRaw extends false ? NormalizedScheduleResponse : TRawDefault extends true ? ScheduleResponse : NormalizedScheduleResponse;
|
|
746
|
+
|
|
544
747
|
declare interface Speciality {
|
|
545
748
|
id: number;
|
|
546
749
|
name: string;
|