iobroker.webuntis2 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/webuntis/WebUntisClient.ts"],
4
+ "sourcesContent": ["/* eslint-disable jsdoc/no-blank-blocks, jsdoc/require-param */\n\nimport { WebUntisError } from \"./WebUntisErrors\";\nimport type { HolidayEntry } from \"./Holidays\";\nimport type {\n\tTimetableQuery,\n\tWebUntisConnectionConfig,\n\tWebUntisHttpDiagnostic,\n\tWebUntisPeriod,\n\tWebUntisSession,\n} from \"./WebUntisTypes\";\n\nconst REQUEST_TIMEOUT_MS = 10_000;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction isAuthenticationResponse(value: unknown): value is WebUntisSession {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.sessionId === \"string\" &&\n\t\ttypeof value.personType === \"number\" &&\n\t\ttypeof value.personId === \"number\" &&\n\t\ttypeof value.klasseId === \"number\"\n\t);\n}\n\nfunction isPeriodList(value: unknown): value is WebUntisPeriod[] {\n\treturn Array.isArray(value) && value.every(isRecord);\n}\n\nfunction getClassIdFromConfig(value: unknown): number | null {\n\tif (!isRecord(value) || !isRecord(value.data)) {\n\t\treturn null;\n\t}\n\tconst classId = value.data.klasseId;\n\tif (typeof classId === \"number\" && Number.isInteger(classId) && classId > 0) {\n\t\treturn classId;\n\t}\n\tif (typeof classId === \"string\" && /^\\d+$/.test(classId) && Number(classId) > 0) {\n\t\treturn Number(classId);\n\t}\n\tif (Array.isArray(value.data.klassen)) {\n\t\tconst firstClass = value.data.klassen.find(isRecord);\n\t\tconst id = firstClass?.id ?? firstClass?.klasseId;\n\t\tif (typeof id === \"number\" && Number.isInteger(id)) {\n\t\t\treturn id;\n\t\t}\n\t\tif (typeof id === \"string\" && /^\\d+$/.test(id)) {\n\t\t\treturn Number(id);\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction publicPeriods(value: unknown, personId: number): WebUntisPeriod[] {\n\tif (!isRecord(value) || !isRecord(value.data) || !isRecord(value.data.result)) {\n\t\treturn [];\n\t}\n\tconst data = value.data.result.data;\n\tif (!isRecord(data) || !isRecord(data.elementPeriods)) {\n\t\treturn [];\n\t}\n\tconst periods = data.elementPeriods[String(personId)];\n\tif (!Array.isArray(periods)) {\n\t\treturn [];\n\t}\n\treturn periods.filter(isRecord).map(period => {\n\t\tconst elements = Array.isArray(period.elements) ? period.elements.filter(isRecord) : [];\n\t\tconst refs = (type: number): Record<string, unknown>[] =>\n\t\t\telements\n\t\t\t\t.filter(element => element.type === type)\n\t\t\t\t.map(element => (isRecord(element.element) ? element.element : element));\n\t\treturn { ...period, kl: refs(1), te: refs(2), su: refs(3), ro: refs(4) };\n\t});\n}\n\nfunction getSupportedPerson(value: unknown): { id: number; type: number } | null {\n\tif (!isRecord(value) || !isRecord(value.data) || !isRecord(value.data.loginServiceConfig)) {\n\t\treturn null;\n\t}\n\tconst user = value.data.loginServiceConfig.user;\n\tif (!isRecord(user) || !Array.isArray(user.persons)) {\n\t\treturn null;\n\t}\n\tfor (const person of user.persons) {\n\t\tif (!isRecord(person) || typeof person.id !== \"number\" || typeof person.type !== \"number\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif (person.type >= 1 && person.type <= 5) {\n\t\t\treturn { id: person.id, type: person.type };\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction isLoginPagePayload(value: unknown): boolean {\n\treturn isRecord(value) && Boolean(value.loginError);\n}\n\nfunction getEndpoint(server: string, schoolName: string): string {\n\tconst url = new URL(server);\n\tconst webUntisPath = url.pathname.match(/^(.*\\/WebUntis)(?:\\/|$)/i)?.[1] || \"/WebUntis\";\n\treturn `${url.origin}${webUntisPath}/jsonrpc.do?school=${encodeURIComponent(schoolName)}`;\n}\n\nfunction getResponseType(body: string, contentType: string): WebUntisHttpDiagnostic[\"type\"] {\n\tif (!body) {\n\t\treturn \"empty\";\n\t}\n\tif (contentType.toLocaleLowerCase().includes(\"html\") || /^\\s*</.test(body)) {\n\t\treturn \"html\";\n\t}\n\ttry {\n\t\tJSON.parse(body);\n\t\treturn \"json\";\n\t} catch {\n\t\treturn \"text\";\n\t}\n}\n\nfunction redactUrl(url: string): string {\n\treturn url.replace(/;jsessionid=[^?;]+/gi, \";jsessionid=<redacted>\");\n}\n\nfunction getCookieHeader(headers: Headers): string | undefined {\n\tconst cookieHeaders = headers as Headers & { getSetCookie?: () => string[] };\n\tconst values = cookieHeaders.getSetCookie?.() ?? [headers.get(\"set-cookie\") || \"\"];\n\tconst cookies = values\n\t\t.flatMap(value => value.split(/,(?=[^;,]+=)/))\n\t\t.map(value => value.split(\";\", 1)[0].trim())\n\t\t.filter(Boolean);\n\treturn cookies.length ? cookies.join(\"; \") : undefined;\n}\n\nfunction cookieValue(header: string | undefined, name: string): string | undefined {\n\treturn header\n\t\t?.split(/;\\s*/)\n\t\t.map(cookie => cookie.split(\"=\", 2))\n\t\t.find(([key]) => key === name)?.[1];\n}\n\nfunction mergeCookieHeader(\n\tprevious: string | undefined,\n\theaders: Headers,\n): { value?: string; changed: boolean; sessionCookieChanged: boolean } {\n\tconst values = new Map<string, string>();\n\tfor (const cookie of (previous || \"\").split(/;\\s*/)) {\n\t\tconst separator = cookie.indexOf(\"=\");\n\t\tif (separator > 0) {\n\t\t\tvalues.set(cookie.slice(0, separator), cookie);\n\t\t}\n\t}\n\tconst next = getCookieHeader(headers);\n\tif (next) {\n\t\tfor (const cookie of next.split(/;\\s*/)) {\n\t\t\tconst separator = cookie.indexOf(\"=\");\n\t\t\tif (separator > 0) {\n\t\t\t\tvalues.set(cookie.slice(0, separator), cookie);\n\t\t\t}\n\t\t}\n\t}\n\tconst value = values.size ? [...values.values()].join(\"; \") : undefined;\n\treturn {\n\t\tvalue,\n\t\tchanged: value !== previous,\n\t\tsessionCookieChanged: cookieValue(previous, \"JSESSIONID\") !== cookieValue(value, \"JSESSIONID\"),\n\t};\n}\n\n/**\n *\n */\nexport class WebUntisClient {\n\tprivate readonly endpoint: string;\n\tprivate sessionCookie?: string;\n\tprivate authenticatedAt?: number;\n\tprivate requestSequence = 0;\n\n\t/**\n\t *\n\t */\n\tpublic constructor(\n\t\tconfig: Pick<WebUntisConnectionConfig, \"server\" | \"schoolName\">,\n\t\tprivate readonly fetchImpl: typeof fetch = fetch,\n\t\tprivate readonly requestTimeoutMs = REQUEST_TIMEOUT_MS,\n\t\tprivate readonly onDiagnostic?: (diagnostic: WebUntisHttpDiagnostic) => void,\n\t) {\n\t\tthis.endpoint = getEndpoint(config.server, config.schoolName);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async authenticate(username: string, password: string): Promise<WebUntisSession> {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), this.requestTimeoutMs);\n\t\ttry {\n\t\t\tconst response = await this.fetchImpl(this.endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"content-type\": \"application/json\", accept: \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tid: Date.now().toString(),\n\t\t\t\t\tmethod: \"authenticate\",\n\t\t\t\t\tparams: { user: username, password, client: \"ioBroker.webuntis2\" },\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t}),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tthis.sessionCookie = getCookieHeader(response.headers);\n\t\t\tthis.authenticatedAt = Date.now();\n\t\t\tconst contentType = response.headers.get(\"content-type\") || \"\";\n\t\t\tconst body = await response.text();\n\t\t\tconst type = getResponseType(body, contentType);\n\t\t\tlet payload: unknown;\n\t\t\tif (type === \"json\") {\n\t\t\t\ttry {\n\t\t\t\t\tpayload = JSON.parse(body);\n\t\t\t\t} catch {\n\t\t\t\t\tthrow new WebUntisError(\"INVALID_RESPONSE\", \"Invalid WebUntis JSON response\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst diagnostic: WebUntisHttpDiagnostic = {\n\t\t\t\tmethod: \"authenticate\",\n\t\t\t\tstatus: response.status,\n\t\t\t\tcontentType,\n\t\t\t\turl: redactUrl(response.url),\n\t\t\t\tredirected: response.redirected,\n\t\t\t\tlength: body.length,\n\t\t\t\ttype,\n\t\t\t\tcookiePresent: Boolean(this.sessionCookie),\n\t\t\t\tresponseHeaders: Array.from(response.headers.keys()).sort(),\n\t\t\t};\n\t\t\tif (isRecord(payload)) {\n\t\t\t\tdiagnostic.keys = Object.keys(payload);\n\t\t\t\tif (isRecord(payload.error)) {\n\t\t\t\t\tdiagnostic.errorKeys = Object.keys(payload.error);\n\t\t\t\t\tif (typeof payload.error.code === \"number\") {\n\t\t\t\t\t\tdiagnostic.errorCode = payload.error.code;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof payload.error.message === \"string\") {\n\t\t\t\t\t\tdiagnostic.errorMessage = payload.error.message.slice(0, 120);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isRecord(payload.result)) {\n\t\t\t\t\tdiagnostic.resultKeys = Object.keys(payload.result);\n\t\t\t\t\tif (typeof payload.result.personType === \"number\") {\n\t\t\t\t\t\tdiagnostic.personType = payload.result.personType;\n\t\t\t\t\t}\n\t\t\t\t\tdiagnostic.personIdPresent = typeof payload.result.personId === \"number\";\n\t\t\t\t\tdiagnostic.klasseIdPresent = typeof payload.result.klasseId === \"number\";\n\t\t\t\t}\n\t\t\t\tdiagnostic.resultType = Array.isArray(payload.result)\n\t\t\t\t\t? \"array\"\n\t\t\t\t\t: payload.result === undefined\n\t\t\t\t\t\t? \"missing\"\n\t\t\t\t\t\t: isRecord(payload.result)\n\t\t\t\t\t\t\t? \"object\"\n\t\t\t\t\t\t\t: \"primitive\";\n\t\t\t\tif (Array.isArray(payload.result)) {\n\t\t\t\t\tdiagnostic.resultLength = payload.result.length;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.onDiagnostic?.(diagnostic);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new WebUntisError(\"SERVER_UNREACHABLE\", `WebUntis HTTP ${response.status}`);\n\t\t\t}\n\t\t\tif (response.redirected) {\n\t\t\t\tthrow new WebUntisError(\"REDIRECTED\", \"WebUntis redirected the authentication request\");\n\t\t\t}\n\t\t\tif (type === \"html\") {\n\t\t\t\tthrow new WebUntisError(\"HTML_RESPONSE\", \"WebUntis returned HTML instead of JSON\");\n\t\t\t}\n\t\t\tif (!isRecord(payload)) {\n\t\t\t\tthrow new WebUntisError(\"INVALID_RESPONSE\", \"Invalid WebUntis response\");\n\t\t\t}\n\t\t\tif (isRecord(payload.error)) {\n\t\t\t\tconst code = payload.error.code;\n\t\t\t\tif (code === -8504 || code === -8520 || code === -8521) {\n\t\t\t\t\tthrow new WebUntisError(\"INVALID_CREDENTIALS\", \"WebUntis rejected the credentials\");\n\t\t\t\t}\n\t\t\t\tif (code === -8522) {\n\t\t\t\t\tthrow new WebUntisError(\"USER_BLOCKED\", \"WebUntis user is blocked\");\n\t\t\t\t}\n\t\t\t\tif (code === -8500) {\n\t\t\t\t\tthrow new WebUntisError(\"INVALID_SCHOOL\", \"WebUntis rejected the school\");\n\t\t\t\t}\n\t\t\t\tthrow new WebUntisError(\"UNEXPECTED_RESPONSE\", \"WebUntis authentication failed\");\n\t\t\t}\n\t\t\tif (!isAuthenticationResponse(payload.result)) {\n\t\t\t\tthrow new WebUntisError(\"INVALID_RESPONSE\", \"Invalid authentication response\");\n\t\t\t}\n\t\t\treturn payload.result;\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebUntisError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof DOMException && error.name === \"AbortError\") {\n\t\t\t\tthrow new WebUntisError(\"TIMEOUT\", \"WebUntis authentication timed out\");\n\t\t\t}\n\t\t\tthrow new WebUntisError(\"SERVER_UNREACHABLE\", \"WebUntis authentication failed\", { cause: error });\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getTimetable(session: WebUntisSession, options: TimetableQuery): Promise<WebUntisPeriod[]> {\n\t\treturn this.request<WebUntisPeriod[]>(\"getTimetable\", { options }, session);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getSubjects(session: WebUntisSession): Promise<WebUntisPeriod[]> {\n\t\treturn this.request<WebUntisPeriod[]>(\"getSubjects\", {}, session);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getTeachers(session: WebUntisSession): Promise<WebUntisPeriod[]> {\n\t\treturn this.request<WebUntisPeriod[]>(\"getTeachers\", {}, session);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getRooms(session: WebUntisSession): Promise<WebUntisPeriod[]> {\n\t\treturn this.request<WebUntisPeriod[]>(\"getRooms\", {}, session);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getKlassen(session: WebUntisSession): Promise<WebUntisPeriod[]> {\n\t\treturn this.request<WebUntisPeriod[]>(\"getKlassen\", {}, session);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getHolidays(session: WebUntisSession): Promise<HolidayEntry[]> {\n\t\treturn this.request<HolidayEntry[]>(\"getHolidays\", {}, session);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getClassId(session: WebUntisSession): Promise<number | null> {\n\t\tconst url = this.endpoint.replace(/\\/jsonrpc\\.do\\?.*$/i, \"/api/daytimetable/config\");\n\t\tconst response = await this.fetchImpl(url, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t...(this.sessionCookie\n\t\t\t\t\t? { cookie: this.sessionCookie }\n\t\t\t\t\t: { cookie: `JSESSIONID=${session.sessionId}` }),\n\t\t\t},\n\t\t});\n\t\tconst cookie = mergeCookieHeader(this.sessionCookie, response.headers);\n\t\tthis.sessionCookie = cookie.value;\n\t\tconst contentType = response.headers.get(\"content-type\") || \"\";\n\t\tconst body = await response.text();\n\t\tconst type = getResponseType(body, contentType);\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = JSON.parse(body);\n\t\t} catch {\n\t\t\tthis.onDiagnostic?.({\n\t\t\t\tmethod: \"getClassId\",\n\t\t\t\tstatus: response.status,\n\t\t\t\tcontentType,\n\t\t\t\turl: redactUrl(response.url),\n\t\t\t\tredirected: response.redirected,\n\t\t\t\tlength: body.length,\n\t\t\t\ttype,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t\tthis.onDiagnostic?.({\n\t\t\tmethod: \"getClassId\",\n\t\t\tstatus: response.status,\n\t\t\tcontentType,\n\t\t\turl: redactUrl(response.url),\n\t\t\tredirected: response.redirected,\n\t\t\tlength: body.length,\n\t\t\ttype,\n\t\t\tresultType: \"object\",\n\t\t\tresultKeys: isRecord(payload) ? Object.keys(payload) : undefined,\n\t\t\tdataType: isRecord(payload) ? typeof payload.data : typeof payload,\n\t\t\tdataKeys: isRecord(payload) && isRecord(payload.data) ? Object.keys(payload.data) : [],\n\t\t\tclassIdType: isRecord(payload) && isRecord(payload.data) ? typeof payload.data.klasseId : \"missing\",\n\t\t\tclassIdPresent: getClassIdFromConfig(payload) !== null,\n\t\t\tcookiePresent: Boolean(this.sessionCookie),\n\t\t\tcookieChanged: cookie.changed,\n\t\t\tsessionCookieChanged: cookie.sessionCookieChanged,\n\t\t\tcookieCount: this.sessionCookie ? this.sessionCookie.split(/;\\s*/).length : 0,\n\t\t\tclassCandidateCount:\n\t\t\t\tisRecord(payload) && isRecord(payload.data) && Array.isArray(payload.data.klassen)\n\t\t\t\t\t? payload.data.klassen.length\n\t\t\t\t\t: 0,\n\t\t});\n\t\tif (response.redirected || isLoginPagePayload(payload)) {\n\t\t\tthrow new WebUntisError(\"SESSION_EXPIRED\", \"WebUntis session expired\");\n\t\t}\n\t\treturn getClassIdFromConfig(payload);\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getPublicTimetable(session: WebUntisSession, date: Date): Promise<WebUntisPeriod[]> {\n\t\tconst url = new URL(this.endpoint.replace(/\\/jsonrpc\\.do\\?.*$/i, \"/api/public/timetable/weekly/data\"));\n\t\turl.searchParams.set(\"elementType\", String(session.personType));\n\t\turl.searchParams.set(\"elementId\", String(session.personId));\n\t\turl.searchParams.set(\"date\", date.toISOString().slice(0, 10));\n\t\turl.searchParams.set(\"formatId\", \"1\");\n\t\tconst response = await this.fetchImpl(url, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t...(this.sessionCookie\n\t\t\t\t\t? { cookie: this.sessionCookie }\n\t\t\t\t\t: { cookie: `JSESSIONID=${session.sessionId}` }),\n\t\t\t},\n\t\t});\n\t\tconst cookie = mergeCookieHeader(this.sessionCookie, response.headers);\n\t\tthis.sessionCookie = cookie.value;\n\t\tconst contentType = response.headers.get(\"content-type\") || \"\";\n\t\tconst body = await response.text();\n\t\tconst type = getResponseType(body, contentType);\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = JSON.parse(body);\n\t\t} catch {\n\t\t\tthrow new WebUntisError(\"INVALID_RESPONSE\", \"Invalid WebUntis public timetable response\");\n\t\t}\n\t\tconst periods = publicPeriods(payload, session.personId);\n\t\tthis.onDiagnostic?.({\n\t\t\tmethod: \"getPublicTimetable\",\n\t\t\tstatus: response.status,\n\t\t\tcontentType,\n\t\t\turl: redactUrl(response.url),\n\t\t\tredirected: response.redirected,\n\t\t\tlength: body.length,\n\t\t\ttype,\n\t\t\tresultType: \"array\",\n\t\t\tresultLength: periods.length,\n\t\t\tresultKeys: isRecord(payload) ? Object.keys(payload) : undefined,\n\t\t\tcookiePresent: Boolean(this.sessionCookie),\n\t\t\tcookieChanged: cookie.changed,\n\t\t\tsessionCookieChanged: cookie.sessionCookieChanged,\n\t\t\tcookieCount: this.sessionCookie ? this.sessionCookie.split(/;\\s*/).length : 0,\n\t\t\terrorMessage:\n\t\t\t\tisRecord(payload) && typeof payload.errorMessage === \"string\"\n\t\t\t\t\t? payload.errorMessage.slice(0, 120)\n\t\t\t\t\t: isRecord(payload) && isRecord(payload.error) && typeof payload.error.message === \"string\"\n\t\t\t\t\t\t? payload.error.message.slice(0, 120)\n\t\t\t\t\t\t: undefined,\n\t\t});\n\t\tif (!response.ok) {\n\t\t\tthrow new WebUntisError(\"SERVER_UNREACHABLE\", `WebUntis HTTP ${response.status}`);\n\t\t}\n\t\treturn periods;\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async getSupportedPerson(session: WebUntisSession): Promise<{ id: number; type: number } | null> {\n\t\tconst url = this.endpoint.replace(/\\/jsonrpc\\.do\\?.*$/i, \"/api/app/config\");\n\t\tconst response = await this.fetchImpl(url, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t...(this.sessionCookie\n\t\t\t\t\t? { cookie: this.sessionCookie }\n\t\t\t\t\t: { cookie: `JSESSIONID=${session.sessionId}` }),\n\t\t\t},\n\t\t});\n\t\tconst cookie = mergeCookieHeader(this.sessionCookie, response.headers);\n\t\tthis.sessionCookie = cookie.value;\n\t\tconst contentType = response.headers.get(\"content-type\") || \"\";\n\t\tconst body = await response.text();\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = JSON.parse(body);\n\t\t} catch {\n\t\t\tthis.onDiagnostic?.({\n\t\t\t\tmethod: \"getSupportedPerson\",\n\t\t\t\tstatus: response.status,\n\t\t\t\tcontentType,\n\t\t\t\turl: redactUrl(response.url),\n\t\t\t\tredirected: response.redirected,\n\t\t\t\tlength: body.length,\n\t\t\t\ttype: getResponseType(body, contentType),\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t\tconst person = getSupportedPerson(payload);\n\t\tthis.onDiagnostic?.({\n\t\t\tmethod: \"getSupportedPerson\",\n\t\t\tstatus: response.status,\n\t\t\tcontentType,\n\t\t\turl: redactUrl(response.url),\n\t\t\tredirected: response.redirected,\n\t\t\tlength: body.length,\n\t\t\ttype: getResponseType(body, contentType),\n\t\t\tresultType: person ? \"object\" : \"missing\",\n\t\t\tpersonCandidate: Boolean(person),\n\t\t\tresultKeys: isRecord(payload) ? Object.keys(payload) : undefined,\n\t\t\tcookiePresent: Boolean(this.sessionCookie),\n\t\t\tcookieChanged: cookie.changed,\n\t\t\tsessionCookieChanged: cookie.sessionCookieChanged,\n\t\t\tcookieCount: this.sessionCookie ? this.sessionCookie.split(/;\\s*/).length : 0,\n\t\t\terrorMessage:\n\t\t\t\tisRecord(payload) && typeof payload.errorMessage === \"string\"\n\t\t\t\t\t? payload.errorMessage.slice(0, 120)\n\t\t\t\t\t: undefined,\n\t\t});\n\t\tif (response.redirected || isLoginPagePayload(payload)) {\n\t\t\tthrow new WebUntisError(\"SESSION_EXPIRED\", \"WebUntis session expired\");\n\t\t}\n\t\treturn person;\n\t}\n\n\tprivate async request<T>(method: string, params: unknown, session: WebUntisSession): Promise<T> {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), this.requestTimeoutMs);\n\t\ttry {\n\t\t\tconst requestSequence = ++this.requestSequence;\n\t\t\tconst sessionEndpoint = this.endpoint.replace(\n\t\t\t\t\"/jsonrpc.do?\",\n\t\t\t\t`/jsonrpc.do;jsessionid=${encodeURIComponent(session.sessionId)}?`,\n\t\t\t);\n\t\t\tconst requestOptions = isRecord(params) && isRecord(params.options) ? params.options : undefined;\n\t\t\tconst response = await this.fetchImpl(sessionEndpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t...(this.sessionCookie ? { cookie: this.sessionCookie } : {}),\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ id: Date.now().toString(), method, params, jsonrpc: \"2.0\" }),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tconst body = await response.text();\n\t\t\tconst cookie = mergeCookieHeader(this.sessionCookie, response.headers);\n\t\t\tthis.sessionCookie = cookie.value;\n\t\t\tconst contentType = response.headers.get(\"content-type\") || \"\";\n\t\t\tconst type = getResponseType(body, contentType);\n\t\t\tlet payload: unknown;\n\t\t\tif (type === \"json\") {\n\t\t\t\ttry {\n\t\t\t\t\tpayload = JSON.parse(body);\n\t\t\t\t} catch {\n\t\t\t\t\t// Keep the safe transport diagnostic even for malformed JSON.\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst diagnostic: WebUntisHttpDiagnostic = {\n\t\t\t\tmethod,\n\t\t\t\tstatus: response.status,\n\t\t\t\tcontentType,\n\t\t\t\turl: redactUrl(response.url),\n\t\t\t\tredirected: response.redirected,\n\t\t\t\tlength: body.length,\n\t\t\t\ttype,\n\t\t\t\tcookiePresent: Boolean(this.sessionCookie),\n\t\t\t\tcookieChanged: cookie.changed,\n\t\t\t\tsessionCookieChanged: cookie.sessionCookieChanged,\n\t\t\t\tcookieCount: this.sessionCookie ? this.sessionCookie.split(/;\\s*/).length : 0,\n\t\t\t\tsessionAgeSeconds: this.authenticatedAt\n\t\t\t\t\t? Math.max(0, Math.round((Date.now() - this.authenticatedAt) / 1000))\n\t\t\t\t\t: undefined,\n\t\t\t\trequestSequence,\n\t\t\t\tsessionPresent: Boolean(session.sessionId),\n\t\t\t\tpersonIdPresent: typeof session.personId === \"number\",\n\t\t\t\telementType: isRecord(requestOptions?.element)\n\t\t\t\t\t? typeof requestOptions.element.type === \"number\"\n\t\t\t\t\t\t? requestOptions.element.type\n\t\t\t\t\t\t: undefined\n\t\t\t\t\t: undefined,\n\t\t\t\tstartDate: typeof requestOptions?.startDate === \"number\" ? requestOptions.startDate : undefined,\n\t\t\t\tendDate: typeof requestOptions?.endDate === \"number\" ? requestOptions.endDate : undefined,\n\t\t\t};\n\t\t\tif (isRecord(payload)) {\n\t\t\t\tdiagnostic.keys = Object.keys(payload);\n\t\t\t\tif (isRecord(payload.error)) {\n\t\t\t\t\tdiagnostic.errorKeys = Object.keys(payload.error);\n\t\t\t\t\tif (typeof payload.error.code === \"number\") {\n\t\t\t\t\t\tdiagnostic.errorCode = payload.error.code;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof payload.error.message === \"string\") {\n\t\t\t\t\t\tdiagnostic.errorMessage = payload.error.message.slice(0, 120);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(payload.result)) {\n\t\t\t\t\tdiagnostic.resultType = \"array\";\n\t\t\t\t\tdiagnostic.resultLength = payload.result.length;\n\t\t\t\t} else if (isRecord(payload.result)) {\n\t\t\t\t\tdiagnostic.resultType = \"object\";\n\t\t\t\t\tdiagnostic.resultKeys = Object.keys(payload.result);\n\t\t\t\t} else {\n\t\t\t\t\tdiagnostic.resultType = payload.result === undefined ? \"missing\" : \"primitive\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.onDiagnostic?.(diagnostic);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new WebUntisError(\"SERVER_UNREACHABLE\", `WebUntis HTTP ${response.status}`);\n\t\t\t}\n\t\t\tif (!isRecord(payload)) {\n\t\t\t\tthrow new WebUntisError(\n\t\t\t\t\ttype === \"html\" ? \"HTML_RESPONSE\" : \"INVALID_RESPONSE\",\n\t\t\t\t\ttype === \"html\" ? \"WebUntis returned HTML instead of JSON\" : \"Invalid WebUntis timetable response\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (isRecord(payload.error)) {\n\t\t\t\tif (\n\t\t\t\t\tpayload.error.code === -7001 &&\n\t\t\t\t\ttypeof payload.error.message === \"string\" &&\n\t\t\t\t\tpayload.error.message.startsWith(\"invalid elementType:\")\n\t\t\t\t) {\n\t\t\t\t\tthrow new WebUntisError(\"API_REQUEST\", \"WebUntis rejected the timetable element type\");\n\t\t\t\t}\n\t\t\t\tif (payload.error.code === -7001) {\n\t\t\t\t\tthrow new WebUntisError(\"SESSION_EXPIRED\", \"WebUntis session expired\");\n\t\t\t\t}\n\t\t\t\tthrow new WebUntisError(\"UNEXPECTED_RESPONSE\", \"WebUntis timetable request failed\");\n\t\t\t}\n\t\t\tif (!isPeriodList(payload.result)) {\n\t\t\t\tthrow new WebUntisError(\"INVALID_RESPONSE\", \"Invalid WebUntis timetable result\");\n\t\t\t}\n\t\t\treturn payload.result as T;\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebUntisError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof DOMException && error.name === \"AbortError\") {\n\t\t\t\tthrow new WebUntisError(\"TIMEOUT\", \"WebUntis timetable request timed out\");\n\t\t\t}\n\t\t\tthrow new WebUntisError(\"SERVER_UNREACHABLE\", \"WebUntis timetable request failed\", { cause: error });\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var WebUntisErrors_exports = {};
20
+ __export(WebUntisErrors_exports, {
21
+ WebUntisError: () => WebUntisError,
22
+ classifyWebUntisError: () => classifyWebUntisError
23
+ });
24
+ module.exports = __toCommonJS(WebUntisErrors_exports);
25
+ class WebUntisError extends Error {
26
+ code;
27
+ /**
28
+ *
29
+ */
30
+ constructor(code, message, options) {
31
+ super(message, options);
32
+ this.name = "WebUntisError";
33
+ this.code = code;
34
+ }
35
+ }
36
+ function classifyWebUntisError(error) {
37
+ if (error instanceof WebUntisError) {
38
+ return error.code;
39
+ }
40
+ if (error instanceof DOMException && error.name === "AbortError") {
41
+ return "TIMEOUT";
42
+ }
43
+ if (error instanceof TypeError) {
44
+ return "SERVER_UNREACHABLE";
45
+ }
46
+ return "UNEXPECTED_RESPONSE";
47
+ }
48
+ // Annotate the CommonJS export names for ESM import in node:
49
+ 0 && (module.exports = {
50
+ WebUntisError,
51
+ classifyWebUntisError
52
+ });
53
+ //# sourceMappingURL=WebUntisErrors.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/webuntis/WebUntisErrors.ts"],
4
+ "sourcesContent": ["/* eslint-disable jsdoc/no-blank-blocks, jsdoc/require-param */\n\nimport type { WebUntisErrorCode } from \"./WebUntisTypes\";\n\n/**\n *\n */\nexport class WebUntisError extends Error {\n\tpublic readonly code: WebUntisErrorCode;\n\n\t/**\n\t *\n\t */\n\tpublic constructor(code: WebUntisErrorCode, message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = \"WebUntisError\";\n\t\tthis.code = code;\n\t}\n}\n\n/**\n *\n */\nexport function classifyWebUntisError(error: unknown): WebUntisErrorCode {\n\tif (error instanceof WebUntisError) {\n\t\treturn error.code;\n\t}\n\tif (error instanceof DOMException && error.name === \"AbortError\") {\n\t\treturn \"TIMEOUT\";\n\t}\n\tif (error instanceof TypeError) {\n\t\treturn \"SERVER_UNREACHABLE\";\n\t}\n\treturn \"UNEXPECTED_RESPONSE\";\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,MAAM,sBAAsB,MAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKT,YAAY,MAAyB,SAAiB,SAAwB;AACpF,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACb;AACD;AAKO,SAAS,sBAAsB,OAAmC;AACxE,MAAI,iBAAiB,eAAe;AACnC,WAAO,MAAM;AAAA,EACd;AACA,MAAI,iBAAiB,gBAAgB,MAAM,SAAS,cAAc;AACjE,WAAO;AAAA,EACR;AACA,MAAI,iBAAiB,WAAW;AAC/B,WAAO;AAAA,EACR;AACA,SAAO;AACR;",
6
+ "names": []
7
+ }
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var WebUntisService_exports = {};
20
+ __export(WebUntisService_exports, {
21
+ WebUntisError: () => import_WebUntisErrors.WebUntisError,
22
+ WebUntisService: () => WebUntisService
23
+ });
24
+ module.exports = __toCommonJS(WebUntisService_exports);
25
+ var import_SchoolDiscovery = require("./SchoolDiscovery");
26
+ var import_Holidays = require("./Holidays");
27
+ var import_WebUntisClient = require("./WebUntisClient");
28
+ var import_WebUntisErrors = require("./WebUntisErrors");
29
+ var import_Timetable = require("./Timetable");
30
+ const MASTERDATA_TTL_MS = 6 * 60 * 60 * 1e3;
31
+ class WebUntisService {
32
+ constructor(onDiagnostic, onInfo, onWarning, fetchImpl = fetch, onDebug) {
33
+ this.onDiagnostic = onDiagnostic;
34
+ this.onInfo = onInfo;
35
+ this.onWarning = onWarning;
36
+ this.fetchImpl = fetchImpl;
37
+ this.onDebug = onDebug;
38
+ }
39
+ holidayCache = new import_Holidays.HolidayCache();
40
+ sessionClient;
41
+ session;
42
+ sessionKey;
43
+ sessionLoading;
44
+ masterDataCache;
45
+ /**
46
+ *
47
+ */
48
+ searchSchools(query) {
49
+ return (0, import_SchoolDiscovery.searchSchools)(query);
50
+ }
51
+ async loadTimetable(config, now = /* @__PURE__ */ new Date()) {
52
+ var _a;
53
+ if (!config.server || !config.schoolName || config.schoolId === null) {
54
+ throw new import_WebUntisErrors.WebUntisError("SCHOOL_NOT_SELECTED", "School selection is missing");
55
+ }
56
+ if (!config.username.trim()) {
57
+ throw new import_WebUntisErrors.WebUntisError("USERNAME_REQUIRED", "Username is missing");
58
+ }
59
+ if (!config.password) {
60
+ throw new import_WebUntisErrors.WebUntisError("PASSWORD_REQUIRED", "Password is missing");
61
+ }
62
+ try {
63
+ return await this.loadTimetableWithSession(config, now);
64
+ } catch (error) {
65
+ if (!(error instanceof import_WebUntisErrors.WebUntisError) || error.code !== "SESSION_EXPIRED") {
66
+ throw error;
67
+ }
68
+ (_a = this.onDebug) == null ? void 0 : _a.call(this, "WebUntis session expired; performing one diagnostic re-authentication");
69
+ this.sessionClient = void 0;
70
+ this.session = void 0;
71
+ this.sessionKey = void 0;
72
+ return this.loadTimetableWithSession(config, now);
73
+ }
74
+ }
75
+ async loadTimetableWithSession(config, now) {
76
+ const { client, session } = await this.getSession(config);
77
+ let holidayEntries = null;
78
+ try {
79
+ holidayEntries = await this.holidayCache.get(now, async () => {
80
+ var _a;
81
+ const entries = await client.getHolidays(session);
82
+ (_a = this.onInfo) == null ? void 0 : _a.call(this, `Holidays loaded: ${entries.length} entries`);
83
+ return entries;
84
+ });
85
+ } catch (error) {
86
+ if (error instanceof import_WebUntisErrors.WebUntisError && error.code === "SESSION_EXPIRED") {
87
+ throw error;
88
+ }
89
+ }
90
+ const holidays = holidayEntries ? (0, import_Holidays.summarizeHolidays)(holidayEntries, now) : null;
91
+ const range = (0, import_Timetable.weekRange)(now);
92
+ const classId = session.personType >= 1 && session.personType <= 5 ? null : await client.getClassId(session);
93
+ const supportedPerson = session.personType >= 1 && session.personType <= 5 ? null : await client.getSupportedPerson(session);
94
+ const element = session.personType >= 1 && session.personType <= 5 ? { id: session.personId, type: session.personType } : supportedPerson ? supportedPerson : (classId != null ? classId : session.klasseId) > 0 ? { id: classId != null ? classId : session.klasseId, type: 1 } : null;
95
+ if (!element) {
96
+ const periods2 = await client.getPublicTimetable(session, now);
97
+ return { ...(0, import_Timetable.splitTimetable)((0, import_Timetable.normalizeLessons)(periods2), now), holidays };
98
+ }
99
+ const periods = await client.getTimetable(session, {
100
+ ...range,
101
+ element,
102
+ onlyBaseTimetable: false,
103
+ showBooking: true,
104
+ showInfo: true,
105
+ showSubstText: true,
106
+ showLsText: true,
107
+ showLsNumber: true,
108
+ showStudentgroup: true
109
+ });
110
+ const { subjects, teachers, rooms, klassen } = await this.getMasterData(
111
+ client,
112
+ session,
113
+ this.configKey(config),
114
+ now
115
+ );
116
+ return {
117
+ ...(0, import_Timetable.splitTimetable)(
118
+ (0, import_Timetable.normalizeLessons)((0, import_Timetable.resolveTimetableReferences)(periods, { subjects, teachers, rooms, klassen })),
119
+ now
120
+ ),
121
+ holidays
122
+ };
123
+ }
124
+ configKey(config) {
125
+ return [config.server, config.schoolName, config.username, config.password].join("\0");
126
+ }
127
+ async getSession(config) {
128
+ var _a;
129
+ const key = this.configKey(config);
130
+ if (this.sessionClient && this.session && this.sessionKey === key) {
131
+ return { client: this.sessionClient, session: this.session };
132
+ }
133
+ if (((_a = this.sessionLoading) == null ? void 0 : _a.key) === key) {
134
+ return this.sessionLoading.promise;
135
+ }
136
+ const client = new import_WebUntisClient.WebUntisClient(config, this.fetchImpl, void 0, this.onDiagnostic);
137
+ const promise = client.authenticate(config.username, config.password).then((session) => {
138
+ var _a2;
139
+ this.sessionClient = client;
140
+ this.session = session;
141
+ this.sessionKey = key;
142
+ (_a2 = this.onInfo) == null ? void 0 : _a2.call(this, "WebUntis login successful");
143
+ return { client, session };
144
+ });
145
+ this.sessionLoading = { key, promise };
146
+ void promise.then(
147
+ () => {
148
+ var _a2;
149
+ if (((_a2 = this.sessionLoading) == null ? void 0 : _a2.promise) === promise) {
150
+ this.sessionLoading = void 0;
151
+ }
152
+ },
153
+ () => {
154
+ var _a2;
155
+ if (((_a2 = this.sessionLoading) == null ? void 0 : _a2.promise) === promise) {
156
+ this.sessionLoading = void 0;
157
+ }
158
+ }
159
+ );
160
+ return promise;
161
+ }
162
+ async getMasterData(client, session, key, now) {
163
+ const current = this.masterDataCache;
164
+ if ((current == null ? void 0 : current.key) === key && current.fetchedAt > 0 && now.getTime() - current.fetchedAt < MASTERDATA_TTL_MS) {
165
+ return current.data;
166
+ }
167
+ if ((current == null ? void 0 : current.key) === key && current.loading) {
168
+ return current.loading;
169
+ }
170
+ const cache = {
171
+ key,
172
+ data: (current == null ? void 0 : current.key) === key ? current.data : { subjects: [], teachers: [], rooms: [], klassen: [] },
173
+ fetchedAt: (current == null ? void 0 : current.key) === key ? current.fetchedAt : 0
174
+ };
175
+ this.masterDataCache = cache;
176
+ const loading = this.refreshMasterData(client, session, cache, now);
177
+ cache.loading = loading;
178
+ void loading.then(
179
+ () => {
180
+ if (cache.loading === loading) {
181
+ cache.loading = void 0;
182
+ }
183
+ },
184
+ () => {
185
+ if (cache.loading === loading) {
186
+ cache.loading = void 0;
187
+ }
188
+ }
189
+ );
190
+ return loading;
191
+ }
192
+ async refreshMasterData(client, session, cache, now) {
193
+ var _a, _b, _c;
194
+ const results = await Promise.allSettled([
195
+ client.getSubjects(session),
196
+ client.getTeachers(session),
197
+ client.getRooms(session),
198
+ client.getKlassen(session)
199
+ ]);
200
+ const failed = results.some((result) => result.status === "rejected");
201
+ if (failed && cache.fetchedAt > 0) {
202
+ (_a = this.onWarning) == null ? void 0 : _a.call(this, "Master data refresh failed; existing master data is being reused");
203
+ return cache.data;
204
+ }
205
+ const data = {
206
+ subjects: results[0].status === "fulfilled" ? results[0].value : [],
207
+ teachers: results[1].status === "fulfilled" ? results[1].value : [],
208
+ rooms: results[2].status === "fulfilled" ? results[2].value : [],
209
+ klassen: results[3].status === "fulfilled" ? results[3].value : []
210
+ };
211
+ cache.data = data;
212
+ cache.fetchedAt = now.getTime();
213
+ if (failed) {
214
+ (_b = this.onWarning) == null ? void 0 : _b.call(this, "Some master data could not be loaded; unavailable lookups remain empty");
215
+ } else {
216
+ (_c = this.onInfo) == null ? void 0 : _c.call(
217
+ this,
218
+ `Master data loaded: ${data.subjects.length} subjects, ${data.teachers.length} teachers, ${data.rooms.length} rooms, ${data.klassen.length} classes`
219
+ );
220
+ }
221
+ return data;
222
+ }
223
+ /**
224
+ *
225
+ */
226
+ async testConnection(config) {
227
+ if (!config.server || !config.schoolName || config.schoolId === null) {
228
+ return { ok: false, code: "SCHOOL_NOT_SELECTED" };
229
+ }
230
+ if (!config.username.trim()) {
231
+ return { ok: false, code: "USERNAME_REQUIRED" };
232
+ }
233
+ if (!config.password) {
234
+ return { ok: false, code: "PASSWORD_REQUIRED" };
235
+ }
236
+ try {
237
+ await new import_WebUntisClient.WebUntisClient(config, this.fetchImpl, void 0, this.onDiagnostic).authenticate(
238
+ config.username,
239
+ config.password
240
+ );
241
+ return { ok: true };
242
+ } catch (error) {
243
+ return { ok: false, code: (0, import_WebUntisErrors.classifyWebUntisError)(error) };
244
+ }
245
+ }
246
+ }
247
+ // Annotate the CommonJS export names for ESM import in node:
248
+ 0 && (module.exports = {
249
+ WebUntisError,
250
+ WebUntisService
251
+ });
252
+ //# sourceMappingURL=WebUntisService.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/webuntis/WebUntisService.ts"],
4
+ "sourcesContent": ["/* eslint-disable jsdoc/no-blank-blocks, jsdoc/require-jsdoc, jsdoc/require-param */\n\nimport { searchSchools } from \"./SchoolDiscovery\";\nimport { HolidayCache, summarizeHolidays, type HolidaySummary } from \"./Holidays\";\nimport { WebUntisClient } from \"./WebUntisClient\";\nimport { classifyWebUntisError, WebUntisError } from \"./WebUntisErrors\";\nimport { normalizeLessons, resolveTimetableReferences, splitTimetable, weekRange } from \"./Timetable\";\nimport type {\n\tConnectionResult,\n\tSchoolSearchResult,\n\tWebUntisConnectionConfig,\n\tWebUntisHttpDiagnostic,\n\tWebUntisPeriod,\n\tWebUntisSession,\n} from \"./WebUntisTypes\";\nimport type { TimetableMasterData } from \"./Timetable\";\n\nconst MASTERDATA_TTL_MS = 6 * 60 * 60 * 1000;\n\ninterface MasterDataCache {\n\tkey: string;\n\tdata: TimetableMasterData;\n\tfetchedAt: number;\n\tloading?: Promise<TimetableMasterData>;\n}\n\n/**\n *\n */\nexport class WebUntisService {\n\tprivate readonly holidayCache = new HolidayCache();\n\tprivate sessionClient?: WebUntisClient;\n\tprivate session?: WebUntisSession;\n\tprivate sessionKey?: string;\n\tprivate sessionLoading?: { key: string; promise: Promise<{ client: WebUntisClient; session: WebUntisSession }> };\n\tprivate masterDataCache?: MasterDataCache;\n\n\tpublic constructor(\n\t\tprivate readonly onDiagnostic?: (diagnostic: WebUntisHttpDiagnostic) => void,\n\t\tprivate readonly onInfo?: (message: string) => void,\n\t\tprivate readonly onWarning?: (message: string) => void,\n\t\tprivate readonly fetchImpl: typeof fetch = fetch,\n\t\tprivate readonly onDebug?: (message: string) => void,\n\t) {}\n\t/**\n\t *\n\t */\n\tpublic searchSchools(query: string): Promise<SchoolSearchResult[]> {\n\t\treturn searchSchools(query);\n\t}\n\n\tpublic async loadTimetable(\n\t\tconfig: WebUntisConnectionConfig,\n\t\tnow = new Date(),\n\t): Promise<ReturnType<typeof splitTimetable> & { holidays: HolidaySummary | null }> {\n\t\tif (!config.server || !config.schoolName || config.schoolId === null) {\n\t\t\tthrow new WebUntisError(\"SCHOOL_NOT_SELECTED\", \"School selection is missing\");\n\t\t}\n\t\tif (!config.username.trim()) {\n\t\t\tthrow new WebUntisError(\"USERNAME_REQUIRED\", \"Username is missing\");\n\t\t}\n\t\tif (!config.password) {\n\t\t\tthrow new WebUntisError(\"PASSWORD_REQUIRED\", \"Password is missing\");\n\t\t}\n\t\ttry {\n\t\t\treturn await this.loadTimetableWithSession(config, now);\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof WebUntisError) || error.code !== \"SESSION_EXPIRED\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthis.onDebug?.(\"WebUntis session expired; performing one diagnostic re-authentication\");\n\t\t\tthis.sessionClient = undefined;\n\t\t\tthis.session = undefined;\n\t\t\tthis.sessionKey = undefined;\n\t\t\treturn this.loadTimetableWithSession(config, now);\n\t\t}\n\t}\n\n\tprivate async loadTimetableWithSession(\n\t\tconfig: WebUntisConnectionConfig,\n\t\tnow: Date,\n\t): Promise<ReturnType<typeof splitTimetable> & { holidays: HolidaySummary | null }> {\n\t\tconst { client, session } = await this.getSession(config);\n\t\tlet holidayEntries: Awaited<ReturnType<HolidayCache[\"get\"]>> = null;\n\t\ttry {\n\t\t\tholidayEntries = await this.holidayCache.get(now, async () => {\n\t\t\t\tconst entries = await client.getHolidays(session);\n\t\t\t\tthis.onInfo?.(`Holidays loaded: ${entries.length} entries`);\n\t\t\t\treturn entries;\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebUntisError && error.code === \"SESSION_EXPIRED\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\t// Holiday failures are optional; preserve existing holiday states.\n\t\t}\n\t\tconst holidays = holidayEntries ? summarizeHolidays(holidayEntries, now) : null;\n\t\tconst range = weekRange(now);\n\t\tconst classId = session.personType >= 1 && session.personType <= 5 ? null : await client.getClassId(session);\n\t\tconst supportedPerson =\n\t\t\tsession.personType >= 1 && session.personType <= 5 ? null : await client.getSupportedPerson(session);\n\t\tconst element =\n\t\t\tsession.personType >= 1 && session.personType <= 5\n\t\t\t\t? { id: session.personId, type: session.personType }\n\t\t\t\t: supportedPerson\n\t\t\t\t\t? supportedPerson\n\t\t\t\t\t: (classId ?? session.klasseId) > 0\n\t\t\t\t\t\t? { id: classId ?? session.klasseId, type: 1 }\n\t\t\t\t\t\t: null;\n\t\tif (!element) {\n\t\t\tconst periods = await client.getPublicTimetable(session, now);\n\t\t\treturn { ...splitTimetable(normalizeLessons(periods), now), holidays };\n\t\t}\n\t\tconst periods: WebUntisPeriod[] = await client.getTimetable(session, {\n\t\t\t...range,\n\t\t\telement,\n\t\t\tonlyBaseTimetable: false,\n\t\t\tshowBooking: true,\n\t\t\tshowInfo: true,\n\t\t\tshowSubstText: true,\n\t\t\tshowLsText: true,\n\t\t\tshowLsNumber: true,\n\t\t\tshowStudentgroup: true,\n\t\t});\n\t\tconst { subjects, teachers, rooms, klassen } = await this.getMasterData(\n\t\t\tclient,\n\t\t\tsession,\n\t\t\tthis.configKey(config),\n\t\t\tnow,\n\t\t);\n\t\treturn {\n\t\t\t...splitTimetable(\n\t\t\t\tnormalizeLessons(resolveTimetableReferences(periods, { subjects, teachers, rooms, klassen })),\n\t\t\t\tnow,\n\t\t\t),\n\t\t\tholidays,\n\t\t};\n\t}\n\n\tprivate configKey(config: WebUntisConnectionConfig): string {\n\t\treturn [config.server, config.schoolName, config.username, config.password].join(\"\\u0000\");\n\t}\n\n\tprivate async getSession(\n\t\tconfig: WebUntisConnectionConfig,\n\t): Promise<{ client: WebUntisClient; session: WebUntisSession }> {\n\t\tconst key = this.configKey(config);\n\t\tif (this.sessionClient && this.session && this.sessionKey === key) {\n\t\t\treturn { client: this.sessionClient, session: this.session };\n\t\t}\n\t\tif (this.sessionLoading?.key === key) {\n\t\t\treturn this.sessionLoading.promise;\n\t\t}\n\t\tconst client = new WebUntisClient(config, this.fetchImpl, undefined, this.onDiagnostic);\n\t\tconst promise = client.authenticate(config.username, config.password).then(session => {\n\t\t\tthis.sessionClient = client;\n\t\t\tthis.session = session;\n\t\t\tthis.sessionKey = key;\n\t\t\tthis.onInfo?.(\"WebUntis login successful\");\n\t\t\treturn { client, session };\n\t\t});\n\t\tthis.sessionLoading = { key, promise };\n\t\tvoid promise.then(\n\t\t\t() => {\n\t\t\t\tif (this.sessionLoading?.promise === promise) {\n\t\t\t\t\tthis.sessionLoading = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (this.sessionLoading?.promise === promise) {\n\t\t\t\t\tthis.sessionLoading = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t\treturn promise;\n\t}\n\n\tprivate async getMasterData(\n\t\tclient: WebUntisClient,\n\t\tsession: WebUntisSession,\n\t\tkey: string,\n\t\tnow: Date,\n\t): Promise<TimetableMasterData> {\n\t\tconst current = this.masterDataCache;\n\t\tif (current?.key === key && current.fetchedAt > 0 && now.getTime() - current.fetchedAt < MASTERDATA_TTL_MS) {\n\t\t\treturn current.data;\n\t\t}\n\t\tif (current?.key === key && current.loading) {\n\t\t\treturn current.loading;\n\t\t}\n\t\tconst cache: MasterDataCache = {\n\t\t\tkey,\n\t\t\tdata: current?.key === key ? current.data : { subjects: [], teachers: [], rooms: [], klassen: [] },\n\t\t\tfetchedAt: current?.key === key ? current.fetchedAt : 0,\n\t\t};\n\t\tthis.masterDataCache = cache;\n\t\tconst loading = this.refreshMasterData(client, session, cache, now);\n\t\tcache.loading = loading;\n\t\tvoid loading.then(\n\t\t\t() => {\n\t\t\t\tif (cache.loading === loading) {\n\t\t\t\t\tcache.loading = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (cache.loading === loading) {\n\t\t\t\t\tcache.loading = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t\treturn loading;\n\t}\n\n\tprivate async refreshMasterData(\n\t\tclient: WebUntisClient,\n\t\tsession: WebUntisSession,\n\t\tcache: MasterDataCache,\n\t\tnow: Date,\n\t): Promise<TimetableMasterData> {\n\t\tconst results = await Promise.allSettled([\n\t\t\tclient.getSubjects(session),\n\t\t\tclient.getTeachers(session),\n\t\t\tclient.getRooms(session),\n\t\t\tclient.getKlassen(session),\n\t\t]);\n\t\tconst failed = results.some(result => result.status === \"rejected\");\n\t\tif (failed && cache.fetchedAt > 0) {\n\t\t\tthis.onWarning?.(\"Master data refresh failed; existing master data is being reused\");\n\t\t\treturn cache.data;\n\t\t}\n\t\tconst data: TimetableMasterData = {\n\t\t\tsubjects: results[0].status === \"fulfilled\" ? results[0].value : [],\n\t\t\tteachers: results[1].status === \"fulfilled\" ? results[1].value : [],\n\t\t\trooms: results[2].status === \"fulfilled\" ? results[2].value : [],\n\t\t\tklassen: results[3].status === \"fulfilled\" ? results[3].value : [],\n\t\t};\n\t\tcache.data = data;\n\t\tcache.fetchedAt = now.getTime();\n\t\tif (failed) {\n\t\t\tthis.onWarning?.(\"Some master data could not be loaded; unavailable lookups remain empty\");\n\t\t} else {\n\t\t\tthis.onInfo?.(\n\t\t\t\t`Master data loaded: ${data.subjects.length} subjects, ${data.teachers.length} teachers, ${data.rooms.length} rooms, ${data.klassen.length} classes`,\n\t\t\t);\n\t\t}\n\t\treturn data;\n\t}\n\n\t/**\n\t *\n\t */\n\tpublic async testConnection(config: WebUntisConnectionConfig): Promise<ConnectionResult> {\n\t\tif (!config.server || !config.schoolName || config.schoolId === null) {\n\t\t\treturn { ok: false, code: \"SCHOOL_NOT_SELECTED\" };\n\t\t}\n\t\tif (!config.username.trim()) {\n\t\t\treturn { ok: false, code: \"USERNAME_REQUIRED\" };\n\t\t}\n\t\tif (!config.password) {\n\t\t\treturn { ok: false, code: \"PASSWORD_REQUIRED\" };\n\t\t}\n\t\ttry {\n\t\t\tawait new WebUntisClient(config, this.fetchImpl, undefined, this.onDiagnostic).authenticate(\n\t\t\t\tconfig.username,\n\t\t\t\tconfig.password,\n\t\t\t);\n\t\t\treturn { ok: true };\n\t\t} catch (error) {\n\t\t\treturn { ok: false, code: classifyWebUntisError(error) };\n\t\t}\n\t}\n}\n\nexport { WebUntisError };\nexport type * from \"./WebUntisTypes\";\n"],
5
+ "mappings": "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",
6
+ "names": ["periods", "_a"]
7
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var WebUntisTypes_exports = {};
16
+ module.exports = __toCommonJS(WebUntisTypes_exports);
17
+ //# sourceMappingURL=WebUntisTypes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/webuntis/WebUntisTypes.ts"],
4
+ "sourcesContent": ["/* eslint-disable jsdoc/no-blank-blocks, jsdoc/require-jsdoc */\n\nexport interface SchoolSearchResult {\n\t/**\n\t *\n\t */\n\tdisplayName: string;\n\t/**\n\t *\n\t */\n\taddress: string;\n\t/**\n\t *\n\t */\n\tloginName: string;\n\t/**\n\t *\n\t */\n\tschoolId: number;\n\t/**\n\t *\n\t */\n\tserver: string;\n\t/**\n\t *\n\t */\n\tserverUrl: string;\n\t/**\n\t *\n\t */\n\tmobileServiceUrl: string | null;\n}\n\n/**\n *\n */\nexport interface WebUntisSchoolConfig {\n\t/**\n\t *\n\t */\n\tserver: string;\n\t/**\n\t *\n\t */\n\tschoolName: string;\n\t/**\n\t *\n\t */\n\tschoolDisplayName: string;\n\t/**\n\t *\n\t */\n\tschoolAddress: string;\n\t/**\n\t *\n\t */\n\tschoolId: number | null;\n}\n\n/**\n *\n */\nexport interface WebUntisConnectionConfig extends WebUntisSchoolConfig {\n\t/**\n\t *\n\t */\n\tusername: string;\n\t/**\n\t *\n\t */\n\tpassword: string;\n}\n\nexport type ConnectionResult =\n\t| {\n\t\t\tok: true;\n\t }\n\t| {\n\t\t\tok: false;\n\t\t\t/**\n\t\t\t *\n\t\t\t */\n\t\t\tcode: WebUntisErrorCode;\n\t };\n\nexport type WebUntisErrorCode =\n\t| \"INVALID_CONFIG\"\n\t| \"SCHOOL_NOT_SELECTED\"\n\t| \"USERNAME_REQUIRED\"\n\t| \"PASSWORD_REQUIRED\"\n\t| \"INVALID_CREDENTIALS\"\n\t| \"USER_BLOCKED\"\n\t| \"INVALID_SCHOOL\"\n\t| \"SERVER_UNREACHABLE\"\n\t| \"TIMEOUT\"\n\t| \"UNSUPPORTED_LOGIN\"\n\t| \"INVALID_RESPONSE\"\n\t| \"HTML_RESPONSE\"\n\t| \"REDIRECTED\"\n\t| \"SESSION_EXPIRED\"\n\t| \"API_REQUEST\"\n\t| \"UNEXPECTED_RESPONSE\";\n\nexport interface WebUntisHttpDiagnostic {\n\tmethod?: string;\n\tstatus: number;\n\tcontentType: string;\n\turl: string;\n\tredirected: boolean;\n\tlength: number;\n\ttype: \"json\" | \"html\" | \"text\" | \"empty\";\n\tkeys?: string[];\n\terrorKeys?: string[];\n\terrorCode?: number;\n\terrorMessage?: string;\n\tcookiePresent?: boolean;\n\tcookieChanged?: boolean;\n\tsessionCookieChanged?: boolean;\n\tcookieCount?: number;\n\tsessionAgeSeconds?: number;\n\tsessionPresent?: boolean;\n\trequestSequence?: number;\n\tpersonIdPresent?: boolean;\n\tresponseHeaders?: string[];\n\tpersonType?: number;\n\tklasseIdPresent?: boolean;\n\telementType?: number;\n\tstartDate?: number;\n\tendDate?: number;\n\tclassIdType?: string;\n\tclassIdPresent?: boolean;\n\tdataType?: string;\n\tdataKeys?: string[];\n\tclassCandidateCount?: number;\n\tpersonCandidate?: boolean;\n\tresultKeys?: string[];\n\tresultType?: \"array\" | \"object\" | \"primitive\" | \"missing\";\n\tresultLength?: number;\n}\n\n/**\n *\n */\nexport interface SchoolSearchResponse {\n\t/**\n\t *\n\t */\n\tsize: number;\n\t/**\n\t *\n\t */\n\tschools: unknown[];\n}\n\n/**\n *\n */\nexport interface AuthenticationResponse {\n\t/**\n\t *\n\t */\n\tsessionId: string;\n\t/**\n\t *\n\t */\n\tpersonType: number;\n\t/**\n\t *\n\t */\n\tpersonId: number;\n\t/**\n\t *\n\t */\n\tklasseId: number;\n}\n\nexport interface WebUntisSession extends AuthenticationResponse {\n\tsessionId: string;\n}\n\nexport interface WebUntisPeriod {\n\t[key: string]: unknown;\n}\n\nexport interface TimetableQuery {\n\tstartDate: number;\n\tendDate: number;\n\telement: {\n\t\tid: number;\n\t\ttype: number;\n\t};\n\tonlyBaseTimetable: boolean;\n\tshowBooking: boolean;\n\tshowInfo: boolean;\n\tshowSubstText: boolean;\n\tshowLsText: boolean;\n\tshowLsNumber: boolean;\n\tshowStudentgroup: boolean;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
+ "names": []
7
+ }