diff --git a/packages/controller/src/ControlConnection.ts b/packages/controller/src/ControlConnection.ts index 5e827a89..aa2350f3 100644 --- a/packages/controller/src/ControlConnection.ts +++ b/packages/controller/src/ControlConnection.ts @@ -315,23 +315,24 @@ export default class ControlConnection extends BaseConnection { } async handleInstanceConfigSetRequest(request: lib.InstanceConfigSetRequest) { + const instance = this._controller.instances.getForRequest(request.instanceId); try { for (const [fieldName, fieldValue] of Object.entries(request.fields)) { ControlConnection.validateInstanceConfigSetField(fieldName); if (typeof fieldValue === "object") { for (const [propName, propValue] of Object.entries(fieldValue)) { - this._controller.config.stageProp( - fieldName as keyof lib.ControllerConfigFields, propName, propValue, "control" + instance.config.stageProp( + fieldName as keyof lib.InstanceConfigFields, propName, propValue, "control" ); } } else { - this._controller.config.stage(fieldName as keyof lib.ControllerConfigFields, fieldValue, "control"); + instance.config.stage(fieldName as keyof lib.InstanceConfigFields, fieldValue, "control"); } } - this._controller.config.commitStaging(); + instance.config.commitStaging(); } finally { - this._controller.config.revertStaging(); + instance.config.revertStaging(); } } diff --git a/packages/lib/src/config/classes.ts b/packages/lib/src/config/classes.ts index c5834268..02760cde 100644 --- a/packages/lib/src/config/classes.ts +++ b/packages/lib/src/config/classes.ts @@ -9,7 +9,6 @@ import * as libSchema from "../schema"; import { StringEnum } from "../data/composites"; import { safeOutputFile } from "../file_ops"; import * as validators from "./validators"; -import { string } from "yargs"; const ConfigLocation = StringEnum(["controller", "host", "control"]); export type ConfigLocation = Static; @@ -208,7 +207,7 @@ export class Config< * Note that mutating this object will lead to unexpected behaviour. */ declare static fieldDefinitions: ConfigDefs; - declare ["constructor"]: typeof Config; + declare ["constructor"]: typeof Config; /** A set of common validators and validator factories */ static validators = validators; @@ -272,14 +271,14 @@ export class Config< } /** A staging version of the config with changes tracked, invalided by revertStaging */ - private _staging?: { config: Config, changes: Set }; + private _staging?: { config: Config, changes: Set}; /** Get the latest version of staging */ get staging(): Config { if (this._staging) { return this._staging.config; } - const config = new this.constructor(this.location, this.fields) as this; - const changes = new Set(); - config.on("fieldChanged", name => changes.add(name as keyof Fields & string)); + const config = new this.constructor(this.location, this.fields); + const changes = new Set(); + config.on("fieldChanged", name => changes.add(name)); this._staging = { config, changes }; return config; } @@ -832,7 +831,8 @@ export class Config< // Validation success, set all values which have changed for (const fieldName of staging.changes) { - this._set(fieldName, config.fields[fieldName]); + const field = fieldName as keyof Fields & string; + this._set(field, config.fields[field]); } } diff --git a/packages/lib/src/data/messages_controller.ts b/packages/lib/src/data/messages_controller.ts index d4206a39..69ffb3a0 100644 --- a/packages/lib/src/data/messages_controller.ts +++ b/packages/lib/src/data/messages_controller.ts @@ -45,12 +45,12 @@ export class ControllerConfigSetRequest { static permission = "core.controller.update_config" as const; constructor( - public fields: Record>, + public fields: Record>, ) { } static jsonSchema = Type.Object({ "fields": Type.Record(Type.String(), Type.Union([ - Type.String(), Type.Record(Type.String(), Type.String()), + Type.String(), Type.Record(Type.String(), Type.Unknown()), ])), }); diff --git a/packages/lib/src/data/messages_host.ts b/packages/lib/src/data/messages_host.ts index 67cf060b..e707d856 100644 --- a/packages/lib/src/data/messages_host.ts +++ b/packages/lib/src/data/messages_host.ts @@ -45,12 +45,12 @@ export class HostConfigSetRequest { static permission = "core.host.update_config" as const; constructor( - public fields: Record>, + public fields: Record>, ) { } static jsonSchema = Type.Object({ "fields": Type.Record(Type.String(), Type.Union([ - Type.String(), Type.Record(Type.String(), Type.String()), + Type.String(), Type.Record(Type.String(), Type.Unknown()), ])), }); diff --git a/packages/lib/src/data/messages_instance.ts b/packages/lib/src/data/messages_instance.ts index 7c9d7693..0b87461b 100644 --- a/packages/lib/src/data/messages_instance.ts +++ b/packages/lib/src/data/messages_instance.ts @@ -111,13 +111,13 @@ export class InstanceConfigSetRequest { constructor( public instanceId: number, - public fields: Record>, + public fields: Record>, ) { } static jsonSchema = Type.Object({ "instanceId": Type.Integer(), "fields": Type.Record(Type.String(), Type.Union([ - Type.String(), Type.Record(Type.String(), Type.String()), + Type.String(), Type.Record(Type.String(), Type.Unknown()), ])), }); diff --git a/packages/web_ui/src/components/BaseConfigTree.tsx b/packages/web_ui/src/components/BaseConfigTree.tsx index 00f5962d..fcc7c1e8 100644 --- a/packages/web_ui/src/components/BaseConfigTree.tsx +++ b/packages/web_ui/src/components/BaseConfigTree.tsx @@ -164,7 +164,15 @@ export default function BaseConfigTree(props: BaseConfigTreeProps) { const [fieldName, prop] = propsMap.get(field)!; const fieldValue = (fields[fieldName] ?? {}) as Record; fields[fieldName] = fieldValue; - fieldValue[prop] = value ? JSON.parse(value) : undefined; + try { + fieldValue[prop] = value ? JSON.parse(value) : undefined; + } catch (err: any) { + setErrorFields(errors => { + const newErrors = new Map(errors); + newErrors.set(fieldName, err.message); + return newErrors; + }); + } } else { fields[field] = value === null ? "" : String(value);