bsuir-iis-api 0.3.0 → 0.4.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
@@ -8,6 +8,18 @@ This changelog is maintained manually and updated in release commits.
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.4.0] - 2026-03-19
12
+
13
+ ### Removed
14
+
15
+ - `client.currentWeek` namespace; use `client.schedule.getCurrentWeek()` only.
16
+
17
+ ### Changed
18
+
19
+ - README: Quick start and “Raw vs normalized” explicitly tie examples to the default normalized
20
+ shape vs `{ raw: true }`; document `lessons`, `scheduleLessons`, and `examLessons`; note keeping
21
+ README and installed package version in sync with exported types.
22
+
11
23
  ## [0.3.0] - 2026-03-19
12
24
 
13
25
  ### Changed (0.3.0)
package/README.md CHANGED
@@ -10,12 +10,15 @@ npm install bsuir-iis-api
10
10
 
11
11
  ## Quick start
12
12
 
13
+ 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.
14
+
13
15
  ```ts
14
16
  import { createBsuirClient } from "bsuir-iis-api";
15
17
 
16
18
  const client = createBsuirClient();
17
19
 
18
20
  const schedule = await client.schedule.getGroup("053503");
21
+ // Normalized: `lessons` = weekly + exams flattened; see `scheduleLessons` / `examLessons` to split.
19
22
  console.log(schedule.lessons.length);
20
23
  ```
21
24
 
