From 3291a78d2b4b865836807d5a5b5bd96c25107994 Mon Sep 17 00:00:00 2001 From: imperosol Date: Mon, 13 Jul 2026 08:53:12 +0200 Subject: [PATCH 1/4] split `node` and `bundled` TS config --- tsconfig.bundled.json | 26 ++++++++++++++++++++++++++ tsconfig.json | 26 ++++---------------------- tsconfig.node.json | 10 ++++++++++ 3 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 tsconfig.bundled.json create mode 100644 tsconfig.node.json diff --git a/tsconfig.bundled.json b/tsconfig.bundled.json new file mode 100644 index 00000000..85f12b34 --- /dev/null +++ b/tsconfig.bundled.json @@ -0,0 +1,26 @@ +{ + "exclude": ["./staticfiles/generated/*", "vite.config.mts", "node_modules/*"], + "compilerOptions": { + "outDir": "./staticfiles/generated/bundled/", + "sourceMap": true, + "noImplicitAny": true, + "module": "esnext", + "target": "es2024", + "allowJs": true, + "moduleResolution": "node", + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "composite": true, + "types": ["alpinejs"], + "paths": { + "#openapi": ["./staticfiles/generated/openapi/client/index.ts"], + "#openapi:*": ["./staticfiles/generated/openapi/client/*"], + "#core:*": ["./core/static/bundled/*"], + "#pedagogy:*": ["./pedagogy/static/bundled/*"], + "#counter:*": ["./counter/static/bundled/*"], + "#com:*": ["./com/static/bundled/*"] + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 25b3cd17..7e438255 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,24 +1,6 @@ { - "compilerOptions": { - "outDir": "./staticfiles/generated/bundled/", - "sourceMap": true, - "noImplicitAny": true, - "module": "esnext", - "target": "es2024", - "allowJs": true, - "moduleResolution": "node", - "experimentalDecorators": true, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "types": ["alpinejs"], - "paths": { - "#openapi": ["./staticfiles/generated/openapi/client/index.ts"], - "#openapi:*": ["./staticfiles/generated/openapi/client/*"], - "#core:*": ["./core/static/bundled/*"], - "#pedagogy:*": ["./pedagogy/static/bundled/*"], - "#counter:*": ["./counter/static/bundled/*"], - "#com:*": ["./com/static/bundled/*"] - } - } + "references": [ + {"path": "tsconfig.bundled.json"}, + {"path": "tsconfig.node.json"} + ], } diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 00000000..e24febd8 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "include": ["vite.config.*"], + "compilerOptions": { + "module": "preserve", + "moduleResolution": "bundler", + "types": ["node"], + "emitDeclarationOnly": true, + "composite": true + } +} From 236860d0f54a0067d4aa4c0ba2c837cb34d88132 Mon Sep 17 00:00:00 2001 From: imperosol Date: Mon, 13 Jul 2026 11:51:02 +0200 Subject: [PATCH 2/4] adapt typescript to strict mode --- .../club/components/ajax-select-index.ts | 9 +- .../com/components/ics-calendar-index.ts | 43 ++++--- .../bundled/com/moderation-alert-index.ts | 10 +- .../bundled/com/upcoming-news-loader-index.ts | 11 +- core/api.py | 5 +- core/schemas.py | 10 ++ core/static/bundled/alpine/limited-choices.ts | 4 +- core/static/bundled/base-bundle-index.ts | 18 ++- .../core/components/ajax-select-base.ts | 16 +-- .../core/components/ajax-select-index.ts | 9 +- .../bundled/core/components/easymde-index.ts | 34 +++--- .../bundled/core/components/include-index.ts | 8 +- .../core/components/nfc-input-index.ts | 8 +- .../bundled/core/components/tabs-index.ts | 10 +- .../bundled/core/dynamic-formset-index.ts | 14 ++- core/static/bundled/core/navbar.ts | 9 +- core/static/bundled/core/read-more-index.ts | 1 + core/static/bundled/core/tooltips-index.ts | 15 +-- .../static/bundled/user/family-graph-index.ts | 41 +++---- core/static/bundled/utils/alert-message.ts | 4 +- core/static/bundled/utils/api.ts | 13 ++- core/static/bundled/utils/csv.ts | 21 ++-- core/static/bundled/utils/web-components.ts | 5 +- .../counter/components/ajax-select-index.ts | 20 ++-- .../counter-product-select-index.ts | 9 +- .../bundled/counter/product-list-index.ts | 37 ++++-- .../bundled/counter/product-type-index.ts | 8 +- .../static/bundled/eboutic/checkout-index.ts | 4 +- package-lock.json | 18 +++ package.json | 1 + sas/api.py | 6 +- .../sas/components/ajax-select-index.ts | 8 +- .../bundled/sas/pictures-download-index.ts | 7 +- sas/static/bundled/sas/user/pictures-index.ts | 18 +-- sas/static/bundled/sas/viewer-index.ts | 107 ++++++++++++------ .../creation-form-existing-user-index.ts | 13 ++- .../bundled/subscription/stats-index.ts | 37 +++--- .../bundled/timetable/generator-index.ts | 4 +- tsconfig.bundled.json | 5 +- vite.config.mts | 8 +- 40 files changed, 386 insertions(+), 242 deletions(-) diff --git a/club/static/bundled/club/components/ajax-select-index.ts b/club/static/bundled/club/components/ajax-select-index.ts index 56c93760..9515b6f0 100644 --- a/club/static/bundled/club/components/ajax-select-index.ts +++ b/club/static/bundled/club/components/ajax-select-index.ts @@ -1,7 +1,6 @@ -import type { TomOption } from "tom-select/dist/types/types"; -import type { escape_html } from "tom-select/dist/types/utils"; -import { AjaxSelect } from "#core:core/components/ajax-select-base.ts"; -import { registerComponent } from "#core:utils/web-components.ts"; +import type { escape_html } from "tom-select/src/utils"; +import { AjaxSelect } from "#core:core/components/ajax-select-base"; +import { registerComponent } from "#core:utils/web-components"; import { type ClubSchema, clubSearchClub } from "#openapi"; @registerComponent("club-ajax-select") @@ -10,7 +9,7 @@ export class ClubAjaxSelect extends AjaxSelect { protected labelField = "name"; protected searchField = ["code", "name"]; - protected async search(query: string): Promise { + protected async search(query: string) { const resp = await clubSearchClub({ query: { search: query } }); if (resp.data) { return resp.data.results; diff --git a/com/static/bundled/com/components/ics-calendar-index.ts b/com/static/bundled/com/components/ics-calendar-index.ts index 8eb159c1..04a46ae2 100644 --- a/com/static/bundled/com/components/ics-calendar-index.ts +++ b/com/static/bundled/com/components/ics-calendar-index.ts @@ -1,4 +1,9 @@ -import { Calendar, type EventClickArg, type EventContentArg } from "@fullcalendar/core"; +import { + Calendar, + type EventClickArg, + type EventContentArg, + type EventInput, +} from "@fullcalendar/core"; import type { EventImpl } from "@fullcalendar/core/internal"; import enLocale from "@fullcalendar/core/locales/en-gb"; import frLocale from "@fullcalendar/core/locales/fr"; @@ -6,8 +11,8 @@ import dayGridPlugin from "@fullcalendar/daygrid"; import iCalendarPlugin from "@fullcalendar/icalendar"; import listPlugin from "@fullcalendar/list"; import { type HTMLTemplateResult, html, render } from "lit-html"; -import { makeUrl } from "#core:utils/api.ts"; -import { inheritHtmlElement, registerComponent } from "#core:utils/web-components.ts"; +import { type GenericEndpoint, makeUrl } from "#core:utils/api"; +import { inheritHtmlElement, registerComponent } from "#core:utils/web-components"; import { calendarCalendarInternal, calendarCalendarUnpublished, @@ -19,11 +24,11 @@ import { @registerComponent("ics-calendar") export class IcsCalendar extends inheritHtmlElement("div") { static observedAttributes = ["locale", "can_moderate", "can_delete", "ics-help-url"]; - private calendar: Calendar; - private locale = "en"; - private canModerate = false; - private canDelete = false; - private helpUrl = ""; + private calendar!: Calendar; + private locale? = "en"; + private canModerate? = false; + private canDelete? = false; + private helpUrl? = ""; // Hack variable to detect recurring events // The underlying ics library doesn't include any info about rrules @@ -35,10 +40,12 @@ export class IcsCalendar extends inheritHtmlElement("div") { this.locale = newValue; } if (name === "can_moderate") { - this.canModerate = newValue.toLowerCase() === "true"; + this.canModerate = + typeof newValue === "string" && newValue.toLowerCase() === "true"; } if (name === "can_delete") { - this.canDelete = newValue.toLowerCase() === "true"; + this.canDelete = + typeof newValue === "string" && newValue.toLowerCase() === "true"; } if (name === "ics-help-url") { @@ -94,7 +101,7 @@ export class IcsCalendar extends inheritHtmlElement("div") { .toString() .split("/") .filter((s) => s) // Remove blank characters - .pop(), + .pop() as string, 10, ); } @@ -159,7 +166,7 @@ export class IcsCalendar extends inheritHtmlElement("div") { this.refreshEvents(); } - async getEventSources() { + async getEventSources(): Promise { const tagRecurringEvents = (eventData: EventImpl) => { // This functions tags events with a similar event url // We rely on the fact that the event url is always the same @@ -173,14 +180,14 @@ export class IcsCalendar extends inheritHtmlElement("div") { }; return [ { - url: `${await makeUrl(calendarCalendarInternal)}`, + url: `${await makeUrl(calendarCalendarInternal as GenericEndpoint)}`, format: "ics", className: "internal", cache: false, eventDataTransform: tagRecurringEvents, }, { - url: `${await makeUrl(calendarCalendarUnpublished)}`, + url: `${await makeUrl(calendarCalendarUnpublished as GenericEndpoint)}`, format: "ics", color: "red", className: "unpublished", @@ -213,7 +220,7 @@ export class IcsCalendar extends inheritHtmlElement("div") { ${event.title} - ${this.formatDate(event.start)} - ${this.formatDate(event.end)} + ${this.formatDate(event.start as Date)} - ${this.formatDate(event.end as Date)} `; @@ -251,7 +258,7 @@ export class IcsCalendar extends inheritHtmlElement("div") { const buttons = [] as HTMLTemplateResult[]; if (this.canModerate) { - if (event.source.internalEventSource.ui.classNames.includes("unpublished")) { + if (event.source?.internalEventSource.ui.classNames.includes("unpublished")) { const button = html`