diff --git a/eslint.config.js b/eslint.config.js index 8592e57d9..94d7a7e0b 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -8,10 +8,7 @@ import globals from "globals" import tseslint from "typescript-eslint" const rules = Object.fromEntries( - Object.entries(eslintPluginAntfu.rules) - .map( - ([id]) => [`antfu/${id}`, "off"], - ), + Object.entries(eslintPluginAntfu.rules).map(([id]) => [`antfu/${id}`, "off"]), ) const antfuLint = { name: "antfu/without-if-newline-or-imports", @@ -214,7 +211,15 @@ export default tseslint.config( rules: { "@typescript-eslint/no-unused-vars": "off", "unused-imports/no-unused-imports": "error", - "unused-imports/no-unused-vars": "error", + "unused-imports/no-unused-vars": [ + "error", + { + vars: "all", + varsIgnorePattern: "^_", + args: "after-used", + argsIgnorePattern: "^_", + }, + ], }, }, @@ -242,7 +247,14 @@ export default tseslint.config( "error", { // The default grouping, but with type imports first as a separate group. - groups: [["^.*\\u0000$"], ["^\\u0000"], ["^node:"], ["^@?\\w"], ["^"], ["^\\."]], + groups: [ + ["^.*\\u0000$"], + ["^\\u0000"], + ["^node:"], + ["^@?\\w"], + ["^"], + ["^\\."], + ], }, ], "simple-import-sort/exports": "error", diff --git a/src/NodeSlot.ts b/src/NodeSlot.ts index 9515f63c4..ccf917546 100644 --- a/src/NodeSlot.ts +++ b/src/NodeSlot.ts @@ -7,6 +7,7 @@ import { LiteGraph } from "./litegraph" import { LinkDirection, RenderShape } from "./types/globalEnums" import { ISerialisedNodeOutputSlot } from "./types/serialisation" import { ISerialisedNodeInputSlot } from "./types/serialisation" +import { omitBy } from "./utils/object" export interface ConnectionColorContext { default_connection_color: { @@ -33,16 +34,13 @@ interface IDrawOptions { export function serializeSlot(slot: INodeInputSlot): ISerialisedNodeInputSlot export function serializeSlot(slot: INodeOutputSlot): ISerialisedNodeOutputSlot export function serializeSlot(slot: INodeInputSlot | INodeOutputSlot): ISerialisedNodeInputSlot | ISerialisedNodeOutputSlot { - const serialized = { ...slot } - delete serialized._layoutElement - if ("_data" in serialized) { - delete serialized._data - } - // Widget input slots' pos is calculated during layout, so we don't need to serialize it. - if (isWidgetInputSlot(slot) && "pos" in serialized) { - delete serialized.pos - } - return serialized + return omitBy({ + ...slot, + _layoutElement: undefined, + _data: undefined, + pos: isWidgetInputSlot(slot) ? undefined : slot.pos, + widget: isWidgetInputSlot(slot) && slot.widget?.name ? { name: slot.widget.name } : undefined, + }, value => value === undefined) as ISerialisedNodeInputSlot | ISerialisedNodeOutputSlot } export function toNodeSlotClass(slot: INodeSlot): NodeSlot { diff --git a/src/types/serialisation.ts b/src/types/serialisation.ts index ff1fe9374..7603be315 100644 --- a/src/types/serialisation.ts +++ b/src/types/serialisation.ts @@ -41,7 +41,7 @@ export interface SerialisableGraph { } export type ISerialisedNodeInputSlot = Omit & { - widget?: { name?: string } + widget?: { name: string } } export type ISerialisedNodeOutputSlot = Omit diff --git a/src/utils/object.ts b/src/utils/object.ts new file mode 100644 index 000000000..9e95fd422 --- /dev/null +++ b/src/utils/object.ts @@ -0,0 +1,5 @@ +export function omitBy(obj: T, predicate: (value: any) => boolean): Partial { + return Object.fromEntries( + Object.entries(obj).filter(([_key, value]) => !predicate(value)), + ) as Partial +} diff --git a/test/NodeSlot.test.ts b/test/NodeSlot.test.ts index b3bbaa56c..45637f0bb 100644 --- a/test/NodeSlot.test.ts +++ b/test/NodeSlot.test.ts @@ -46,5 +46,27 @@ describe("NodeSlot", () => { const serialized = serializeSlot(normalSlot) expect(serialized).toHaveProperty("pos") }) + + it("preserves only widget name during serialization", () => { + const widgetInputSlot: INodeInputSlot = { + name: "test-id", + type: "STRING", + link: null, + widget: { + name: "test-widget", + type: "combo", + value: "test-value-1", + options: { + values: ["test-value-1", "test-value-2"], + }, + }, + } + + const serialized = serializeSlot(widgetInputSlot) + expect(serialized.widget).toEqual({ name: "test-widget" }) + expect(serialized.widget).not.toHaveProperty("type") + expect(serialized.widget).not.toHaveProperty("value") + expect(serialized.widget).not.toHaveProperty("options") + }) }) })