@@ -68,7 +71,6 @@ const client = createBsuirClient({
68
71
 
69
72
  ### Meta
70
73
 
71
- - `client.currentWeek.get(options?)` (alias to `client.schedule.getCurrentWeek`)
72
74
  - `client.lastUpdate.byGroup({ groupNumber } | { id }, options?)`
73
75
  - `client.lastUpdate.byEmployee({ urlId } | { id }, options?)`
74
76
 
@@ -97,8 +99,7 @@ Retry and abort behavior:
97
99
 
98
100
  ## Raw vs normalized schedule response
99
101
 
100
- By default, schedule methods return normalized response with `lessons`, `lessonsByDay`,
101
- `scheduleLessons`, and `examLessons`.
102
+ By default, schedule methods return a **normalized** `NormalizedScheduleResponse`: `lessons` is all flattened items (weekly + exams), each tagged with `source: "schedules" | "exams"`; `scheduleLessons` / `examLessons` are the same rows split by source; `lessonsByDay` groups by weekday.
102
103
 
103
104
  ```ts
104
105
  const raw = await client.schedule.getGroup("053503", { raw: true });
@@ -108,10 +109,11 @@ Use `defaultRaw: true` in `createBsuirClient` to change global behavior.
108
109
  When `raw` is omitted, `getGroup()` and `getEmployee()` return normalized payload.
109
110
  In raw mode API may return `schedules: null`; normalized mode always converts it to `{}`.
110
111
  In raw mode some lesson fields may also be nullable (`weekNumber`, `lessonTypeAbbrev`), so keep null checks if you consume raw payload directly.
112
+ README examples match the installed package version; if types and docs ever diverge, rely on `NormalizedScheduleResponse` / `ScheduleResponse` from the same release.
111
113
 
112
114
  ## Current week
113
115
 
114
- `getCurrentWeek()` returns the current week value directly from IIS API.
116
+ `client.schedule.getCurrentWeek()` returns the current week value directly from IIS API.
115
117
  The SDK normalizes `current-week` payloads, including plain-text responses like `1\n`.
116
118
 
117
119
  Filtering example:
package/dist/index.d.ts CHANGED
@@ -98,9 +98,6 @@ declare function createBsuirClient(options?: BsuirClientOptions): {
98
98
  id: number;
99
99
  }, options?: ReadOptions): Promise<ApiDateResponse>;
100
100
  };
101
- currentWeek: {
102
- get: (options?: ReadOptions) => Promise<number>;
103
- };
104
101
  };
105
102
  /**
106
103
  * Public client contract returned by {@link createBsuirClient}.
package/dist/index.js CHANGED
@@ -560,10 +560,7 @@ function createBsuirClient(options = {}) {
560
560
  specialities: createSpecialitiesModule(config),
561
561
  announcements: createAnnouncementsModule(config),
562
562
  auditories: createAuditoriesModule(config),
563
- lastUpdate: createLastUpdateModule(config),
564
- currentWeek: {
565
- get: schedule.getCurrentWeek
566
- }
563
+ lastUpdate: createLastUpdateModule(config)
567
564
  };
568
565
  }
569
566
  export {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/errors.ts","../src/utils/guards.ts","../src/client/http.ts","../src/modules/announcements.ts","../src/modules/auditories.ts","../src/modules/departments.ts","../src/modules/employees.ts","../src/modules/faculties.ts","../src/modules/groups.ts","../src/modules/lastUpdate.ts","../src/utils/week.ts","../src/modules/schedule.ts","../src/modules/specialities.ts","../src/client/createClient.ts"],"sourcesContent":["function fixErrorPrototype(instance: Error, prototype: object): void {\n Object.setPrototypeOf(instance, prototype);\n}\n\nexport class BsuirApiError extends Error {\n readonly status: number;\n readonly endpoint: string;\n readonly body: unknown;\n\n constructor(message: string, status: number, endpoint: string, body: unknown) {\n super(message);\n fixErrorPrototype(this, BsuirApiError.prototype);\n this.name = \"BsuirApiError\";\n this.status = status;\n this.endpoint = endpoint;\n this.body = body;\n }\n}\n\nexport class BsuirNetworkError extends Error {\n readonly endpoint: string;\n readonly causeError: unknown;\n\n constructor(message: string, endpoint: string, causeError: unknown) {\n super(message, { cause: causeError });\n fixErrorPrototype(this, BsuirNetworkError.prototype);\n this.name = \"BsuirNetworkError\";\n this.endpoint = endpoint;\n this.causeError = causeError;\n }\n}\n\nexport class BsuirTimeoutError extends Error {\n readonly endpoint: string;\n readonly timeoutMs: number;\n\n constructor(message: string, endpoint: string, timeoutMs: number) {\n super(message);\n fixErrorPrototype(this, BsuirTimeoutError.prototype);\n this.name = \"BsuirTimeoutError\";\n this.endpoint = endpoint;\n this.timeoutMs = timeoutMs;\n }\n}\n\nexport class BsuirValidationError extends Error {\n constructor(message: string) {\n super(message);\n fixErrorPrototype(this, BsuirValidationError.prototype);\n this.name = \"BsuirValidationError\";\n }\n}\n","import { BsuirValidationError } from \"../client/errors\";\n\nconst GROUP_NUMBER_PATTERN = /^\\d+$/;\nconst EMPLOYEE_URL_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/i;\n\nexport function assertNonEmptyString(value: unknown, fieldName: string): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new BsuirValidationError(`'${fieldName}' must be a non-empty string`);\n }\n}\n\nexport function assertPositiveInt(value: unknown, fieldName: string): asserts value is number {\n if (typeof value !== \"number\" || !Number.isInteger(value) || value <= 0) {\n throw new BsuirValidationError(`'${fieldName}' must be a positive integer`);\n }\n}\n\nexport function assertGroupNumber(value: unknown, fieldName = \"groupNumber\"): asserts value is string {\n assertNonEmptyString(value, fieldName);\n if (!GROUP_NUMBER_PATTERN.test(value)) {\n throw new BsuirValidationError(`'${fieldName}' must contain only digits`);\n }\n}\n\nexport function assertEmployeeUrlId(value: unknown, fieldName = \"urlId\"): asserts value is string {\n assertNonEmptyString(value, fieldName);\n if (!EMPLOYEE_URL_ID_PATTERN.test(value)) {\n throw new BsuirValidationError(\n `'${fieldName}' must be a valid slug (letters, digits, hyphen)`\n );\n }\n}\n\nexport function isAbortError(error: unknown): boolean {\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return true;\n }\n\n if (typeof error === \"object\" && error !== null) {\n const maybeError = error as { name?: unknown; code?: unknown };\n return maybeError.name === \"AbortError\" || maybeError.code === \"ABORT_ERR\";\n }\n\n return false;\n}\n","import { BsuirApiError, BsuirNetworkError, BsuirTimeoutError } from \"./errors\";\nimport type { InternalClientConfig, QueryParams, RequestOptions } from \"./types\";\nimport { isAbortError } from \"../utils/guards\";\n\nconst RETRIABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504]);\n\nfunction buildUrl(baseUrl: string, path: string, query?: QueryParams): string {\n const normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n const url = new URL(`${normalizedBase}${normalizedPath}`);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n url.searchParams.set(key, String(value));\n }\n }\n\n return url.toString();\n}\n\nfunction mergeSignals(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n if (typeof AbortSignal.any === \"function\") {\n return AbortSignal.any([AbortSignal.timeout(timeoutMs), signal].filter(Boolean) as AbortSignal[]);\n }\n\n if (signal) {\n return signal;\n }\n\n return AbortSignal.timeout(timeoutMs);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseRetryAfterMs(retryAfter: string | null): number | null {\n if (!retryAfter) {\n return null;\n }\n\n const asSeconds = Number(retryAfter);\n if (!Number.isNaN(asSeconds)) {\n return Math.max(0, Math.floor(asSeconds * 1000));\n }\n\n const dateValue = Date.parse(retryAfter);\n if (!Number.isNaN(dateValue)) {\n return Math.max(0, dateValue - Date.now());\n }\n\n return null;\n}\n\nfunction getRetryDelayMs(\n config: InternalClientConfig,\n attempt: number,\n retryAfterHeader?: string | null\n): number {\n const retryAfterDelay = parseRetryAfterMs(retryAfterHeader ?? null);\n if (retryAfterDelay !== null) {\n return Math.min(retryAfterDelay, config.retryMaxDelayMs);\n }\n\n const exponent = Math.max(0, attempt);\n const baseDelay = Math.min(config.retryDelayMs * 2 ** exponent, config.retryMaxDelayMs);\n if (!config.retryJitter) {\n return baseDelay;\n }\n\n const jitterFactor = 0.75 + Math.random() * 0.5;\n return Math.floor(baseDelay * jitterFactor);\n}\n\nasync function parseBody(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (!contentType.includes(\"application/json\")) {\n return response.text();\n }\n\n try {\n return await response.json();\n } catch {\n throw new BsuirApiError(\"Invalid JSON response payload\", response.status, response.url, null);\n }\n}\n\nexport async function requestJson<T>(\n config: InternalClientConfig,\n path: string,\n options: RequestOptions = {}\n): Promise<T> {\n const endpoint = buildUrl(config.baseUrl, path, options.query);\n const headers = new Headers({\n Accept: \"application/json\"\n });\n\n if (config.userAgent) {\n headers.set(\"User-Agent\", config.userAgent);\n }\n\n for (let attempt = 0; attempt <= config.retries; attempt += 1) {\n const requestSignal = mergeSignals(options.signal, config.timeoutMs);\n try {\n const response = await config.fetchImpl(endpoint, {\n method: \"GET\",\n headers,\n signal: requestSignal\n });\n\n if (!response.ok) {\n const errorBody = await parseBody(response);\n if (attempt < config.retries && RETRIABLE_STATUS_CODES.has(response.status)) {\n const delayMs = getRetryDelayMs(config, attempt, response.headers.get(\"retry-after\"));\n await sleep(delayMs);\n continue;\n }\n throw new BsuirApiError(\n `BSUIR API returned HTTP ${String(response.status)} for ${path}`,\n response.status,\n endpoint,\n errorBody\n );\n }\n\n return (await parseBody(response)) as T;\n } catch (error) {\n if (error instanceof BsuirApiError) {\n throw error;\n }\n\n if (isAbortError(error)) {\n if (options.signal?.aborted) {\n throw error;\n }\n throw new BsuirTimeoutError(\n `Request timed out after ${String(config.timeoutMs)}ms: ${path}`,\n endpoint,\n config.timeoutMs\n );\n }\n\n if (attempt < config.retries) {\n const delayMs = getRetryDelayMs(config, attempt);\n await sleep(delayMs);\n continue;\n }\n\n throw new BsuirNetworkError(`Network error while requesting ${path}`, endpoint, error);\n }\n }\n\n throw new BsuirNetworkError(`Unexpected retry loop termination for ${path}`, endpoint, null);\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport { assertEmployeeUrlId, assertPositiveInt } from \"../utils/guards\";\nimport type { Announcement } from \"../types/announcement\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createAnnouncementsModule(config: InternalClientConfig) {\n return {\n async byEmployee(urlId: string, options: ReadOptions = {}): Promise<Announcement[]> {\n assertEmployeeUrlId(urlId, \"urlId\");\n return requestJson<Announcement[]>(config, \"/announcements/employees\", {\n query: { \"url-id\": urlId },\n signal: options.signal\n });\n },\n\n async byDepartment(id: number, options: ReadOptions = {}): Promise<Announcement[]> {\n assertPositiveInt(id, \"id\");\n return requestJson<Announcement[]>(config, \"/announcements/departments\", {\n query: { id },\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Auditory } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createAuditoriesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Auditory[]> {\n return requestJson<Auditory[]>(config, \"/auditories\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Department } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createDepartmentsModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Department[]> {\n return requestJson<Department[]>(config, \"/departments\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { EmployeeCatalogItem } from \"../types/employee\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createEmployeesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<EmployeeCatalogItem[]> {\n return requestJson<EmployeeCatalogItem[]>(config, \"/employees/all\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Faculty } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createFacultiesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Faculty[]> {\n return requestJson<Faculty[]>(config, \"/faculties\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { StudentGroupCatalogItem } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createGroupsModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<StudentGroupCatalogItem[]> {\n return requestJson<StudentGroupCatalogItem[]>(config, \"/student-groups\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport { assertEmployeeUrlId, assertGroupNumber, assertPositiveInt } from \"../utils/guards\";\nimport type { ApiDateResponse } from \"../types/common\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createLastUpdateModule(config: InternalClientConfig) {\n return {\n async byGroup(\n params: { groupNumber: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"groupNumber\" in params) {\n assertGroupNumber(params.groupNumber, \"groupNumber\");\n query = { groupNumber: params.groupNumber };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n\n return requestJson<ApiDateResponse>(config, \"/last-update-date/student-group\", {\n query,\n signal: options.signal\n });\n },\n\n async byEmployee(\n params: { urlId: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"urlId\" in params) {\n assertEmployeeUrlId(params.urlId, \"urlId\");\n query = { \"url-id\": params.urlId };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n\n return requestJson<ApiDateResponse>(config, \"/last-update-date/employee\", {\n query,\n signal: options.signal\n });\n }\n };\n}\n","import { BsuirValidationError } from \"../client/errors\";\nimport { assertPositiveInt } from \"./guards\";\n\n/**\n * Normalizes current week payload from API to a positive integer.\n * API can return plain text (`\"1\\n\"`) or number.\n */\nexport function parseCurrentWeek(payload: unknown): number {\n if (typeof payload === \"number\") {\n assertPositiveInt(payload, \"currentWeek\");\n return payload;\n }\n\n if (typeof payload === \"string\") {\n const normalized = payload.trim();\n if (normalized.length > 0) {\n const parsed = Number(normalized);\n if (Number.isInteger(parsed)) {\n assertPositiveInt(parsed, \"currentWeek\");\n return parsed;\n }\n }\n }\n\n if (typeof payload === \"object\" && payload !== null) {\n const record = payload as Record<string, unknown>;\n if (\"weekNumber\" in record) {\n return parseCurrentWeek(record.weekNumber);\n }\n if (\"currentWeek\" in record) {\n return parseCurrentWeek(record.currentWeek);\n }\n }\n\n throw new BsuirValidationError(\"'currentWeek' response payload must be a positive integer\");\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport { assertEmployeeUrlId, assertGroupNumber, assertPositiveInt } from \"../utils/guards\";\nimport type {\n FlattenedLessonsByDay,\n FlattenedScheduleItem,\n NormalizedScheduleResponse,\n ScheduleFilterOptions,\n ScheduleResponse\n} from \"../types/schedule\";\nimport type { ApiDateResponse } from \"../types/common\";\nimport type { Weekday } from \"../types/common\";\nimport type { ReadOptions } from \"./types\";\nimport { parseCurrentWeek } from \"../utils/week\";\n\nconst WEEKDAYS: Weekday[] = [\n \"Понедельник\",\n \"Вторник\",\n \"Среда\",\n \"Четверг\",\n \"Пятница\",\n \"Суббота\"\n];\n\nfunction normalizeSchedule(response: ScheduleResponse): NormalizedScheduleResponse {\n const lessons: FlattenedScheduleItem[] = [];\n const lessonsByDay: FlattenedLessonsByDay = {};\n const safeSchedules = response.schedules ?? {};\n const safeExams = response.exams ?? [];\n for (const day of WEEKDAYS) {\n const dayItems = safeSchedules[day] ?? [];\n const flattenedDayItems = dayItems.map((item) => ({ ...item, day, source: \"schedules\" as const }));\n lessonsByDay[day] = flattenedDayItems;\n for (const item of dayItems) {\n lessons.push({ ...item, day, source: \"schedules\" });\n }\n }\n\n for (const exam of safeExams) {\n lessons.push({\n ...exam,\n day: null,\n // Exams are not grouped by weekday in API response.\n source: \"exams\"\n });\n }\n\n const scheduleLessons = lessons.filter((lesson) => lesson.source === \"schedules\");\n const examLessons = lessons.filter((lesson) => lesson.source === \"exams\");\n\n return {\n ...response,\n schedules: safeSchedules,\n exams: safeExams,\n lessons,\n lessonsByDay,\n scheduleLessons,\n examLessons\n };\n}\n\nfunction matchesFilter(item: FlattenedScheduleItem, filter: ScheduleFilterOptions): boolean {\n if (filter.source && item.source !== filter.source) {\n return false;\n }\n\n if (filter.weekday && item.day !== filter.weekday) {\n return false;\n }\n\n if (typeof filter.weekNumber === \"number\") {\n if (!Array.isArray(item.weekNumber) || !item.weekNumber.includes(filter.weekNumber)) {\n return false;\n }\n }\n\n if (typeof filter.subgroup === \"number\" && item.numSubgroup !== filter.subgroup) {\n return false;\n }\n\n if (filter.lessonTypeAbbrev) {\n const types = Array.isArray(filter.lessonTypeAbbrev)\n ? filter.lessonTypeAbbrev\n : [filter.lessonTypeAbbrev];\n if (!item.lessonTypeAbbrev || !types.includes(item.lessonTypeAbbrev)) {\n return false;\n }\n }\n\n if (filter.subjectQuery) {\n const query = filter.subjectQuery.toLowerCase();\n const haystack = `${item.subject} ${item.subjectFullName} ${item.note ?? \"\"}`.toLowerCase();\n if (!haystack.includes(query)) {\n return false;\n }\n }\n\n if (filter.employeeUrlId) {\n const employeeMatch = item.employees?.some((employee) => employee.urlId === filter.employeeUrlId);\n if (!employeeMatch) {\n return false;\n }\n }\n\n if (filter.auditory && !item.auditories.includes(filter.auditory)) {\n return false;\n }\n\n return true;\n}\n\nfunction filterLessons(\n response: NormalizedScheduleResponse,\n filter: ScheduleFilterOptions\n): FlattenedScheduleItem[] {\n return response.lessons.filter((item) => matchesFilter(item, filter));\n}\n\nexport function createScheduleModule(config: InternalClientConfig) {\n /**\n * Returns schedule for a student group.\n * By default returns normalized payload, unless `raw: true` is passed.\n */\n async function getGroup<TRaw extends boolean | undefined = undefined>(\n groupNumber: string,\n options: ReadOptions & { raw?: TRaw } = {}\n ): Promise<TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse> {\n assertGroupNumber(groupNumber, \"groupNumber\");\n const response = await requestJson<ScheduleResponse>(config, \"/schedule\", {\n query: { studentGroup: groupNumber },\n signal: options.signal\n });\n const result = options.raw ?? config.defaultRaw ? response : normalizeSchedule(response);\n return result as TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse;\n }\n\n /**\n * Returns schedule for an employee.\n * By default returns normalized payload, unless `raw: true` is passed.\n */\n async function getEmployee<TRaw extends boolean | undefined = undefined>(\n urlId: string,\n options: ReadOptions & { raw?: TRaw } = {}\n ): Promise<TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse> {\n assertEmployeeUrlId(urlId, \"urlId\");\n const response = await requestJson<ScheduleResponse>(\n config,\n `/employees/schedule/${encodeURIComponent(urlId)}`,\n {\n signal: options.signal\n }\n );\n const result = options.raw ?? config.defaultRaw ? response : normalizeSchedule(response);\n return result as TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse;\n }\n\n /**\n * Returns filtered schedule items for a group from normalized schedule payload.\n */\n async function getGroupFiltered(\n groupNumber: string,\n filter: ScheduleFilterOptions,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n const normalized = await getGroup(groupNumber, { ...options, raw: false });\n return filterLessons(normalized, filter);\n }\n\n /**\n * Returns filtered schedule items for an employee from normalized schedule payload.\n */\n async function getEmployeeFiltered(\n urlId: string,\n filter: ScheduleFilterOptions,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n const normalized = await getEmployee(urlId, { ...options, raw: false });\n return filterLessons(normalized, filter);\n }\n\n async function getCurrentWeek(options: ReadOptions = {}): Promise<number> {\n const payload = await requestJson<unknown>(config, \"/schedule/current-week\", {\n signal: options.signal\n });\n return parseCurrentWeek(payload);\n }\n\n return {\n getGroup,\n getEmployee,\n getGroupFiltered,\n getEmployeeFiltered,\n\n async getGroupExams(groupNumber: string, options: ReadOptions = {}): Promise<FlattenedScheduleItem[]> {\n return getGroupFiltered(groupNumber, { source: \"exams\" }, options);\n },\n\n async getEmployeeExams(urlId: string, options: ReadOptions = {}): Promise<FlattenedScheduleItem[]> {\n return getEmployeeFiltered(urlId, { source: \"exams\" }, options);\n },\n\n async getGroupBySubgroup(\n groupNumber: string,\n subgroup: number,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n assertPositiveInt(subgroup, \"subgroup\");\n return getGroupFiltered(groupNumber, { source: \"schedules\", subgroup }, options);\n },\n\n async getEmployeeBySubgroup(\n urlId: string,\n subgroup: number,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n assertPositiveInt(subgroup, \"subgroup\");\n return getEmployeeFiltered(urlId, { source: \"schedules\", subgroup }, options);\n },\n\n getCurrentWeek,\n\n async getLastUpdateByGroup(\n params: { groupNumber: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"groupNumber\" in params) {\n assertGroupNumber(params.groupNumber, \"groupNumber\");\n query = { groupNumber: params.groupNumber };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n return requestJson<ApiDateResponse>(config, \"/last-update-date/student-group\", {\n query,\n signal: options.signal\n });\n },\n\n async getLastUpdateByEmployee(\n params: { urlId: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"urlId\" in params) {\n assertEmployeeUrlId(params.urlId, \"urlId\");\n query = { \"url-id\": params.urlId };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n return requestJson<ApiDateResponse>(config, \"/last-update-date/employee\", {\n query,\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Speciality } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createSpecialitiesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Speciality[]> {\n return requestJson<Speciality[]>(config, \"/specialities\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { BsuirClientOptions, InternalClientConfig } from \"./types\";\nimport { createAnnouncementsModule } from \"../modules/announcements\";\nimport { createAuditoriesModule } from \"../modules/auditories\";\nimport { createDepartmentsModule } from \"../modules/departments\";\nimport { createEmployeesModule } from \"../modules/employees\";\nimport { createFacultiesModule } from \"../modules/faculties\";\nimport { createGroupsModule } from \"../modules/groups\";\nimport { createLastUpdateModule } from \"../modules/lastUpdate\";\nimport { createScheduleModule } from \"../modules/schedule\";\nimport { createSpecialitiesModule } from \"../modules/specialities\";\n\nconst DEFAULT_BASE_URL = \"https://iis.bsuir.by/api/v1\";\n\nfunction resolveFetch(customFetch?: typeof globalThis.fetch): typeof globalThis.fetch {\n if (customFetch) {\n return customFetch;\n }\n\n if (typeof globalThis.fetch !== \"function\") {\n throw new Error(\"Global fetch is unavailable. Provide 'fetch' in createBsuirClient options.\");\n }\n\n return globalThis.fetch;\n}\n\nfunction createInternalConfig(options: BsuirClientOptions = {}): InternalClientConfig {\n return {\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetchImpl: resolveFetch(options.fetch),\n timeoutMs: options.timeoutMs ?? 10_000,\n retries: options.retries ?? 1,\n retryDelayMs: options.retryDelayMs ?? 300,\n retryMaxDelayMs: options.retryMaxDelayMs ?? 3_000,\n retryJitter: options.retryJitter ?? true,\n userAgent: options.userAgent,\n defaultRaw: options.defaultRaw ?? false\n };\n}\n\n/**\n * Creates a configured BSUIR IIS API client.\n */\nexport function createBsuirClient(options: BsuirClientOptions = {}) {\n const config = createInternalConfig(options);\n const schedule = createScheduleModule(config);\n\n return {\n schedule,\n groups: createGroupsModule(config),\n employees: createEmployeesModule(config),\n faculties: createFacultiesModule(config),\n departments: createDepartmentsModule(config),\n specialities: createSpecialitiesModule(config),\n announcements: createAnnouncementsModule(config),\n auditories: createAuditoriesModule(config),\n lastUpdate: createLastUpdateModule(config),\n currentWeek: {\n get: schedule.getCurrentWeek\n }\n };\n}\n\n/**\n * Public client contract returned by {@link createBsuirClient}.\n */\nexport type BsuirClient = ReturnType<typeof createBsuirClient>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client/errors.ts","../src/utils/guards.ts","../src/client/http.ts","../src/modules/announcements.ts","../src/modules/auditories.ts","../src/modules/departments.ts","../src/modules/employees.ts","../src/modules/faculties.ts","../src/modules/groups.ts","../src/modules/lastUpdate.ts","../src/utils/week.ts","../src/modules/schedule.ts","../src/modules/specialities.ts","../src/client/createClient.ts"],"sourcesContent":["function fixErrorPrototype(instance: Error, prototype: object): void {\n Object.setPrototypeOf(instance, prototype);\n}\n\nexport class BsuirApiError extends Error {\n readonly status: number;\n readonly endpoint: string;\n readonly body: unknown;\n\n constructor(message: string, status: number, endpoint: string, body: unknown) {\n super(message);\n fixErrorPrototype(this, BsuirApiError.prototype);\n this.name = \"BsuirApiError\";\n this.status = status;\n this.endpoint = endpoint;\n this.body = body;\n }\n}\n\nexport class BsuirNetworkError extends Error {\n readonly endpoint: string;\n readonly causeError: unknown;\n\n constructor(message: string, endpoint: string, causeError: unknown) {\n super(message, { cause: causeError });\n fixErrorPrototype(this, BsuirNetworkError.prototype);\n this.name = \"BsuirNetworkError\";\n this.endpoint = endpoint;\n this.causeError = causeError;\n }\n}\n\nexport class BsuirTimeoutError extends Error {\n readonly endpoint: string;\n readonly timeoutMs: number;\n\n constructor(message: string, endpoint: string, timeoutMs: number) {\n super(message);\n fixErrorPrototype(this, BsuirTimeoutError.prototype);\n this.name = \"BsuirTimeoutError\";\n this.endpoint = endpoint;\n this.timeoutMs = timeoutMs;\n }\n}\n\nexport class BsuirValidationError extends Error {\n constructor(message: string) {\n super(message);\n fixErrorPrototype(this, BsuirValidationError.prototype);\n this.name = \"BsuirValidationError\";\n }\n}\n","import { BsuirValidationError } from \"../client/errors\";\n\nconst GROUP_NUMBER_PATTERN = /^\\d+$/;\nconst EMPLOYEE_URL_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/i;\n\nexport function assertNonEmptyString(value: unknown, fieldName: string): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new BsuirValidationError(`'${fieldName}' must be a non-empty string`);\n }\n}\n\nexport function assertPositiveInt(value: unknown, fieldName: string): asserts value is number {\n if (typeof value !== \"number\" || !Number.isInteger(value) || value <= 0) {\n throw new BsuirValidationError(`'${fieldName}' must be a positive integer`);\n }\n}\n\nexport function assertGroupNumber(value: unknown, fieldName = \"groupNumber\"): asserts value is string {\n assertNonEmptyString(value, fieldName);\n if (!GROUP_NUMBER_PATTERN.test(value)) {\n throw new BsuirValidationError(`'${fieldName}' must contain only digits`);\n }\n}\n\nexport function assertEmployeeUrlId(value: unknown, fieldName = \"urlId\"): asserts value is string {\n assertNonEmptyString(value, fieldName);\n if (!EMPLOYEE_URL_ID_PATTERN.test(value)) {\n throw new BsuirValidationError(\n `'${fieldName}' must be a valid slug (letters, digits, hyphen)`\n );\n }\n}\n\nexport function isAbortError(error: unknown): boolean {\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return true;\n }\n\n if (typeof error === \"object\" && error !== null) {\n const maybeError = error as { name?: unknown; code?: unknown };\n return maybeError.name === \"AbortError\" || maybeError.code === \"ABORT_ERR\";\n }\n\n return false;\n}\n","import { BsuirApiError, BsuirNetworkError, BsuirTimeoutError } from \"./errors\";\nimport type { InternalClientConfig, QueryParams, RequestOptions } from \"./types\";\nimport { isAbortError } from \"../utils/guards\";\n\nconst RETRIABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504]);\n\nfunction buildUrl(baseUrl: string, path: string, query?: QueryParams): string {\n const normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n const url = new URL(`${normalizedBase}${normalizedPath}`);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n url.searchParams.set(key, String(value));\n }\n }\n\n return url.toString();\n}\n\nfunction mergeSignals(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n if (typeof AbortSignal.any === \"function\") {\n return AbortSignal.any([AbortSignal.timeout(timeoutMs), signal].filter(Boolean) as AbortSignal[]);\n }\n\n if (signal) {\n return signal;\n }\n\n return AbortSignal.timeout(timeoutMs);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseRetryAfterMs(retryAfter: string | null): number | null {\n if (!retryAfter) {\n return null;\n }\n\n const asSeconds = Number(retryAfter);\n if (!Number.isNaN(asSeconds)) {\n return Math.max(0, Math.floor(asSeconds * 1000));\n }\n\n const dateValue = Date.parse(retryAfter);\n if (!Number.isNaN(dateValue)) {\n return Math.max(0, dateValue - Date.now());\n }\n\n return null;\n}\n\nfunction getRetryDelayMs(\n config: InternalClientConfig,\n attempt: number,\n retryAfterHeader?: string | null\n): number {\n const retryAfterDelay = parseRetryAfterMs(retryAfterHeader ?? null);\n if (retryAfterDelay !== null) {\n return Math.min(retryAfterDelay, config.retryMaxDelayMs);\n }\n\n const exponent = Math.max(0, attempt);\n const baseDelay = Math.min(config.retryDelayMs * 2 ** exponent, config.retryMaxDelayMs);\n if (!config.retryJitter) {\n return baseDelay;\n }\n\n const jitterFactor = 0.75 + Math.random() * 0.5;\n return Math.floor(baseDelay * jitterFactor);\n}\n\nasync function parseBody(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (!contentType.includes(\"application/json\")) {\n return response.text();\n }\n\n try {\n return await response.json();\n } catch {\n throw new BsuirApiError(\"Invalid JSON response payload\", response.status, response.url, null);\n }\n}\n\nexport async function requestJson<T>(\n config: InternalClientConfig,\n path: string,\n options: RequestOptions = {}\n): Promise<T> {\n const endpoint = buildUrl(config.baseUrl, path, options.query);\n const headers = new Headers({\n Accept: \"application/json\"\n });\n\n if (config.userAgent) {\n headers.set(\"User-Agent\", config.userAgent);\n }\n\n for (let attempt = 0; attempt <= config.retries; attempt += 1) {\n const requestSignal = mergeSignals(options.signal, config.timeoutMs);\n try {\n const response = await config.fetchImpl(endpoint, {\n method: \"GET\",\n headers,\n signal: requestSignal\n });\n\n if (!response.ok) {\n const errorBody = await parseBody(response);\n if (attempt < config.retries && RETRIABLE_STATUS_CODES.has(response.status)) {\n const delayMs = getRetryDelayMs(config, attempt, response.headers.get(\"retry-after\"));\n await sleep(delayMs);\n continue;\n }\n throw new BsuirApiError(\n `BSUIR API returned HTTP ${String(response.status)} for ${path}`,\n response.status,\n endpoint,\n errorBody\n );\n }\n\n return (await parseBody(response)) as T;\n } catch (error) {\n if (error instanceof BsuirApiError) {\n throw error;\n }\n\n if (isAbortError(error)) {\n if (options.signal?.aborted) {\n throw error;\n }\n throw new BsuirTimeoutError(\n `Request timed out after ${String(config.timeoutMs)}ms: ${path}`,\n endpoint,\n config.timeoutMs\n );\n }\n\n if (attempt < config.retries) {\n const delayMs = getRetryDelayMs(config, attempt);\n await sleep(delayMs);\n continue;\n }\n\n throw new BsuirNetworkError(`Network error while requesting ${path}`, endpoint, error);\n }\n }\n\n throw new BsuirNetworkError(`Unexpected retry loop termination for ${path}`, endpoint, null);\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport { assertEmployeeUrlId, assertPositiveInt } from \"../utils/guards\";\nimport type { Announcement } from \"../types/announcement\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createAnnouncementsModule(config: InternalClientConfig) {\n return {\n async byEmployee(urlId: string, options: ReadOptions = {}): Promise<Announcement[]> {\n assertEmployeeUrlId(urlId, \"urlId\");\n return requestJson<Announcement[]>(config, \"/announcements/employees\", {\n query: { \"url-id\": urlId },\n signal: options.signal\n });\n },\n\n async byDepartment(id: number, options: ReadOptions = {}): Promise<Announcement[]> {\n assertPositiveInt(id, \"id\");\n return requestJson<Announcement[]>(config, \"/announcements/departments\", {\n query: { id },\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Auditory } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createAuditoriesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Auditory[]> {\n return requestJson<Auditory[]>(config, \"/auditories\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Department } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createDepartmentsModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Department[]> {\n return requestJson<Department[]>(config, \"/departments\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { EmployeeCatalogItem } from \"../types/employee\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createEmployeesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<EmployeeCatalogItem[]> {\n return requestJson<EmployeeCatalogItem[]>(config, \"/employees/all\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Faculty } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createFacultiesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Faculty[]> {\n return requestJson<Faculty[]>(config, \"/faculties\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { StudentGroupCatalogItem } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createGroupsModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<StudentGroupCatalogItem[]> {\n return requestJson<StudentGroupCatalogItem[]>(config, \"/student-groups\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport { assertEmployeeUrlId, assertGroupNumber, assertPositiveInt } from \"../utils/guards\";\nimport type { ApiDateResponse } from \"../types/common\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createLastUpdateModule(config: InternalClientConfig) {\n return {\n async byGroup(\n params: { groupNumber: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"groupNumber\" in params) {\n assertGroupNumber(params.groupNumber, \"groupNumber\");\n query = { groupNumber: params.groupNumber };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n\n return requestJson<ApiDateResponse>(config, \"/last-update-date/student-group\", {\n query,\n signal: options.signal\n });\n },\n\n async byEmployee(\n params: { urlId: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"urlId\" in params) {\n assertEmployeeUrlId(params.urlId, \"urlId\");\n query = { \"url-id\": params.urlId };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n\n return requestJson<ApiDateResponse>(config, \"/last-update-date/employee\", {\n query,\n signal: options.signal\n });\n }\n };\n}\n","import { BsuirValidationError } from \"../client/errors\";\nimport { assertPositiveInt } from \"./guards\";\n\n/**\n * Normalizes current week payload from API to a positive integer.\n * API can return plain text (`\"1\\n\"`) or number.\n */\nexport function parseCurrentWeek(payload: unknown): number {\n if (typeof payload === \"number\") {\n assertPositiveInt(payload, \"currentWeek\");\n return payload;\n }\n\n if (typeof payload === \"string\") {\n const normalized = payload.trim();\n if (normalized.length > 0) {\n const parsed = Number(normalized);\n if (Number.isInteger(parsed)) {\n assertPositiveInt(parsed, \"currentWeek\");\n return parsed;\n }\n }\n }\n\n if (typeof payload === \"object\" && payload !== null) {\n const record = payload as Record<string, unknown>;\n if (\"weekNumber\" in record) {\n return parseCurrentWeek(record.weekNumber);\n }\n if (\"currentWeek\" in record) {\n return parseCurrentWeek(record.currentWeek);\n }\n }\n\n throw new BsuirValidationError(\"'currentWeek' response payload must be a positive integer\");\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport { assertEmployeeUrlId, assertGroupNumber, assertPositiveInt } from \"../utils/guards\";\nimport type {\n FlattenedLessonsByDay,\n FlattenedScheduleItem,\n NormalizedScheduleResponse,\n ScheduleFilterOptions,\n ScheduleResponse\n} from \"../types/schedule\";\nimport type { ApiDateResponse } from \"../types/common\";\nimport type { Weekday } from \"../types/common\";\nimport type { ReadOptions } from \"./types\";\nimport { parseCurrentWeek } from \"../utils/week\";\n\nconst WEEKDAYS: Weekday[] = [\n \"Понедельник\",\n \"Вторник\",\n \"Среда\",\n \"Четверг\",\n \"Пятница\",\n \"Суббота\"\n];\n\nfunction normalizeSchedule(response: ScheduleResponse): NormalizedScheduleResponse {\n const lessons: FlattenedScheduleItem[] = [];\n const lessonsByDay: FlattenedLessonsByDay = {};\n const safeSchedules = response.schedules ?? {};\n const safeExams = response.exams ?? [];\n for (const day of WEEKDAYS) {\n const dayItems = safeSchedules[day] ?? [];\n const flattenedDayItems = dayItems.map((item) => ({ ...item, day, source: \"schedules\" as const }));\n lessonsByDay[day] = flattenedDayItems;\n for (const item of dayItems) {\n lessons.push({ ...item, day, source: \"schedules\" });\n }\n }\n\n for (const exam of safeExams) {\n lessons.push({\n ...exam,\n day: null,\n // Exams are not grouped by weekday in API response.\n source: \"exams\"\n });\n }\n\n const scheduleLessons = lessons.filter((lesson) => lesson.source === \"schedules\");\n const examLessons = lessons.filter((lesson) => lesson.source === \"exams\");\n\n return {\n ...response,\n schedules: safeSchedules,\n exams: safeExams,\n lessons,\n lessonsByDay,\n scheduleLessons,\n examLessons\n };\n}\n\nfunction matchesFilter(item: FlattenedScheduleItem, filter: ScheduleFilterOptions): boolean {\n if (filter.source && item.source !== filter.source) {\n return false;\n }\n\n if (filter.weekday && item.day !== filter.weekday) {\n return false;\n }\n\n if (typeof filter.weekNumber === \"number\") {\n if (!Array.isArray(item.weekNumber) || !item.weekNumber.includes(filter.weekNumber)) {\n return false;\n }\n }\n\n if (typeof filter.subgroup === \"number\" && item.numSubgroup !== filter.subgroup) {\n return false;\n }\n\n if (filter.lessonTypeAbbrev) {\n const types = Array.isArray(filter.lessonTypeAbbrev)\n ? filter.lessonTypeAbbrev\n : [filter.lessonTypeAbbrev];\n if (!item.lessonTypeAbbrev || !types.includes(item.lessonTypeAbbrev)) {\n return false;\n }\n }\n\n if (filter.subjectQuery) {\n const query = filter.subjectQuery.toLowerCase();\n const haystack = `${item.subject} ${item.subjectFullName} ${item.note ?? \"\"}`.toLowerCase();\n if (!haystack.includes(query)) {\n return false;\n }\n }\n\n if (filter.employeeUrlId) {\n const employeeMatch = item.employees?.some((employee) => employee.urlId === filter.employeeUrlId);\n if (!employeeMatch) {\n return false;\n }\n }\n\n if (filter.auditory && !item.auditories.includes(filter.auditory)) {\n return false;\n }\n\n return true;\n}\n\nfunction filterLessons(\n response: NormalizedScheduleResponse,\n filter: ScheduleFilterOptions\n): FlattenedScheduleItem[] {\n return response.lessons.filter((item) => matchesFilter(item, filter));\n}\n\nexport function createScheduleModule(config: InternalClientConfig) {\n /**\n * Returns schedule for a student group.\n * By default returns normalized payload, unless `raw: true` is passed.\n */\n async function getGroup<TRaw extends boolean | undefined = undefined>(\n groupNumber: string,\n options: ReadOptions & { raw?: TRaw } = {}\n ): Promise<TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse> {\n assertGroupNumber(groupNumber, \"groupNumber\");\n const response = await requestJson<ScheduleResponse>(config, \"/schedule\", {\n query: { studentGroup: groupNumber },\n signal: options.signal\n });\n const result = options.raw ?? config.defaultRaw ? response : normalizeSchedule(response);\n return result as TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse;\n }\n\n /**\n * Returns schedule for an employee.\n * By default returns normalized payload, unless `raw: true` is passed.\n */\n async function getEmployee<TRaw extends boolean | undefined = undefined>(\n urlId: string,\n options: ReadOptions & { raw?: TRaw } = {}\n ): Promise<TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse> {\n assertEmployeeUrlId(urlId, \"urlId\");\n const response = await requestJson<ScheduleResponse>(\n config,\n `/employees/schedule/${encodeURIComponent(urlId)}`,\n {\n signal: options.signal\n }\n );\n const result = options.raw ?? config.defaultRaw ? response : normalizeSchedule(response);\n return result as TRaw extends true ? ScheduleResponse : NormalizedScheduleResponse;\n }\n\n /**\n * Returns filtered schedule items for a group from normalized schedule payload.\n */\n async function getGroupFiltered(\n groupNumber: string,\n filter: ScheduleFilterOptions,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n const normalized = await getGroup(groupNumber, { ...options, raw: false });\n return filterLessons(normalized, filter);\n }\n\n /**\n * Returns filtered schedule items for an employee from normalized schedule payload.\n */\n async function getEmployeeFiltered(\n urlId: string,\n filter: ScheduleFilterOptions,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n const normalized = await getEmployee(urlId, { ...options, raw: false });\n return filterLessons(normalized, filter);\n }\n\n async function getCurrentWeek(options: ReadOptions = {}): Promise<number> {\n const payload = await requestJson<unknown>(config, \"/schedule/current-week\", {\n signal: options.signal\n });\n return parseCurrentWeek(payload);\n }\n\n return {\n getGroup,\n getEmployee,\n getGroupFiltered,\n getEmployeeFiltered,\n\n async getGroupExams(groupNumber: string, options: ReadOptions = {}): Promise<FlattenedScheduleItem[]> {\n return getGroupFiltered(groupNumber, { source: \"exams\" }, options);\n },\n\n async getEmployeeExams(urlId: string, options: ReadOptions = {}): Promise<FlattenedScheduleItem[]> {\n return getEmployeeFiltered(urlId, { source: \"exams\" }, options);\n },\n\n async getGroupBySubgroup(\n groupNumber: string,\n subgroup: number,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n assertPositiveInt(subgroup, \"subgroup\");\n return getGroupFiltered(groupNumber, { source: \"schedules\", subgroup }, options);\n },\n\n async getEmployeeBySubgroup(\n urlId: string,\n subgroup: number,\n options: ReadOptions = {}\n ): Promise<FlattenedScheduleItem[]> {\n assertPositiveInt(subgroup, \"subgroup\");\n return getEmployeeFiltered(urlId, { source: \"schedules\", subgroup }, options);\n },\n\n getCurrentWeek,\n\n async getLastUpdateByGroup(\n params: { groupNumber: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"groupNumber\" in params) {\n assertGroupNumber(params.groupNumber, \"groupNumber\");\n query = { groupNumber: params.groupNumber };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n return requestJson<ApiDateResponse>(config, \"/last-update-date/student-group\", {\n query,\n signal: options.signal\n });\n },\n\n async getLastUpdateByEmployee(\n params: { urlId: string } | { id: number },\n options: ReadOptions = {}\n ): Promise<ApiDateResponse> {\n let query: Record<string, string | number>;\n if (\"urlId\" in params) {\n assertEmployeeUrlId(params.urlId, \"urlId\");\n query = { \"url-id\": params.urlId };\n } else {\n assertPositiveInt(params.id, \"id\");\n query = { id: params.id };\n }\n return requestJson<ApiDateResponse>(config, \"/last-update-date/employee\", {\n query,\n signal: options.signal\n });\n }\n };\n}\n","import type { InternalClientConfig } from \"../client/types\";\nimport { requestJson } from \"../client/http\";\nimport type { Speciality } from \"../types/catalog\";\nimport type { ReadOptions } from \"./types\";\n\nexport function createSpecialitiesModule(config: InternalClientConfig) {\n return {\n async listAll(options: ReadOptions = {}): Promise<Speciality[]> {\n return requestJson<Speciality[]>(config, \"/specialities\", {\n signal: options.signal\n });\n }\n };\n}\n","import type { BsuirClientOptions, InternalClientConfig } from \"./types\";\nimport { createAnnouncementsModule } from \"../modules/announcements\";\nimport { createAuditoriesModule } from \"../modules/auditories\";\nimport { createDepartmentsModule } from \"../modules/departments\";\nimport { createEmployeesModule } from \"../modules/employees\";\nimport { createFacultiesModule } from \"../modules/faculties\";\nimport { createGroupsModule } from \"../modules/groups\";\nimport { createLastUpdateModule } from \"../modules/lastUpdate\";\nimport { createScheduleModule } from \"../modules/schedule\";\nimport { createSpecialitiesModule } from \"../modules/specialities\";\n\nconst DEFAULT_BASE_URL = \"https://iis.bsuir.by/api/v1\";\n\nfunction resolveFetch(customFetch?: typeof globalThis.fetch): typeof globalThis.fetch {\n if (customFetch) {\n return customFetch;\n }\n\n if (typeof globalThis.fetch !== \"function\") {\n throw new Error(\"Global fetch is unavailable. Provide 'fetch' in createBsuirClient options.\");\n }\n\n return globalThis.fetch;\n}\n\nfunction createInternalConfig(options: BsuirClientOptions = {}): InternalClientConfig {\n return {\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetchImpl: resolveFetch(options.fetch),\n timeoutMs: options.timeoutMs ?? 10_000,\n retries: options.retries ?? 1,\n retryDelayMs: options.retryDelayMs ?? 300,\n retryMaxDelayMs: options.retryMaxDelayMs ?? 3_000,\n retryJitter: options.retryJitter ?? true,\n userAgent: options.userAgent,\n defaultRaw: options.defaultRaw ?? false\n };\n}\n\n/**\n * Creates a configured BSUIR IIS API client.\n */\nexport function createBsuirClient(options: BsuirClientOptions = {}) {\n const config = createInternalConfig(options);\n const schedule = createScheduleModule(config);\n\n return {\n schedule,\n groups: createGroupsModule(config),\n employees: createEmployeesModule(config),\n faculties: createFacultiesModule(config),\n departments: createDepartmentsModule(config),\n specialities: createSpecialitiesModule(config),\n announcements: createAnnouncementsModule(config),\n auditories: createAuditoriesModule(config),\n lastUpdate: createLastUpdateModule(config)\n };\n}\n\n/**\n * Public client contract returned by {@link createBsuirClient}.\n */\nexport type BsuirClient = ReturnType<typeof createBsuirClient>;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bsuir-iis-api",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Type-safe ESM SDK for BSUIR IIS API",
5
5
  "type": "module",
6
6
  "author": "kotru21",