From f55d8a9c2ebbc612775d66b1f073605fb9e151f3 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:37:43 +0100 Subject: [PATCH] fix(deps): update dependency next-intl to v4 (#2580) * fix(deps): update dependency next-intl to v4 * fix: typecheck issue * refactor: implement improvements for next-intl v4 * fix: typecheck issues * fix: typecheck issue --------- Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> Co-authored-by: Meier Lukas --- .gitignore | 3 ++ apps/nextjs/next.config.ts | 7 +++- .../app/[locale]/auth/invite/[id]/page.tsx | 3 +- apps/nextjs/src/app/[locale]/layout.tsx | 4 +-- .../src/app/[locale]/manage/about/page.tsx | 6 ++-- .../manage/apps/_app-delete-button.tsx | 4 ++- .../_search-engine-delete-button.tsx | 4 ++- .../manage/tools/docker/docker-table.tsx | 6 ++-- .../configmaps/configmaps-table.tsx | 2 +- .../kubernetes/ingresses/ingresses-table.tsx | 2 +- .../namespaces/namespaces-table.tsx | 2 +- .../tools/kubernetes/nodes/nodes-table.tsx | 2 +- .../tools/kubernetes/pods/pods-table.tsx | 2 +- .../kubernetes/secrets/secrets-table.tsx | 2 +- .../kubernetes/services/services-table.tsx | 2 +- .../kubernetes/volumes/volumes-table.tsx | 2 +- .../_components/_delete-user-button.tsx | 3 +- .../manage/users/[userId]/general/page.tsx | 3 +- .../src/components/user-avatar-menu.tsx | 5 ++- .../src/icon-picker/icon-picker.tsx | 2 +- .../initial/board-selection-card.tsx | 2 +- packages/translation/package.json | 2 +- packages/translation/src/client/index.ts | 12 +++++-- .../src/client/use-current-locale.ts | 4 +-- packages/translation/src/lang/en.json | 2 +- packages/translation/src/request.ts | 2 +- packages/translation/src/routing.ts | 2 ++ packages/translation/src/server.ts | 10 ++++++ packages/validation/src/form/i18n.ts | 3 +- .../src/_inputs/widget-location-input.tsx | 2 +- .../src/health-monitoring/system-health.tsx | 14 +++++--- .../src/media-transcoding/component.tsx | 6 ++-- packages/widgets/src/notebook/notebook.tsx | 8 ++--- packages/widgets/src/weather/component.tsx | 2 +- packages/widgets/src/weather/icon.tsx | 12 +++++-- pnpm-lock.yaml | 34 +++++++++++++------ tooling/typescript/base.json | 20 +++-------- 37 files changed, 127 insertions(+), 76 deletions(-) diff --git a/.gitignore b/.gitignore index 76c8f08fc..0aa3ed4c7 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,6 @@ e2e/shared/tmp #personal backgrounds apps/nextjs/public/images/background.png + +# next-intl +en.d.json.ts \ No newline at end of file diff --git a/apps/nextjs/next.config.ts b/apps/nextjs/next.config.ts index a8a022a60..d88dac644 100644 --- a/apps/nextjs/next.config.ts +++ b/apps/nextjs/next.config.ts @@ -10,7 +10,12 @@ import MillionLint from "@million/lint"; import createNextIntlPlugin from "next-intl/plugin"; // Package path does not work... so we need to use relative path -const withNextIntl = createNextIntlPlugin("../../packages/translation/src/request.ts"); +const withNextIntl = createNextIntlPlugin({ + experimental: { + createMessagesDeclaration: "../../packages/translation/src/lang/en.json", + }, + requestConfig: "../../packages/translation/src/request.ts", +}); interface WebpackConfig { module: { diff --git a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx index 7de11ff0f..cc6535703 100644 --- a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx +++ b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx @@ -63,7 +63,8 @@ export default async function InviteUsagePage(props: InviteUsagePageProps) { - {t("description", { username: invite.creator.name })} + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {t("description", { username: invite.creator.name! })} diff --git a/apps/nextjs/src/app/[locale]/layout.tsx b/apps/nextjs/src/app/[locale]/layout.tsx index b988647bc..5fbd3c3f7 100644 --- a/apps/nextjs/src/app/[locale]/layout.tsx +++ b/apps/nextjs/src/app/[locale]/layout.tsx @@ -20,7 +20,6 @@ import { SettingsProvider } from "@homarr/settings"; import { SpotlightProvider } from "@homarr/spotlight"; import type { SupportedLanguage } from "@homarr/translation"; import { isLocaleRTL, isLocaleSupported } from "@homarr/translation"; -import { getI18nMessages } from "@homarr/translation/server"; import { Analytics } from "~/components/layout/analytics"; import { SearchEngineOptimization } from "~/components/layout/search-engine-optimization"; @@ -81,7 +80,6 @@ export default async function Layout(props: { const serverSettings = await getServerSettingsAsync(db); const colorScheme = await getCurrentColorSchemeAsync(); const direction = isLocaleRTL((await props.params).locale) ? "rtl" : "ltr"; - const i18nMessages = await getI18nMessages(); const StackedProvider = composeWrappers([ (innerProps) => { @@ -105,7 +103,7 @@ export default async function Layout(props: { (innerProps) => , (innerProps) => , (innerProps) => , - (innerProps) => , + (innerProps) => , (innerProps) => , (innerProps) => , (innerProps) => , diff --git a/apps/nextjs/src/app/[locale]/manage/about/page.tsx b/apps/nextjs/src/app/[locale]/manage/about/page.tsx index 024267be2..ece275534 100644 --- a/apps/nextjs/src/app/[locale]/manage/about/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/about/page.tsx @@ -80,7 +80,7 @@ export default async function AboutPage() { {t("accordion.contributors.title")} {t("accordion.contributors.subtitle", { - count: githubContributors.length, + count: String(githubContributors.length), })} @@ -104,7 +104,7 @@ export default async function AboutPage() { {t("accordion.translators.title")} {t("accordion.translators.subtitle", { - count: crowdinContributors.length, + count: String(crowdinContributors.length), })} @@ -128,7 +128,7 @@ export default async function AboutPage() { {t("accordion.libraries.title")} {t("accordion.libraries.subtitle", { - count: Object.keys(attributes.dependencies).length, + count: String(Object.keys(attributes.dependencies).length), })} diff --git a/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx b/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx index bdc520579..2fb1dce56 100644 --- a/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx +++ b/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx @@ -23,7 +23,9 @@ export const AppDeleteButton = ({ app }: AppDeleteButtonProps) => { const onClick = useCallback(() => { openConfirmModal({ title: t("title"), - children: t("message", app), + children: t("message", { + name: app.name, + }), onConfirm: () => { mutate( { id: app.id }, diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx index b8df69619..6857c4714 100644 --- a/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx +++ b/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx @@ -23,7 +23,9 @@ export const SearchEngineDeleteButton = ({ searchEngine }: SearchEngineDeleteBut const onClick = useCallback(() => { openConfirmModal({ title: t("title"), - children: t("message", searchEngine), + children: t("message", { + name: searchEngine.name, + }), onConfirm: () => { mutate( { id: searchEngine.id }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx index b2478d5d9..e94d2be6a 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx @@ -104,7 +104,7 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers" enableBottomToolbar: false, positionGlobalFilter: "right", mantineSearchTextInputProps: { - placeholder: tDocker("table.search", { count: data.containers.length }), + placeholder: tDocker("table.search", { count: String(data.containers.length) }), style: { minWidth: 300 }, autoFocus: true, }, @@ -146,8 +146,8 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers" {groupedAlert} {tDocker("table.selected", { - selectCount: table.getSelectedRowModel().rows.length, - totalCount: table.getRowCount(), + selectCount: String(table.getSelectedRowModel().rows.length), + totalCount: String(table.getRowCount()), })} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx index ac144ee15..9723171eb 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx @@ -62,7 +62,7 @@ export function ConfigmapsTable(initialData: ConfigMapsTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tConfigMaps("table.search", { count: data.length }), + placeholder: tConfigMaps("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx index e53e492eb..fbb250806 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx @@ -95,7 +95,7 @@ export function IngressesTable(initialData: IngressesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tIngresses("table.search", { count: data.length }), + placeholder: tIngresses("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx index 9ef0e4a5b..2486a4ad0 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx @@ -79,7 +79,7 @@ export function NamespacesTable(initialData: NamespacesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tNamespaces("table.search", { count: data.length }), + placeholder: tNamespaces("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx index b7b17d984..2fc69d51f 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx @@ -105,7 +105,7 @@ export function NodesTable(initialData: NodesListComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tNodes("table.search", { count: data.length }), + placeholder: tNodes("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx index 3a1e10820..dd600b387 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx @@ -70,7 +70,7 @@ export function PodsTable(initialData: PodsTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true, expanded: true }, mantineSearchTextInputProps: { - placeholder: tPods("table.search", { count: data.length }), + placeholder: tPods("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx index 3c24ad0f1..d0a902f22 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx @@ -65,7 +65,7 @@ export function SecretsTable(initialData: SecretsTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tSecrets("table.search", { count: data.length }), + placeholder: tSecrets("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx index 7e13a630a..04a2924d7 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx @@ -84,7 +84,7 @@ export function ServicesTable(initialData: ServicesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tServices("table.search", { count: data.length }), + placeholder: tServices("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx index be217d314..e911ee7a6 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx @@ -89,7 +89,7 @@ export function VolumesTable(initialData: VolumesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tVolumes("table.search", { count: data.length }), + placeholder: tVolumes("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx index ebaf1b0cb..0b93f2388 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx @@ -28,7 +28,8 @@ export const DeleteUserButton = ({ user }: DeleteUserButtonProps) => { () => openConfirmModal({ title: t("user.action.delete.label"), - children: t("user.action.delete.confirm", { username: user.name }), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + children: t("user.action.delete.confirm", { username: user.name! }), // eslint-disable-next-line no-restricted-syntax async onConfirm() { await mutateUserDeletionAsync({ diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx index 48a2e8aa3..add232243 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx @@ -41,7 +41,8 @@ export async function generateMetadata(props: Props) { const t = await getScopedI18n("management.page.user.edit"); return { - title: createMetaTitle(t("metaTitle", { username: user.name })), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + title: createMetaTitle(t("metaTitle", { username: user.name! })), }; } diff --git a/apps/nextjs/src/components/user-avatar-menu.tsx b/apps/nextjs/src/components/user-avatar-menu.tsx index d7a53f901..cc676ee09 100644 --- a/apps/nextjs/src/components/user-avatar-menu.tsx +++ b/apps/nextjs/src/components/user-avatar-menu.tsx @@ -74,7 +74,10 @@ export const UserAvatarMenu = ({ children, availableUpdates }: UserAvatarMenuPro leftSection={} > - {t("updateAvailable", { countUpdates: availableUpdates.length, tag: availableUpdates[0].tagName })} + {t("updateAvailable", { + countUpdates: String(availableUpdates.length), + tag: availableUpdates[0].tagName, + })} diff --git a/packages/forms-collection/src/icon-picker/icon-picker.tsx b/packages/forms-collection/src/icon-picker/icon-picker.tsx index d3abda661..9dbfb55f7 100644 --- a/packages/forms-collection/src/icon-picker/icon-picker.tsx +++ b/packages/forms-collection/src/icon-picker/icon-picker.tsx @@ -148,7 +148,7 @@ export const IconPicker = ({ value: propsValue, onChange, error, onFocus, onBlur withAsterisk error={error} label={tCommon("iconPicker.label")} - placeholder={tCommon("iconPicker.header", { countIcons: data?.countIcons ?? 0 })} + placeholder={tCommon("iconPicker.header", { countIcons: String(data?.countIcons ?? 0) })} /> {session?.user.permissions.includes("media-upload") && ( - {tBoardSelection("title", { count: selections.size })} + {tBoardSelection("title", { count: String(selections.size) })} {areAllChecked ? tBoardSelection("action.unselectAll") : tBoardSelection("action.selectAll")} diff --git a/packages/translation/package.json b/packages/translation/package.json index 45c65045d..461ddde18 100644 --- a/packages/translation/package.json +++ b/packages/translation/package.json @@ -33,7 +33,7 @@ "deepmerge": "4.3.1", "mantine-react-table": "2.0.0-beta.9", "next": "15.1.7", - "next-intl": "3.26.5", + "next-intl": "4.0.0", "react": "19.0.0", "react-dom": "19.0.0" }, diff --git a/packages/translation/src/client/index.ts b/packages/translation/src/client/index.ts index 16d73330b..5c6755883 100644 --- a/packages/translation/src/client/index.ts +++ b/packages/translation/src/client/index.ts @@ -2,18 +2,26 @@ import { useMessages, useTranslations } from "next-intl"; -import type { TranslationObject } from "../type"; +import type { SupportedLanguage } from "../config"; +import type englishTranslation from "../lang/en.json"; export { useChangeLocale } from "./use-change-locale"; export { useCurrentLocale } from "./use-current-locale"; +declare module "next-intl" { + interface AppConfig { + Messages: typeof englishTranslation; + Locale: SupportedLanguage; + } +} + export const { useI18n, useScopedI18n } = { useI18n: useTranslations, useScopedI18n: useTranslations, }; export const { useI18nMessages } = { - useI18nMessages: () => useMessages() as TranslationObject, + useI18nMessages: () => useMessages(), }; export { useTranslations }; diff --git a/packages/translation/src/client/use-current-locale.ts b/packages/translation/src/client/use-current-locale.ts index f05eff7e5..a0e796010 100644 --- a/packages/translation/src/client/use-current-locale.ts +++ b/packages/translation/src/client/use-current-locale.ts @@ -1,5 +1,3 @@ import { useLocale } from "next-intl"; -import type { SupportedLanguage } from "../config"; - -export const useCurrentLocale = () => useLocale() as SupportedLanguage; +export const useCurrentLocale = useLocale; diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 320abee21..57eca7c72 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -3594,7 +3594,7 @@ }, "delete": { "title": "Delete search engine", - "message": "Are you sure you want to delete the search engine '{name}'?", + "message": "Are you sure you want to delete the search engine {name}?", "notification": { "success": { "title": "Search engine deleted", diff --git a/packages/translation/src/request.ts b/packages/translation/src/request.ts index 9b901d2ba..1d680e50b 100644 --- a/packages/translation/src/request.ts +++ b/packages/translation/src/request.ts @@ -22,7 +22,7 @@ export default getRequestConfig(async ({ requestLocale }) => { if (currentLocale !== fallbackLocale) { const fallbackMessages = (await languageMap[fallbackLocale]()).default; return { - locale: currentLocale, + locale: typedLocale, messages: deepmerge(fallbackMessages, currentMessages), }; } diff --git a/packages/translation/src/routing.ts b/packages/translation/src/routing.ts index db81f0228..e6f268690 100644 --- a/packages/translation/src/routing.ts +++ b/packages/translation/src/routing.ts @@ -11,6 +11,8 @@ export const createRouting = (defaultLocale: SupportedLanguage) => defaultLocale, localeCookie: { name: localeCookieKey, + // 1 year + maxAge: 60 * 60 * 24 * 365, }, localePrefix: { mode: "never", // Rewrite the URL with locale parameter but without shown in url diff --git a/packages/translation/src/server.ts b/packages/translation/src/server.ts index bfab90719..ebcc6442b 100644 --- a/packages/translation/src/server.ts +++ b/packages/translation/src/server.ts @@ -1,5 +1,15 @@ import { getTranslations } from "next-intl/server"; +import type { SupportedLanguage } from "./config"; +import type englishTranslation from "./lang/en.json"; + +declare module "next-intl" { + interface AppConfig { + Messages: typeof englishTranslation; + Locale: SupportedLanguage; + } +} + export const { getI18n, getScopedI18n } = { getI18n: getTranslations, getScopedI18n: getTranslations, diff --git a/packages/validation/src/form/i18n.ts b/packages/validation/src/form/i18n.ts index db53d1e95..e1f01041a 100644 --- a/packages/validation/src/form/i18n.ts +++ b/packages/validation/src/form/i18n.ts @@ -12,7 +12,8 @@ export const zodErrorMap = (t: TFunction) }; } return { - message: t(error.key ? `common.zod.${error.key}` : "common.zod.errors.default", error.params ?? {}), + // use never to make ts happy + message: t(error.key ? `common.zod.${error.key}` : "common.zod.errors.default", (error.params ?? {}) as never), }; }; }; diff --git a/packages/widgets/src/_inputs/widget-location-input.tsx b/packages/widgets/src/_inputs/widget-location-input.tsx index a27be85cb..37d26cf2e 100644 --- a/packages/widgets/src/_inputs/widget-location-input.tsx +++ b/packages/widgets/src/_inputs/widget-location-input.tsx @@ -224,7 +224,7 @@ const LocationSelectTableRow = ({ city, onLocationSelect, closeModal }: Location diff --git a/packages/widgets/src/health-monitoring/system-health.tsx b/packages/widgets/src/health-monitoring/system-health.tsx index e2f064ebd..6e4aa2ed4 100644 --- a/packages/widgets/src/health-monitoring/system-health.tsx +++ b/packages/widgets/src/health-monitoring/system-health.tsx @@ -140,7 +140,7 @@ export const SystemHealthMonitoring = ({ }> {t("widget.healthMonitoring.popover.memoryAvailable", { memoryAvailable: memoryUsage.memFree.GB, - percent: memoryUsage.memFree.percent, + percent: String(memoryUsage.memFree.percent), })} }> @@ -159,10 +159,11 @@ export const SystemHealthMonitoring = ({ {t("widget.healthMonitoring.popover.minute")} {healthInfo.loadAverage["1min"]}% - {t("widget.healthMonitoring.popover.minutes", { count: 5 })} {healthInfo.loadAverage["5min"]}% + {t("widget.healthMonitoring.popover.minutes", { count: "5" })} {healthInfo.loadAverage["5min"]}% - {t("widget.healthMonitoring.popover.minutes", { count: 15 })} {healthInfo.loadAverage["15min"]}% + {t("widget.healthMonitoring.popover.minutes", { count: "15" })}{" "} + {healthInfo.loadAverage["15min"]}% @@ -274,7 +275,12 @@ export const formatUptime = (uptimeInSeconds: number, t: TranslationFunction) => const hours = uptimeDuration.hours(); const minutes = uptimeDuration.minutes(); - return t("widget.healthMonitoring.popover.uptime", { months, days, hours, minutes }); + return t("widget.healthMonitoring.popover.uptime", { + months: String(months), + days: String(days), + hours: String(hours), + minutes: String(minutes), + }); }; export const progressColor = (percentage: number) => { diff --git a/packages/widgets/src/media-transcoding/component.tsx b/packages/widgets/src/media-transcoding/component.tsx index cad468681..d66da98e6 100644 --- a/packages/widgets/src/media-transcoding/component.tsx +++ b/packages/widgets/src/media-transcoding/component.tsx @@ -95,9 +95,9 @@ export default function MediaTranscodingWidget({ {t("currentIndex", { - start: transcodingData.data.queue.startIndex + 1, - end: transcodingData.data.queue.endIndex + 1, - total: transcodingData.data.queue.totalCount, + start: String(transcodingData.data.queue.startIndex + 1), + end: String(transcodingData.data.queue.endIndex + 1), + total: String(transcodingData.data.queue.totalCount), })} diff --git a/packages/widgets/src/notebook/notebook.tsx b/packages/widgets/src/notebook/notebook.tsx index 257dcfc50..a30048427 100644 --- a/packages/widgets/src/notebook/notebook.tsx +++ b/packages/widgets/src/notebook/notebook.tsx @@ -280,10 +280,10 @@ export function Notebook({ options, isEditMode, boardId, itemId }: WidgetCompone - - - - + + + + diff --git a/packages/widgets/src/weather/component.tsx b/packages/widgets/src/weather/component.tsx index fb1fecdc9..88df5cce5 100644 --- a/packages/widgets/src/weather/component.tsx +++ b/packages/widgets/src/weather/component.tsx @@ -75,7 +75,7 @@ const DailyWeather = ({ options, weather }: WeatherProps) => { {options.showCurrentWindSpeed && ( - {t("currentWindSpeed", { currentWindSpeed: weather.current.windspeed })} + {t("currentWindSpeed", { currentWindSpeed: String(weather.current.windspeed) })} )} diff --git a/packages/widgets/src/weather/icon.tsx b/packages/widgets/src/weather/icon.tsx index f93eba241..17e9c03c5 100644 --- a/packages/widgets/src/weather/icon.tsx +++ b/packages/widgets/src/weather/icon.tsx @@ -94,8 +94,16 @@ export const WeatherDescription = ({ }>{`${tCommon("information.min")}: ${minTemp}`} }>{`${t("dailyForecast.sunrise")}: ${sunrise}`} }>{`${t("dailyForecast.sunset")}: ${sunset}`} - }>{t("dailyForecast.maxWindSpeed", { maxWindSpeed })} - }>{t("dailyForecast.maxWindGusts", { maxWindGusts })} + {maxWindSpeed !== undefined && ( + }> + {t("dailyForecast.maxWindSpeed", { maxWindSpeed: String(maxWindSpeed) })} + + )} + {maxWindGusts !== undefined && ( + }> + {t("dailyForecast.maxWindGusts", { maxWindGusts: String(maxWindGusts) })} + + )} ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 935c447c3..7ca1e920c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1893,8 +1893,8 @@ importers: specifier: 15.1.7 version: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) next-intl: - specifier: 3.26.5 - version: 3.26.5(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0) + specifier: 4.0.0 + version: 4.0.0(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2) react: specifier: 19.0.0 version: 19.0.0 @@ -4081,6 +4081,9 @@ packages: '@scarf/scarf@1.4.0': resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} + '@schummar/icu-type-parser@1.21.5': + resolution: {integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==} + '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -7850,11 +7853,15 @@ packages: nodemailer: optional: true - next-intl@3.26.5: - resolution: {integrity: sha512-EQlCIfY0jOhRldiFxwSXG+ImwkQtDEfQeSOEQp6ieAGSLWGlgjdb/Ck/O7wMfC430ZHGeUKVKax8KGusTPKCgg==} + next-intl@4.0.0: + resolution: {integrity: sha512-l+I1PLAFrjzYzrc340n1vssDJ7pP1gtYT1jOWlRWIHkyrPdyosEIHPC+LiqJP4vWvWtCZzzqTn9AaBF+x5Ja8g==} peerDependencies: - next: ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 + next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true next@15.1.7: resolution: {integrity: sha512-GNeINPGS9c6OZKCvKypbL8GTsT5GhWPp4DM0fzkXJuXMilOO2EeFxuAY6JZbtk6XIl6Ws10ag3xRINDjSO5+wg==} @@ -9977,10 +9984,10 @@ packages: peerDependencies: react: '>=16.13' - use-intl@3.26.5: - resolution: {integrity: sha512-OdsJnC/znPvHCHLQH/duvQNXnP1w0hPfS+tkSi3mAbfjYBGh4JnyfdwkQBfIVf7t8gs9eSX/CntxUMvtKdG2MQ==} + use-intl@4.0.0: + resolution: {integrity: sha512-/fmC7haEMVNa0isXGRGUir56fD4I9LRnOgbeBmji+bow6U8pE7WD+2X2sjqh+0h3yJ0T36PA6JXZ6PlVeRyt8w==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 use-isomorphic-layout-effect@1.1.2: resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} @@ -11995,6 +12002,8 @@ snapshots: '@scarf/scarf@1.4.0': {} + '@schummar/icu-type-parser@1.21.5': {} + '@sec-ant/readable-stream@0.4.1': {} '@semantic-release/changelog@6.0.3(semantic-release@24.2.3(typescript@5.8.2))': @@ -16501,13 +16510,15 @@ snapshots: next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - next-intl@3.26.5(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0): + next-intl@4.0.0(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2): dependencies: '@formatjs/intl-localematcher': 0.5.5 negotiator: 1.0.0 next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - use-intl: 3.26.5(react@19.0.0) + use-intl: 4.0.0(react@19.0.0) + optionalDependencies: + typescript: 5.8.2 next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1): dependencies: @@ -18934,9 +18945,10 @@ snapshots: dequal: 2.0.3 react: 19.0.0 - use-intl@3.26.5(react@19.0.0): + use-intl@4.0.0(react@19.0.0): dependencies: '@formatjs/fast-memoize': 2.2.1 + '@schummar/icu-type-parser': 1.21.5 intl-messageformat: 10.7.1 react: 19.0.0 diff --git a/tooling/typescript/base.json b/tooling/typescript/base.json index 37f6290fb..ae235642b 100644 --- a/tooling/typescript/base.json +++ b/tooling/typescript/base.json @@ -2,11 +2,7 @@ "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "target": "ES2022", - "lib": [ - "dom", - "dom.iterable", - "ES2022" - ], + "lib": ["dom", "dom.iterable", "ES2022"], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -15,6 +11,7 @@ "module": "esnext", "moduleResolution": "Bundler", "resolveJsonModule": true, + "allowArbitraryExtensions": true, "isolatedModules": true, "moduleDetection": "force", "jsx": "preserve", @@ -23,15 +20,8 @@ "strictNullChecks": true, "baseUrl": ".", "paths": { - "*": [ - "node_modules/*" - ] + "*": ["node_modules/*"] } }, - "exclude": [ - "node_modules", - "build", - "dist", - ".next" - ] -} \ No newline at end of file + "exclude": ["node_modules", "build", "dist", ".next"] +}