[refactor] Type createNode options parameter (#9262)

## Summary
Narrow `CreateNodeOptions` from `Partial<Omit<LGraphNode, ...>>`
(exposing hundreds of properties/methods) to an explicit interface
listing only creation-time properties.

## Changes
- Replace `Partial<Omit<LGraphNode, 'constructor' | 'inputs' |
'outputs'>>` with explicit `CreateNodeOptions` interface containing
only: `pos`, `size`, `properties`, `flags`, `mode`, `color`, `bgcolor`,
`boxcolor`, `title`, `shape`, `inputs`, `outputs`
- Rename local `CreateNodeOptions` in `createModelNodeFromAsset.ts` to
`ModelNodeCreateOptions` to avoid collision

## Ecosystem verification
GitHub code search across ~50 repos confirms only `pos` and `outputs`
are used externally. All covered by the narrowed interface.

Fixes #9276
Fixes #4740
This commit is contained in:
Johnpaul Chiwetelu
2026-03-04 23:01:18 +01:00
committed by GitHub
parent 9e2299ca65
commit 82750d629d
6 changed files with 37 additions and 12 deletions

View File

@@ -6573,7 +6573,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
const ySizeFix = opts.posSizeFix[1] * LiteGraph.NODE_SLOT_HEIGHT
const nodeX = opts.position[0] + opts.posAdd[0] + xSizeFix
const nodeY = opts.position[1] + opts.posAdd[1] + ySizeFix
const pos = [nodeX, nodeY]
const pos: [number, number] = [nodeX, nodeY]
const newNode = LiteGraph.createNode(nodeTypeStr, nodeNewOpts?.title, {
pos
})

View File

@@ -10,7 +10,13 @@ import { Reroute } from './Reroute'
import { InputIndicators } from './canvas/InputIndicators'
import { LabelPosition, SlotDirection, SlotShape, SlotType } from './draw'
import { Rectangle } from './infrastructure/Rectangle'
import type { Dictionary, ISlotType, Rect, WhenNullish } from './interfaces'
import type {
CreateNodeOptions,
Dictionary,
ISlotType,
Rect,
WhenNullish
} from './interfaces'
import { distance, isInsideRectangle, overlapBounding } from './measure'
import { SubgraphIONodeBase } from './subgraph/SubgraphIONodeBase'
import { SubgraphSlot } from './subgraph/SubgraphSlotBase'
@@ -525,7 +531,7 @@ export class LiteGraphGlobal {
createNode(
type: string,
title?: string,
options?: Dictionary<unknown>
options?: CreateNodeOptions
): LGraphNode | null {
const base_class = this.registered_node_types[type]
if (!base_class) {
@@ -561,10 +567,7 @@ export class LiteGraphGlobal {
// extra options
if (options) {
for (const i in options) {
// @ts-expect-error #577 Requires interface
node[i] = options[i]
}
Object.assign(node, options)
}
// callback

View File

@@ -3,13 +3,17 @@ import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
import type { TWidgetValue } from '@/lib/litegraph/src/types/widgets'
import type { ContextMenu } from './ContextMenu'
import type { LGraphNode, NodeId } from './LGraphNode'
import type { LGraphNode, NodeId, NodeProperty } from './LGraphNode'
import type { LLink, LinkId } from './LLink'
import type { Reroute, RerouteId } from './Reroute'
import type { SubgraphInput } from './subgraph/SubgraphInput'
import type { SubgraphInputNode } from './subgraph/SubgraphInputNode'
import type { SubgraphOutputNode } from './subgraph/SubgraphOutputNode'
import type { LinkDirection, RenderShape } from './types/globalEnums'
import type {
LGraphEventMode,
LinkDirection,
RenderShape
} from './types/globalEnums'
import type { IBaseWidget } from './types/widgets'
export type Dictionary<T> = { [key: string]: T }
@@ -373,6 +377,22 @@ export interface INodeOutputSlot extends INodeSlot {
slot_index?: number
}
/** Options for {@link LiteGraphGlobal.createNode}. Shallow-copied onto the new node. */
export interface CreateNodeOptions {
pos?: Point
size?: Size
properties?: Dictionary<NodeProperty | undefined>
flags?: Partial<INodeFlags>
mode?: LGraphEventMode
color?: string
bgcolor?: string
boxcolor?: string
title?: string
shape?: RenderShape
inputs?: Partial<INodeInputSlot>[]
outputs?: Partial<INodeOutputSlot>[]
}
/** Links */
export interface ConnectingLink extends IInputOrOutput {
node: LGraphNode

View File

@@ -91,6 +91,7 @@ export { RecursionError } from './infrastructure/RecursionError'
export type {
CanvasColour,
ColorOption,
CreateNodeOptions,
IContextMenuOptions,
IContextMenuValue,
INodeInputSlot,

View File

@@ -12,7 +12,7 @@ import { app } from '@/scripts/app'
import { useLitegraphService } from '@/services/litegraphService'
import { useModelToNodeStore } from '@/stores/modelToNodeStore'
interface CreateNodeOptions {
interface ModelNodeCreateOptions {
position?: Point
}
@@ -48,7 +48,7 @@ type Result<T, E> = { success: true; value: T } | { success: false; error: E }
*/
export function createModelNodeFromAsset(
asset: AssetItem,
options?: CreateNodeOptions
options?: ModelNodeCreateOptions
): Result<LGraphNode, NodeCreationError> {
const validatedAsset = assetItemSchema.safeParse(asset)

View File

@@ -22,6 +22,7 @@ import {
createBounds
} from '@/lib/litegraph/src/litegraph'
import type {
CreateNodeOptions,
GraphAddOptions,
IContextMenuValue,
Point,
@@ -885,7 +886,7 @@ export const useLitegraphService = () => {
function addNodeOnGraph(
nodeDef: ComfyNodeDefV1 | ComfyNodeDefV2,
options: Record<string, unknown> & { pos?: Point } = {},
options: CreateNodeOptions = {},
addOptions?: GraphAddOptions
): LGraphNode | null {
options.pos ??= getCanvasCenter()