mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-08-02 17:12:16 +03:00
improve typing
This commit is contained in:
@@ -3,23 +3,25 @@ import { useMemo } from "react";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import get from "lodash/get";
|
||||
import set from "lodash/set";
|
||||
import type { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { JsonObject, JsonValue } from "@/types/configForm";
|
||||
import { isJsonObject } from "@/lib/utils";
|
||||
|
||||
const INTERNAL_FIELD_SUFFIXES = ["enabled_in_config", "raw_mask"];
|
||||
|
||||
function stripInternalFields(value: unknown): unknown {
|
||||
function stripInternalFields(value: JsonValue): JsonValue {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(stripInternalFields);
|
||||
}
|
||||
|
||||
if (value && typeof value === "object") {
|
||||
const obj = value as Record<string, unknown>;
|
||||
const cleaned: Record<string, unknown> = {};
|
||||
if (isJsonObject(value)) {
|
||||
const obj = value;
|
||||
const cleaned: JsonObject = {};
|
||||
for (const [key, val] of Object.entries(obj)) {
|
||||
if (INTERNAL_FIELD_SUFFIXES.some((suffix) => key.endsWith(suffix))) {
|
||||
continue;
|
||||
}
|
||||
cleaned[key] = stripInternalFields(val);
|
||||
cleaned[key] = stripInternalFields(val as JsonValue);
|
||||
}
|
||||
return cleaned;
|
||||
}
|
||||
@@ -27,8 +29,8 @@ function stripInternalFields(value: unknown): unknown {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function normalizeConfigValue(value: unknown): unknown {
|
||||
return stripInternalFields(value);
|
||||
export function normalizeConfigValue(value: unknown): JsonValue {
|
||||
return stripInternalFields(value as JsonValue);
|
||||
}
|
||||
|
||||
export interface OverrideStatus {
|
||||
@@ -51,15 +53,15 @@ export interface UseConfigOverrideOptions {
|
||||
compareFields?: string[];
|
||||
}
|
||||
|
||||
function pickFields(value: unknown, fields: string[]): Record<string, unknown> {
|
||||
function pickFields(value: unknown, fields: string[]): JsonObject {
|
||||
if (!fields || fields.length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const result: Record<string, unknown> = {};
|
||||
const result: JsonObject = {};
|
||||
fields.forEach((path) => {
|
||||
if (!path) return;
|
||||
const fieldValue = get(value as Record<string, unknown>, path);
|
||||
const fieldValue = get(value as JsonObject, path);
|
||||
if (fieldValue !== undefined) {
|
||||
set(result, path, fieldValue);
|
||||
}
|
||||
|
||||
@@ -3,12 +3,23 @@
|
||||
|
||||
import { useMemo } from "react";
|
||||
import useSWR from "swr";
|
||||
import type { RJSFSchema } from "@rjsf/utils";
|
||||
import { RJSFSchema } from "@rjsf/utils";
|
||||
import { resolveAndCleanSchema } from "@/lib/config-schema";
|
||||
|
||||
// Cache for resolved section schemas - keyed by schema reference + section key
|
||||
const sectionSchemaCache = new WeakMap<RJSFSchema, Map<string, RJSFSchema>>();
|
||||
|
||||
type SchemaWithDefinitions = RJSFSchema & {
|
||||
$defs?: Record<string, RJSFSchema>;
|
||||
definitions?: Record<string, RJSFSchema>;
|
||||
properties?: Record<string, RJSFSchema>;
|
||||
};
|
||||
|
||||
const getSchemaDefinitions = (schema: RJSFSchema): Record<string, RJSFSchema> =>
|
||||
(schema as SchemaWithDefinitions).$defs ||
|
||||
(schema as SchemaWithDefinitions).definitions ||
|
||||
{};
|
||||
|
||||
/**
|
||||
* Extracts and resolves a section schema from the full config schema
|
||||
* Uses caching to avoid repeated expensive resolution
|
||||
@@ -32,50 +43,43 @@ function extractSectionSchema(
|
||||
return schemaCache.get(cacheKey)!;
|
||||
}
|
||||
|
||||
const schemaObj = schema as Record<string, unknown>;
|
||||
const defs = (schemaObj.$defs || schemaObj.definitions || {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
const defs = getSchemaDefinitions(schema);
|
||||
const schemaObj = schema as SchemaWithDefinitions;
|
||||
|
||||
let sectionDef: Record<string, unknown> | null = null;
|
||||
let sectionDef: RJSFSchema | null = null;
|
||||
|
||||
// For camera level, get section from CameraConfig in $defs
|
||||
if (level === "camera") {
|
||||
const cameraConfigDef = defs.CameraConfig as
|
||||
| Record<string, unknown>
|
||||
| undefined;
|
||||
const cameraConfigDef = defs.CameraConfig;
|
||||
if (cameraConfigDef?.properties) {
|
||||
const props = cameraConfigDef.properties as Record<string, unknown>;
|
||||
const props = cameraConfigDef.properties;
|
||||
const sectionProp = props[sectionPath];
|
||||
|
||||
if (sectionProp && typeof sectionProp === "object") {
|
||||
const refProp = sectionProp as Record<string, unknown>;
|
||||
if (refProp.$ref && typeof refProp.$ref === "string") {
|
||||
const refPath = (refProp.$ref as string)
|
||||
if ("$ref" in sectionProp && typeof sectionProp.$ref === "string") {
|
||||
const refPath = sectionProp.$ref
|
||||
.replace(/^#\/\$defs\//, "")
|
||||
.replace(/^#\/definitions\//, "");
|
||||
sectionDef = defs[refPath] as Record<string, unknown>;
|
||||
sectionDef = defs[refPath] || null;
|
||||
} else {
|
||||
sectionDef = sectionProp as Record<string, unknown>;
|
||||
sectionDef = sectionProp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For global level, get from root properties
|
||||
if (schemaObj.properties) {
|
||||
const props = schemaObj.properties as Record<string, unknown>;
|
||||
const props = schemaObj.properties;
|
||||
const sectionProp = props[sectionPath];
|
||||
|
||||
if (sectionProp && typeof sectionProp === "object") {
|
||||
const refProp = sectionProp as Record<string, unknown>;
|
||||
if (refProp.$ref && typeof refProp.$ref === "string") {
|
||||
const refPath = (refProp.$ref as string)
|
||||
if ("$ref" in sectionProp && typeof sectionProp.$ref === "string") {
|
||||
const refPath = sectionProp.$ref
|
||||
.replace(/^#\/\$defs\//, "")
|
||||
.replace(/^#\/definitions\//, "");
|
||||
sectionDef = defs[refPath] as Record<string, unknown>;
|
||||
sectionDef = defs[refPath] || null;
|
||||
} else {
|
||||
sectionDef = sectionProp as Record<string, unknown>;
|
||||
sectionDef = sectionProp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,10 +88,10 @@ function extractSectionSchema(
|
||||
if (!sectionDef) return null;
|
||||
|
||||
// Include $defs for nested references and resolve them
|
||||
const schemaWithDefs = {
|
||||
const schemaWithDefs: RJSFSchema = {
|
||||
...sectionDef,
|
||||
$defs: defs,
|
||||
} as RJSFSchema;
|
||||
};
|
||||
|
||||
// Resolve all references and strip $defs from result
|
||||
const resolved = resolveAndCleanSchema(schemaWithDefs);
|
||||
|
||||
Reference in New Issue
Block a user