Update more web deps and reformat with updated prettier (#24358)

* update date-fns, i18next, react-dropzone, react-markdown and @types/node

react-i18next 17 peers `i18next >= 26.2.0`, so the two move together. react-day-picker already depends on date-fns 4, so date-fns now dedupes to a single copy. react-dropzone 20 declares `node >=22` in `engines`, but npm only warns on Node 20 and nothing in the build needs Node 22.

* update js-yaml, @hookform/resolvers and prettier

js-yaml 5 has no default export, so `DictAsYamlField` imports `dump`, `load` and `YAMLException` by name. @hookform/resolvers 5 types `zodResolver` with the schema's input and output types separately, and fields with defaults are optional on input, so the zone and classification model forms pass both types to `useForm`. zod's range now starts at 3.25, which resolvers 5 requires.

* format with prettier 3.9
This commit is contained in:
Josh Hawkins
2026-09-15 15:18:49 -06:00
committed by GitHub
parent ba41c90c07
commit cabdffea20
62 changed files with 588 additions and 574 deletions
@@ -1,5 +1,5 @@
import type { FieldPathList, FieldProps } from "@rjsf/utils";
import yaml from "js-yaml";
import { dump, load, YAMLException } from "js-yaml";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -16,7 +16,7 @@ function formatYaml(value: unknown): string {
return "";
}
try {
return yaml.dump(value, { indent: 2, lineWidth: -1 }).trimEnd();
return dump(value, { indent: 2, lineWidth: -1 }).trimEnd();
} catch {
return "";
}
@@ -31,7 +31,7 @@ function parseYaml(text: string): {
return { value: {}, error: undefined };
}
try {
const parsed = yaml.load(trimmed);
const parsed = load(trimmed);
if (
typeof parsed !== "object" ||
parsed === null ||
@@ -41,7 +41,7 @@ function parseYaml(text: string): {
}
return { value: parsed as Record<string, unknown>, error: undefined };
} catch (e) {
const msg = e instanceof yaml.YAMLException ? e.reason : "Invalid YAML";
const msg = e instanceof YAMLException ? e.reason : "Invalid YAML";
return { value: undefined, error: msg };
}
}
@@ -217,8 +217,7 @@ function PlateCombobox({
export function KnownPlatesField(props: FieldProps) {
const { schema, formData, onChange, idSchema, disabled, readonly } = props;
const formContext = props.registry?.formContext as
| ConfigFormContext
| undefined;
ConfigFormContext | undefined;
const configNamespace =
formContext?.i18nNamespace ??
@@ -159,8 +159,7 @@ function StreamValueCombobox({
export function LiveStreamsField(props: FieldProps) {
const { schema, formData, onChange, idSchema, disabled, readonly } = props;
const formContext = props.registry?.formContext as
| ConfigFormContext
| undefined;
ConfigFormContext | undefined;
const configNamespace =
formContext?.i18nNamespace ??
@@ -96,8 +96,7 @@ const getItemProperties = (
const getSceneOptions = (itemSchema: RJSFSchema | undefined): string[] => {
const scene = getItemProperties(itemSchema).scene as
| Record<string, unknown>
| undefined;
Record<string, unknown> | undefined;
const values = scene?.enum;
return Array.isArray(values)
@@ -44,8 +44,7 @@ function getPropertyTitle(itemSchema: RJSFSchema | undefined, key: string) {
export function ReplaceRulesField(props: FieldProps) {
const { schema, formData, onChange, idSchema, disabled, readonly } = props;
const formContext = props.registry?.formContext as
| ConfigFormContext
| undefined;
ConfigFormContext | undefined;
const configNamespace =
formContext?.i18nNamespace ??
@@ -86,8 +86,7 @@ export function FieldTemplate(props: FieldTemplateProps) {
const formContext = registry?.formContext as ConfigFormContext | undefined;
const i18nNamespace = formContext?.i18nNamespace as string | undefined;
const sectionI18nPrefix = formContext?.sectionI18nPrefix as
| string
| undefined;
string | undefined;
const isCameraLevel = formContext?.level === "camera";
const effectiveNamespace = isCameraLevel ? "config/cameras" : i18nNamespace;
const { t, i18n } = useTranslation([
@@ -25,8 +25,7 @@ export function MultiSchemaFieldTemplate<
const { schema, selector, optionSchemaField, uiSchema } = props;
const uiOptions = uiSchema?.["ui:options"] as
| UiSchema["ui:options"]
| undefined;
UiSchema["ui:options"] | undefined;
const suppressMultiSchema = uiOptions?.suppressMultiSchema === true;
// Check if this is a simple nullable field that should be handled specially
@@ -55,8 +55,7 @@ export function CameraPathWidget(props: WidgetProps) {
const [showCredentials, setShowCredentials] = useState(false);
const formContext = props.registry?.formContext as
| ConfigFormContext
| undefined;
ConfigFormContext | undefined;
const isCameraLevel = formContext?.level === "camera";
const cameraName = formContext?.cameraName;
const inputIndex = useMemo(() => getInputIndexFromWidgetId(id), [id]);
@@ -103,8 +103,7 @@ const normalizeManualText = (value: unknown): string => {
export function FfmpegArgsWidget(props: WidgetProps) {
const formContext = props.registry?.formContext as
| ConfigFormContext
| undefined;
ConfigFormContext | undefined;
const i18nNamespace = formContext?.i18nNamespace as string | undefined;
const isCameraLevel = formContext?.level === "camera";
const effectiveNamespace = isCameraLevel ? "config/cameras" : i18nNamespace;
@@ -27,8 +27,7 @@ import type { GenAIModelsResponse } from "@/types/chat";
import { getSizedFieldClassName } from "../utils";
type ProbeResponse =
| { success: true; models: string[] }
| { success: false; message: string };
{ success: true; models: string[] } | { success: false; message: string };
type ProbeStatus = "idle" | "probing" | "success" | "error";
@@ -21,8 +21,7 @@ export function OnvifProfileWidget(props: WidgetProps) {
const { t } = useTranslation(["views/settings"]);
const formContext = props.registry?.formContext as
| ConfigFormContext
| undefined;
ConfigFormContext | undefined;
const cameraName = formContext?.cameraName;
const isCameraLevel = formContext?.level === "camera";
const hasOnvifHost = !!formContext?.fullCameraConfig?.onvif?.host;
@@ -98,8 +98,7 @@ export function SwitchesWidget(props: WidgetProps) {
const availableEntities = useMemo(() => {
const getEntities =
(props.options?.getEntities as
| ((context: FormContext) => string[])
| undefined) || (() => []);
((context: FormContext) => string[]) | undefined) || (() => []);
if (context) {
return getEntities(context);
}
@@ -109,8 +108,8 @@ export function SwitchesWidget(props: WidgetProps) {
const getDisplayLabel = useMemo(
() =>
(props.options?.getDisplayLabel as
| ((entity: string, context?: FormContext) => string)
| undefined) || ((entity: string) => entity),
((entity: string, context?: FormContext) => string) | undefined) ||
((entity: string) => entity),
[props.options],
);