diff --git a/knip.config.ts b/knip.config.ts index c691f35720..ca98c8f2a7 100644 --- a/knip.config.ts +++ b/knip.config.ts @@ -16,6 +16,7 @@ const config: KnipConfig = { 'tests-ui/**/*.{js,ts,vue}', '*.{js,ts,mts}' ], + ignoreBinaries: ['only-allow', 'openapi-typescript'], ignoreDependencies: [ '@primeuix/forms', '@primeuix/styled', @@ -59,7 +60,11 @@ const config: KnipConfig = { 'src/components/button/TextButton.vue', 'src/components/card/CardTitle.vue', 'src/components/card/CardDescription.vue', - 'src/components/input/SingleSelect.vue' + 'src/components/input/SingleSelect.vue', + // Used by a custom node (that should move off of this) + 'src/scripts/ui/components/splitButton.ts', + // Generated file: openapi + 'src/types/comfyRegistryTypes.ts' ], ignoreExportsUsedInFile: true, // Vue-specific configuration @@ -68,15 +73,12 @@ const config: KnipConfig = { // Only check for unused files, disable all other rules // TODO: Gradually enable other rules - see https://github.com/Comfy-Org/ComfyUI_frontend/issues/4888 rules: { - binaries: 'off', - classMembers: 'off', - duplicates: 'off', - enumMembers: 'off', - exports: 'off', - nsExports: 'off', - nsTypes: 'off', - types: 'off' + classMembers: 'off' }, + tags: [ + '-knipIgnoreUnusedButUsedByCustomNodes', + '-knipIgnoreUnusedButUsedByVueNodesBranch' + ], // Include dependencies analysis includeEntryExports: true } diff --git a/src/composables/useTemplateFiltering.ts b/src/composables/useTemplateFiltering.ts index 14e5c6768e..6bf0b53a2a 100644 --- a/src/composables/useTemplateFiltering.ts +++ b/src/composables/useTemplateFiltering.ts @@ -2,7 +2,8 @@ import { type Ref, computed, ref } from 'vue' import type { TemplateInfo } from '@/types/workflowTemplateTypes' -export interface TemplateFilterOptions { +// @ts-expect-error unused (To be used later?) +interface TemplateFilterOptions { searchQuery?: string } diff --git a/src/constants/serverConfig.ts b/src/constants/serverConfig.ts index 2f04e4cf30..45991f7377 100644 --- a/src/constants/serverConfig.ts +++ b/src/constants/serverConfig.ts @@ -1,5 +1,4 @@ import { - AutoLaunch, CrossAttentionMethod, CudaMalloc, FloatingPointPrecision, @@ -20,32 +19,6 @@ export interface ServerConfig extends FormItem { getValue?: (value: T) => Record } -export const WEB_ONLY_CONFIG_ITEMS: ServerConfig[] = [ - // Launch behavior - { - id: 'auto-launch', - name: 'Automatically opens in the browser on startup', - category: ['Launch'], - type: 'combo', - options: Object.values(AutoLaunch), - defaultValue: AutoLaunch.Auto, - getValue: (value: AutoLaunch) => { - switch (value) { - case AutoLaunch.Auto: - return {} - case AutoLaunch.Enable: - return { - ['auto-launch']: true - } - case AutoLaunch.Disable: - return { - ['disable-auto-launch']: true - } - } - } - } -] - export const SERVER_CONFIG_ITEMS: ServerConfig[] = [ // Network settings { diff --git a/src/extensions/core/load3d/interfaces.ts b/src/extensions/core/load3d/interfaces.ts index 51247a8a36..fa05ce2b0a 100644 --- a/src/extensions/core/load3d/interfaces.ts +++ b/src/extensions/core/load3d/interfaces.ts @@ -185,12 +185,3 @@ export interface LoaderManagerInterface { dispose(): void loadModel(url: string, originalFileName?: string): Promise } - -export interface RecordingManagerInterface extends BaseManager { - startRecording(): Promise - stopRecording(): void - hasRecording(): boolean - getRecordingDuration(): number - exportRecording(filename?: string): void - clearRecording(): void -} diff --git a/src/extensions/core/widgetInputs.ts b/src/extensions/core/widgetInputs.ts index bc07256279..46954430fa 100644 --- a/src/extensions/core/widgetInputs.ts +++ b/src/extensions/core/widgetInputs.ts @@ -422,6 +422,7 @@ function getConfig(this: LGraphNode, widgetName: string) { * @param node The node to convert the widget to an input slot for. * @param widget The widget to convert to an input slot. * @returns The input slot that was converted from the widget or undefined if the widget is not found. + * @knipIgnoreUnusedButUsedByCustomNodes */ export function convertToInput( node: LGraphNode, diff --git a/src/lib/litegraph/src/draw.ts b/src/lib/litegraph/src/draw.ts index 756c60db1b..b335f3f810 100644 --- a/src/lib/litegraph/src/draw.ts +++ b/src/lib/litegraph/src/draw.ts @@ -1,7 +1,7 @@ import type { Rectangle } from './infrastructure/Rectangle' import type { CanvasColour, Rect } from './interfaces' import { LiteGraph } from './litegraph' -import { LinkDirection, RenderShape, TitleMode } from './types/globalEnums' +import { RenderShape, TitleMode } from './types/globalEnums' const ELLIPSIS = '\u2026' const TWO_DOT_LEADER = '\u2025' @@ -22,12 +22,7 @@ export enum SlotShape { } /** @see LinkDirection */ -export enum SlotDirection { - Up = LinkDirection.UP, - Right = LinkDirection.RIGHT, - Down = LinkDirection.DOWN, - Left = LinkDirection.LEFT -} +export enum SlotDirection {} export enum LabelPosition { Left = 'left', diff --git a/src/lib/litegraph/src/interfaces.ts b/src/lib/litegraph/src/interfaces.ts index 0a34133f9f..0abbf313b6 100644 --- a/src/lib/litegraph/src/interfaces.ts +++ b/src/lib/litegraph/src/interfaces.ts @@ -278,9 +278,6 @@ export type KeysOfType = Exclude< undefined > -/** A new type that contains only the properties of T that are of type Match */ -export type PickByType = { [P in keyof T]: Extract } - /** The names of all (optional) methods and functions in T */ export type MethodNames = KeysOfType any) | undefined> diff --git a/src/lib/litegraph/src/litegraph.ts b/src/lib/litegraph/src/litegraph.ts index 5be28a4138..fd1d1a31af 100644 --- a/src/lib/litegraph/src/litegraph.ts +++ b/src/lib/litegraph/src/litegraph.ts @@ -2,7 +2,7 @@ import type { ContextMenu } from './ContextMenu' import type { LGraphNode } from './LGraphNode' import { LiteGraphGlobal } from './LiteGraphGlobal' import type { ConnectingLink, Point } from './interfaces' -import type { IContextMenuOptions, INodeSlot, Size } from './interfaces' +import type { IContextMenuOptions, Size } from './interfaces' import { loadPolyfills } from './polyfills' import type { CanvasEventDetail } from './types/events' import type { RenderShape, TitleMode } from './types/globalEnums' @@ -22,8 +22,6 @@ loadPolyfills() // Definitions by: NateScarlet /** @deprecated Use {@link Point} instead. */ export type Vector2 = Point -/** @deprecated Use {@link Rect} instead. */ -export type Vector4 = [number, number, number, number] export interface IContextMenuItem { content: string @@ -46,14 +44,6 @@ export type ContextMenuEventListener = ( node: LGraphNode ) => boolean | void -export interface LinkReleaseContext { - node_to?: LGraphNode - node_from?: LGraphNode - slot_from: INodeSlot - type_filter_in?: string - type_filter_out?: string -} - export interface LinkReleaseContextExtended { links: ConnectingLink[] } @@ -117,7 +107,6 @@ export type { LinkNetwork, LinkSegment, MethodNames, - PickByType, Point, Positionable, ReadonlyLinkNetwork, diff --git a/src/lib/litegraph/src/node/slotUtils.ts b/src/lib/litegraph/src/node/slotUtils.ts index 3d97ca1427..e0eda79c84 100644 --- a/src/lib/litegraph/src/node/slotUtils.ts +++ b/src/lib/litegraph/src/node/slotUtils.ts @@ -84,10 +84,6 @@ export function isINodeInputSlot(slot: INodeSlot): slot is INodeInputSlot { return 'link' in slot } -export function isINodeOutputSlot(slot: INodeSlot): slot is INodeOutputSlot { - return 'links' in slot -} - /** * Type guard: Whether this input slot is attached to a widget. * @param slot The slot to check. diff --git a/src/lib/litegraph/src/types/events.ts b/src/lib/litegraph/src/types/events.ts index 912cc89ffa..acbb890436 100644 --- a/src/lib/litegraph/src/types/events.ts +++ b/src/lib/litegraph/src/types/events.ts @@ -50,9 +50,6 @@ export interface CanvasMouseEvent Readonly, LegacyMouseEvent {} -/** DragEvent with canvasX/Y and deltaX/Y properties */ -export interface CanvasDragEvent extends DragEvent, CanvasPointerExtensions {} - export type CanvasEventDetail = | GenericEventDetail | GroupDoubleClickEventDetail diff --git a/src/lib/litegraph/src/types/globalEnums.ts b/src/lib/litegraph/src/types/globalEnums.ts index 5e2afcadc3..c955b8e1e3 100644 --- a/src/lib/litegraph/src/types/globalEnums.ts +++ b/src/lib/litegraph/src/types/globalEnums.ts @@ -89,9 +89,6 @@ export enum LGraphEventMode { } export enum EaseFunction { - LINEAR = 'linear', - EASE_IN_QUAD = 'easeInQuad', - EASE_OUT_QUAD = 'easeOutQuad', EASE_IN_OUT_QUAD = 'easeInOutQuad' } diff --git a/src/lib/litegraph/src/types/serialisation.ts b/src/lib/litegraph/src/types/serialisation.ts index 46b4ad7cc8..4b1bfed902 100644 --- a/src/lib/litegraph/src/types/serialisation.ts +++ b/src/lib/litegraph/src/types/serialisation.ts @@ -179,14 +179,6 @@ export interface ISerialisedGroup { flags?: IGraphGroupFlags } -export type TClipboardLink = [ - targetRelativeIndex: number, - originSlot: number, - nodeRelativeIndex: number, - targetSlot: number, - targetNodeId: NodeId -] - /** Items copied from the canvas */ export interface ClipboardItems { nodes?: ISerialisedNode[] @@ -196,12 +188,6 @@ export interface ClipboardItems { subgraphs?: ExportedSubgraph[] } -/** @deprecated */ -export interface IClipboardContents { - nodes?: ISerialisedNode[] - links?: TClipboardLink[] -} - export interface SerialisableReroute { id: RerouteId parentId?: RerouteId diff --git a/src/lib/litegraph/src/utils/collections.ts b/src/lib/litegraph/src/utils/collections.ts index 85da383826..46eba75e08 100644 --- a/src/lib/litegraph/src/utils/collections.ts +++ b/src/lib/litegraph/src/utils/collections.ts @@ -1,8 +1,7 @@ import { LGraphNode } from '@/lib/litegraph/src/LGraphNode' -import type { LinkId } from '@/lib/litegraph/src/LLink' import { parseSlotTypes } from '@/lib/litegraph/src/strings' -import type { ConnectingLink, ISlotType, Positionable } from '../interfaces' +import type { ISlotType, Positionable } from '../interfaces' /** * Creates a flat set of all positionable items by recursively iterating through all child items. @@ -45,19 +44,6 @@ export function findFirstNode( } } -/** @returns `true` if the provided link ID is currently being dragged. */ -export function isDraggingLink( - linkId: LinkId, - connectingLinks: ConnectingLink[] | null | undefined -): ConnectingLink | undefined { - if (connectingLinks == null) return - - for (const connectingLink of connectingLinks) { - if (connectingLink.link == null) continue - if (linkId === connectingLink.link.id) return connectingLink - } -} - type FreeSlotResult = | { index: number; slot: T } | undefined diff --git a/src/lib/litegraph/src/widgets/widgetMap.ts b/src/lib/litegraph/src/widgets/widgetMap.ts index 87b8614e72..42a8f5663a 100644 --- a/src/lib/litegraph/src/widgets/widgetMap.ts +++ b/src/lib/litegraph/src/widgets/widgetMap.ts @@ -1,14 +1,7 @@ import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode' import type { IBaseWidget, - IBooleanWidget, - IButtonWidget, IComboWidget, - ICustomWidget, - IKnobWidget, - INumericWidget, - ISliderWidget, - IStringWidget, IWidget, TWidgetType } from '@/lib/litegraph/src/types/widgets' @@ -130,49 +123,9 @@ export function toConcreteWidget( // #region Type Guards -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link IButtonWidget}. */ -export function isButtonWidget(widget: IBaseWidget): widget is IButtonWidget { - return widget.type === 'button' -} - -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link IBooleanWidget}. */ -export function isBooleanWidget(widget: IBaseWidget): widget is IBooleanWidget { - return widget.type === 'toggle' -} - -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link ISliderWidget}. */ -export function isSliderWidget(widget: IBaseWidget): widget is ISliderWidget { - return widget.type === 'slider' -} - -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link IKnobWidget}. */ -export function isKnobWidget(widget: IBaseWidget): widget is IKnobWidget { - return widget.type === 'knob' -} - /** Type guard: Narrow **from {@link IBaseWidget}** to {@link IComboWidget}. */ export function isComboWidget(widget: IBaseWidget): widget is IComboWidget { return widget.type === 'combo' } -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link INumericWidget}. */ -export function isNumberWidget(widget: IBaseWidget): widget is INumericWidget { - return widget.type === 'number' -} - -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link IStringWidget}. */ -export function isStringWidget(widget: IBaseWidget): widget is IStringWidget { - return widget.type === 'string' -} - -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link ITextWidget}. */ -export function isTextWidget(widget: IBaseWidget): widget is IStringWidget { - return widget.type === 'text' -} - -/** Type guard: Narrow **from {@link IBaseWidget}** to {@link ICustomWidget}. */ -export function isCustomWidget(widget: IBaseWidget): widget is ICustomWidget { - return widget.type === 'custom' -} - // #endregion Type Guards diff --git a/src/lib/litegraph/test/subgraph/fixtures/subgraphFixtures.ts b/src/lib/litegraph/test/subgraph/fixtures/subgraphFixtures.ts index dcd6624a49..1c2d936acf 100644 --- a/src/lib/litegraph/test/subgraph/fixtures/subgraphFixtures.ts +++ b/src/lib/litegraph/test/subgraph/fixtures/subgraphFixtures.ts @@ -169,140 +169,3 @@ export const subgraphTest = test.extend({ capture.cleanup() } }) - -/** - * Fixtures that test edge cases and error conditions. - * These may leave the system in an invalid state and should be used carefully. - */ -export interface EdgeCaseFixtures { - /** Subgraph with circular references (for testing recursion detection) */ - circularSubgraph: { - rootGraph: LGraph - subgraphA: Subgraph - subgraphB: Subgraph - nodeA: SubgraphNode - nodeB: SubgraphNode - } - - /** Deeply nested subgraphs approaching the theoretical limit */ - deeplyNestedSubgraph: ReturnType - - /** Subgraph with maximum inputs and outputs */ - maxIOSubgraph: Subgraph -} - -/** - * Test with edge case fixtures. Use sparingly and with caution. - * These tests may intentionally create invalid states. - */ -export const edgeCaseTest = subgraphTest.extend({ - // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern - circularSubgraph: async ({}, use: (value: unknown) => Promise) => { - const rootGraph = new LGraph() - - // Create two subgraphs that will reference each other - const subgraphA = createTestSubgraph({ - name: 'Subgraph A', - inputs: [{ name: 'input', type: '*' }], - outputs: [{ name: 'output', type: '*' }] - }) - - const subgraphB = createTestSubgraph({ - name: 'Subgraph B', - inputs: [{ name: 'input', type: '*' }], - outputs: [{ name: 'output', type: '*' }] - }) - - // Create instances (this doesn't create circular refs by itself) - const nodeA = createTestSubgraphNode(subgraphA, { pos: [100, 100] }) - const nodeB = createTestSubgraphNode(subgraphB, { pos: [300, 100] }) - - // Add nodes to root graph - rootGraph.add(nodeA) - rootGraph.add(nodeB) - - await use({ - rootGraph, - subgraphA, - subgraphB, - nodeA, - nodeB - }) - }, - - // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern - deeplyNestedSubgraph: async ({}, use: (value: unknown) => Promise) => { - // Create a very deep nesting structure (but not exceeding MAX_NESTED_SUBGRAPHS) - const nested = createNestedSubgraphs({ - depth: 50, // Deep but reasonable - nodesPerLevel: 1, - inputsPerSubgraph: 1, - outputsPerSubgraph: 1 - }) - - await use(nested) - }, - - // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern - maxIOSubgraph: async ({}, use: (value: unknown) => Promise) => { - // Create a subgraph with many inputs and outputs - const inputs = Array.from({ length: 20 }, (_, i) => ({ - name: `input_${i}`, - type: i % 2 === 0 ? 'number' : ('string' as const) - })) - - const outputs = Array.from({ length: 20 }, (_, i) => ({ - name: `output_${i}`, - type: i % 2 === 0 ? 'number' : ('string' as const) - })) - - const subgraph = createTestSubgraph({ - name: 'Max IO Subgraph', - inputs, - outputs, - nodeCount: 10 - }) - - await use(subgraph) - } -}) - -/** - * Helper to verify fixture integrity. - * Use this in tests to ensure fixtures are properly set up. - */ -export function verifyFixtureIntegrity>( - fixture: T, - expectedProperties: (keyof T)[] -): void { - for (const prop of expectedProperties) { - if (!(prop in fixture)) { - throw new Error(`Fixture missing required property: ${String(prop)}`) - } - if (fixture[prop] === undefined || fixture[prop] === null) { - throw new Error(`Fixture property ${String(prop)} is null or undefined`) - } - } -} - -/** - * Creates a snapshot-friendly representation of a subgraph for testing. - * Useful for serialization tests and regression detection. - */ -export function createSubgraphSnapshot(subgraph: Subgraph) { - return { - id: subgraph.id, - name: subgraph.name, - inputCount: subgraph.inputs.length, - outputCount: subgraph.outputs.length, - nodeCount: subgraph.nodes.length, - linkCount: subgraph.links.size, - inputs: subgraph.inputs.map((i) => ({ name: i.name, type: i.type })), - outputs: subgraph.outputs.map((o) => ({ name: o.name, type: o.type })), - hasInputNode: !!subgraph.inputNode, - hasOutputNode: !!subgraph.outputNode - } -} diff --git a/src/lib/litegraph/test/subgraph/fixtures/subgraphHelpers.ts b/src/lib/litegraph/test/subgraph/fixtures/subgraphHelpers.ts index fcf25ce7cb..4a3bd6c113 100644 --- a/src/lib/litegraph/test/subgraph/fixtures/subgraphHelpers.ts +++ b/src/lib/litegraph/test/subgraph/fixtures/subgraphHelpers.ts @@ -382,76 +382,6 @@ export function createTestSubgraphData( } } -/** - * Creates a complex subgraph with multiple nodes and connections. - * Useful for testing realistic scenarios. - * @param nodeCount Number of internal nodes to create - * @returns Complex subgraph data structure - */ -export function createComplexSubgraphData( - nodeCount: number = 5 -): ExportedSubgraph { - const nodes = [] - const links: Record< - string, - { - id: number - origin_id: number - origin_slot: number - target_id: number - target_slot: number - type: string - } - > = {} - - // Create internal nodes - for (let i = 0; i < nodeCount; i++) { - nodes.push({ - id: i + 1, // Start from 1 to avoid conflicts with IO nodes - type: 'basic/test', - pos: [100 + i * 150, 200], - size: [120, 60], - inputs: [{ name: 'in', type: '*', link: null }], - outputs: [{ name: 'out', type: '*', links: [] }], - properties: { value: i }, - flags: {}, - mode: 0 - }) - } - - // Create some internal links - for (let i = 0; i < nodeCount - 1; i++) { - const linkId = i + 1 - links[linkId] = { - id: linkId, - origin_id: i + 1, - origin_slot: 0, - target_id: i + 2, - target_slot: 0, - type: '*' - } - } - - return createTestSubgraphData({ - // @ts-expect-error TODO: Fix after merge - nodes parameter type - nodes, - // @ts-expect-error TODO: Fix after merge - links parameter type - links, - inputs: [ - // @ts-expect-error TODO: Fix after merge - input object type - { name: 'input1', type: 'number', pos: [0, 0] }, - // @ts-expect-error TODO: Fix after merge - input object type - { name: 'input2', type: 'string', pos: [0, 1] } - ], - outputs: [ - // @ts-expect-error TODO: Fix after merge - output object type - { name: 'output1', type: 'number', pos: [0, 0] }, - // @ts-expect-error TODO: Fix after merge - output object type - { name: 'output2', type: 'string', pos: [0, 1] } - ] - }) -} - /** * Creates an event capture system for testing event sequences. * @param eventTarget The event target to monitor @@ -493,39 +423,5 @@ export function createEventCapture( } } -/** - * Utility to log subgraph structure for debugging tests. - * @param subgraph The subgraph to inspect - * @param label Optional label for the log output - */ -export function logSubgraphStructure( - subgraph: Subgraph, - label: string = 'Subgraph' -): void { - console.log(`\n=== ${label} Structure ===`) - console.log(`Name: ${subgraph.name}`) - console.log(`ID: ${subgraph.id}`) - console.log(`Inputs: ${subgraph.inputs.length}`) - console.log(`Outputs: ${subgraph.outputs.length}`) - console.log(`Nodes: ${subgraph.nodes.length}`) - console.log(`Links: ${subgraph.links.size}`) - - if (subgraph.inputs.length > 0) { - console.log( - 'Input details:', - subgraph.inputs.map((i) => ({ name: i.name, type: i.type })) - ) - } - - if (subgraph.outputs.length > 0) { - console.log( - 'Output details:', - subgraph.outputs.map((o) => ({ name: o.name, type: o.type })) - ) - } - - console.log('========================\n') -} - // Re-export expect from vitest for convenience export { expect } from 'vitest' diff --git a/src/schemas/apiSchema.ts b/src/schemas/apiSchema.ts index 8744496659..5c86ff00cb 100644 --- a/src/schemas/apiSchema.ts +++ b/src/schemas/apiSchema.ts @@ -1,5 +1,4 @@ import { z } from 'zod' -import { fromZodError } from 'zod-validation-error' import { LinkMarkerShape } from '@/lib/litegraph/src/litegraph' import { colorPalettesSchema } from '@/schemas/colorPaletteSchema' @@ -280,18 +279,6 @@ export type PendingTaskItem = z.infer export type HistoryTaskItem = z.infer export type TaskItem = z.infer -export function validateTaskItem(taskItem: unknown) { - const result = zTaskItem.safeParse(taskItem) - if (!result.success) { - const zodError = fromZodError(result.error) - // TODO accept a callback to report error. - console.warn( - `Invalid TaskItem: ${JSON.stringify(taskItem)}\n${zodError.message}` - ) - } - return result -} - const zEmbeddingsResponse = z.array(z.string()) const zExtensionsResponse = z.array(z.string()) const zError = z.object({ diff --git a/src/schemas/comfyWorkflowSchema.ts b/src/schemas/comfyWorkflowSchema.ts index 70ebcd2794..62be3392b6 100644 --- a/src/schemas/comfyWorkflowSchema.ts +++ b/src/schemas/comfyWorkflowSchema.ts @@ -447,14 +447,11 @@ export const zSubgraphDefinition = zComfyWorkflow1 .passthrough() export type ModelFile = z.infer -export type NodeInput = z.infer -export type NodeOutput = z.infer export type ComfyLink = z.infer export type ComfyLinkObject = z.infer export type ComfyNode = z.infer export type Reroute = z.infer export type WorkflowJSON04 = z.infer -export type WorkflowJSON10 = z.infer export type ComfyWorkflowJSON = z.infer< typeof zComfyWorkflow | typeof zComfyWorkflow1 > diff --git a/src/schemas/nodeDef/nodeDefSchemaV2.ts b/src/schemas/nodeDef/nodeDefSchemaV2.ts index f94d7cc486..cb212fb99f 100644 --- a/src/schemas/nodeDef/nodeDefSchemaV2.ts +++ b/src/schemas/nodeDef/nodeDefSchemaV2.ts @@ -214,9 +214,7 @@ export type StringInputSpec = z.infer export type ComboInputSpec = z.infer export type ColorInputSpec = z.infer export type FileUploadInputSpec = z.infer -export type ImageInputSpec = z.infer export type ImageCompareInputSpec = z.infer -export type MarkdownInputSpec = z.infer export type TreeSelectInputSpec = z.infer export type MultiSelectInputSpec = z.infer export type ChartInputSpec = z.infer diff --git a/src/schemas/nodeDefSchema.ts b/src/schemas/nodeDefSchema.ts index 9370c9073c..9d4c0b2e83 100644 --- a/src/schemas/nodeDefSchema.ts +++ b/src/schemas/nodeDefSchema.ts @@ -128,30 +128,12 @@ export function isFloatInputSpec( return inputSpec[0] === 'FLOAT' } -export function isBooleanInputSpec( - inputSpec: InputSpec -): inputSpec is BooleanInputSpec { - return inputSpec[0] === 'BOOLEAN' -} - -export function isStringInputSpec( - inputSpec: InputSpec -): inputSpec is StringInputSpec { - return inputSpec[0] === 'STRING' -} - export function isComboInputSpecV2( inputSpec: InputSpec ): inputSpec is ComboInputSpecV2 { return inputSpec[0] === 'COMBO' } -export function isCustomInputSpec( - inputSpec: InputSpec -): inputSpec is CustomInputSpec { - return typeof inputSpec[0] === 'string' && !excludedLiterals.has(inputSpec[0]) -} - export function isComboInputSpec( inputSpec: InputSpec ): inputSpec is ComboInputSpec | ComboInputSpecV2 { @@ -247,22 +229,13 @@ export type ComfyOutputTypesSpec = z.infer export type ComfyNodeDef = z.infer export type RemoteWidgetConfig = z.infer -// Input specs -export type IntInputOptions = z.infer -export type FloatInputOptions = z.infer -export type BooleanInputOptions = z.infer -export type StringInputOptions = z.infer export type ComboInputOptions = z.infer -export type BaseInputOptions = z.infer export type NumericInputOptions = z.infer export type IntInputSpec = z.infer export type FloatInputSpec = z.infer -export type BooleanInputSpec = z.infer -export type StringInputSpec = z.infer export type ComboInputSpec = z.infer export type ComboInputSpecV2 = z.infer -export type CustomInputSpec = z.infer export type InputSpec = z.infer export function validateComfyNodeDef( diff --git a/src/schemas/signInSchema.ts b/src/schemas/signInSchema.ts index 0e1e4905d7..1e5a44198a 100644 --- a/src/schemas/signInSchema.ts +++ b/src/schemas/signInSchema.ts @@ -10,8 +10,6 @@ export const apiKeySchema = z.object({ .length(72, t('validation.length', { length: 72 })) }) -export type ApiKeyData = z.infer - export const signInSchema = z.object({ email: z .string() @@ -42,8 +40,6 @@ export const updatePasswordSchema = passwordSchema.refine( } ) -export type UpdatePasswordData = z.infer - export const signUpSchema = passwordSchema .extend({ email: z diff --git a/src/scripts/domWidget.ts b/src/scripts/domWidget.ts index ea2158326d..1b081facd2 100644 --- a/src/scripts/domWidget.ts +++ b/src/scripts/domWidget.ts @@ -375,17 +375,3 @@ LGraphNode.prototype.addDOMWidget = function < return widget } - -/** - * Prunes widgets that are no longer in the graph. - * @param nodes The nodes to prune widgets for. - */ -export const pruneWidgets = (nodes: LGraphNode[]) => { - const nodeSet = new Set(nodes) - const domWidgetStore = useDomWidgetStore() - for (const { widget } of domWidgetStore.widgetStates.values()) { - if (!nodeSet.has(widget.node)) { - domWidgetStore.unregisterWidget(widget.id) - } - } -} diff --git a/src/scripts/utils.ts b/src/scripts/utils.ts index 778b712d93..59556523b5 100644 --- a/src/scripts/utils.ts +++ b/src/scripts/utils.ts @@ -17,6 +17,7 @@ export function clone(obj: T): T { } /** + * @knipIgnoreUnusedButUsedByCustomNodes * @deprecated Use `applyTextReplacements` from `@/utils/searchAndReplace` instead * There are external callers to this function, so we need to keep it for now */ @@ -24,6 +25,7 @@ export function applyTextReplacements(app: ComfyApp, value: string): string { return _applyTextReplacements(app.graph, value) } +/** @knipIgnoreUnusedButUsedByCustomNodes */ export async function addStylesheet( urlOrFile: string, relativeTo?: string diff --git a/src/types/algoliaTypes.ts b/src/types/algoliaTypes.ts index 07fd335967..de42fb78a4 100644 --- a/src/types/algoliaTypes.ts +++ b/src/types/algoliaTypes.ts @@ -1,7 +1,4 @@ -import type { - BaseSearchParamsWithoutQuery, - Hit -} from 'algoliasearch/dist/lite/browser' +import type { BaseSearchParamsWithoutQuery } from 'algoliasearch/dist/lite/browser' import type { components } from '@/types/comfyRegistryTypes' @@ -13,15 +10,6 @@ type SafeNestedProperty< type RegistryNodePack = components['schemas']['Node'] -/** - * Result of searching the Algolia index. - * Represents the entire result of a search query. - */ -export type SearchPacksResult = { - nodePacks: Hit[] - querySuggestions: Hit[] -} - /** * Node pack record after it has been mapped to Algolia index format. * @see https://github.com/Comfy-Org/comfy-api/blob/main/mapper/algolia.go diff --git a/src/types/comfyManagerTypes.ts b/src/types/comfyManagerTypes.ts index e59a814802..c536197198 100644 --- a/src/types/comfyManagerTypes.ts +++ b/src/types/comfyManagerTypes.ts @@ -2,7 +2,6 @@ import type { InjectionKey, Ref } from 'vue' import type { AlgoliaNodePack } from '@/types/algoliaTypes' import type { components } from '@/types/comfyRegistryTypes' -import type { components as managerComponents } from '@/types/generatedManagerTypes' export type RegistryPack = components['schemas']['Node'] export type MergedNodePack = RegistryPack & AlgoliaNodePack @@ -10,16 +9,9 @@ export const isMergedNodePack = ( nodePack: RegistryPack | AlgoliaNodePack ): nodePack is MergedNodePack => 'comfy_nodes' in nodePack -export type PackField = keyof RegistryPack | null - export const IsInstallingKey: InjectionKey> = Symbol('isInstalling') -export enum ManagerWsQueueStatus { - DONE = 'all-done', - IN_PROGRESS = 'in_progress' -} - export enum ManagerTab { All = 'all', Installed = 'installed', @@ -34,31 +26,12 @@ export interface TabItem { icon: string } -export enum ManagerSortField { - Author = 'author', - CreateDate = 'creation_date', - LastUpdateDate = 'last_update', - Name = 'name', - Stars = 'stars', - Size = 'size' -} - -export enum PackEnableState { - Enabled, - Disabled, - NotInstalled -} - export type TaskLog = { taskName: string taskId: string logs: string[] } -export interface ManagerQueueOptions { - maxConcurrent?: number -} - export interface UseNodePacksOptions { immediate?: boolean maxConcurrent?: number @@ -83,13 +56,3 @@ export interface ManagerState { searchMode: 'nodes' | 'packs' sortField: string } - -/** - * Types for import failure information API - */ -export type ImportFailInfoBulkRequest = - managerComponents['schemas']['ImportFailInfoBulkRequest'] -export type ImportFailInfoBulkResponse = - managerComponents['schemas']['ImportFailInfoBulkResponse'] -export type ImportFailInfoItem = - managerComponents['schemas']['ImportFailInfoItem'] diff --git a/src/types/conflictDetectionTypes.ts b/src/types/conflictDetectionTypes.ts index c513782ab8..a176e0ea0d 100644 --- a/src/types/conflictDetectionTypes.ts +++ b/src/types/conflictDetectionTypes.ts @@ -9,9 +9,6 @@ import type { components } from './comfyRegistryTypes' // Re-export core types from Registry API export type Node = components['schemas']['Node'] -export type NodeVersion = components['schemas']['NodeVersion'] -export type NodeStatus = components['schemas']['NodeStatus'] -export type NodeVersionStatus = components['schemas']['NodeVersionStatus'] /** * Conflict types that can be detected in the system @@ -27,22 +24,6 @@ export type ConflictType = | 'banned' // Banned package | 'pending' // Security verification pending -/** - * Version comparison operators - * @enum {string} - */ -export type VersionOperator = '>=' | '>' | '<=' | '<' | '==' | '!=' - -/** - * Version requirement specification - */ -export interface VersionRequirement { - /** @description Comparison operator for version checking */ - operator: VersionOperator - /** @description Target version string */ - version: string -} - /** * Node Pack requirements from Registry API * Extends Node type with additional installation and compatibility metadata diff --git a/src/types/searchBoxTypes.ts b/src/types/searchBoxTypes.ts index d80140590d..b25d268bef 100644 --- a/src/types/searchBoxTypes.ts +++ b/src/types/searchBoxTypes.ts @@ -1,9 +1,3 @@ -export enum LinkReleaseTriggerMode { - ALWAYS = 'always', - HOLD_SHIFT = 'hold shift', - NOT_HOLD_SHIFT = 'NOT hold shift' -} - export enum LinkReleaseTriggerAction { CONTEXT_MENU = 'context menu', SEARCH_BOX = 'search box', diff --git a/src/types/serverArgs.ts b/src/types/serverArgs.ts index 011f030d34..83f0216c08 100644 --- a/src/types/serverArgs.ts +++ b/src/types/serverArgs.ts @@ -20,15 +20,6 @@ export enum HashFunction { SHA512 = 'sha512' } -export enum AutoLaunch { - // Let server decide whether to auto launch based on the current environment - Auto = 'auto', - // Disable auto launch - Disable = 'disable', - // Enable auto launch - Enable = 'enable' -} - export enum CudaMalloc { // Let server decide whether to use CUDA malloc based on the current environment Auto = 'auto', diff --git a/src/types/settingTypes.ts b/src/types/settingTypes.ts index af706fb149..47b3a8a36b 100644 --- a/src/types/settingTypes.ts +++ b/src/types/settingTypes.ts @@ -25,13 +25,6 @@ export interface SettingOption { value?: any } -export interface Setting { - id: keyof Settings - onChange?: (value: any, oldValue?: any) => void - name: string - render: () => HTMLElement -} - export interface SettingParams extends FormItem { id: keyof Settings defaultValue: any | (() => any) diff --git a/src/utils/formatUtil.ts b/src/utils/formatUtil.ts index da933d3ec5..7f9ba35829 100644 --- a/src/utils/formatUtil.ts +++ b/src/utils/formatUtil.ts @@ -33,10 +33,6 @@ export function appendJsonExt(path: string) { return path } -export function trimJsonExt(path?: string) { - return path?.replace(/\.json$/, '') -} - export function highlightQuery(text: string, query: string) { if (!query) return text @@ -80,28 +76,6 @@ export function formatSize(value?: number) { return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}` } -/** - * Finds the common directory prefix between two paths - * @example - * findCommonPrefix('a/b/c', 'a/b/d') // returns 'a/b' - * findCommonPrefix('x/y/z', 'a/b/c') // returns '' - * findCommonPrefix('a/b/c', 'a/b/c/d') // returns 'a/b/c' - */ -export function findCommonPrefix(path1: string, path2: string): string { - const parts1 = path1.split('/') - const parts2 = path2.split('/') - - const commonParts: string[] = [] - for (let i = 0; i < Math.min(parts1.length, parts2.length); i++) { - if (parts1[i] === parts2[i]) { - commonParts.push(parts1[i]) - } else { - break - } - } - return commonParts.join('/') -} - /** * Returns various filename components. * Example: @@ -423,26 +397,6 @@ export function compareVersions( return 0 } -/** - * Converts a currency amount to Metronome's integer representation. - * For USD, converts to cents (multiplied by 100). - * For all other currencies (including custom pricing units), returns the amount as is. - * This is specific to Metronome's API requirements. - * - * @param amount - The amount in currency to convert - * @param currency - The currency to convert - * @returns The amount in Metronome's integer format (cents for USD, base units for others) - * @example - * toMetronomeCurrency(1.23, 'usd') // returns 123 (cents) - * toMetronomeCurrency(1000, 'jpy') // returns 1000 (yen) - */ -export function toMetronomeCurrency(amount: number, currency: string): number { - if (currency === 'usd') { - return Math.round(amount * 100) - } - return amount -} - /** * Converts Metronome's integer amount back to a formatted currency string. * For USD, converts from cents to dollars. diff --git a/src/utils/nodeDefUtil.ts b/src/utils/nodeDefUtil.ts index 65c1475c47..efd6772532 100644 --- a/src/utils/nodeDefUtil.ts +++ b/src/utils/nodeDefUtil.ts @@ -15,7 +15,6 @@ import { isFloatInputSpec, isIntInputSpec } from '@/schemas/nodeDefSchema' -import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore' import { lcm } from './mathUtil' @@ -139,11 +138,3 @@ export const mergeInputSpec = ( return mergeCommonInputSpec(spec1, spec2) } - -/** - * Checks if a node definition represents a subgraph node. - * Subgraph nodes are created with category='subgraph' and python_module='nodes'. - */ -export const isSubgraphNode = (nodeDef: ComfyNodeDefImpl): boolean => { - return nodeDef.category === 'subgraph' && nodeDef.python_module === 'nodes' -} diff --git a/src/utils/versionUtil.ts b/src/utils/versionUtil.ts index 2688b234f7..61337b2aa8 100644 --- a/src/utils/versionUtil.ts +++ b/src/utils/versionUtil.ts @@ -29,34 +29,6 @@ export function satisfiesVersion(version: string, range: string): boolean { } } -/** - * Compares two versions and returns the difference type - * @param version1 First version - * @param version2 Second version - * @returns Difference type or null if comparison fails - */ -export function getVersionDifference( - version1: string, - version2: string -): semver.ReleaseType | null { - try { - const clean1 = cleanVersion(version1) - const clean2 = cleanVersion(version2) - return semver.diff(clean1, clean2) - } catch { - return null - } -} - -/** - * Checks if a version is valid according to semver - * @param version Version string to validate - * @returns true if version is valid - */ -export function isValidVersion(version: string): boolean { - return semver.valid(version) !== null -} - /** * Checks version compatibility and returns conflict details. * Supports all semver ranges including >=, <=, >, <, ~, ^ operators. diff --git a/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap b/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap index de81f64e79..87faf8fd4f 100644 --- a/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap +++ b/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap @@ -113,16 +113,7 @@ LiteGraphGlobal { "Reroute": [Function], "SPLINE_LINK": 2, "STRAIGHT_LINK": 0, - "SlotDirection": { - "1": "Up", - "2": "Down", - "3": "Left", - "4": "Right", - "Down": 2, - "Left": 3, - "Right": 4, - "Up": 1, - }, + "SlotDirection": {}, "SlotShape": { "1": "Box", "3": "Circle", diff --git a/tests-ui/tests/litegraph/subgraph/fixtures/subgraphFixtures.ts b/tests-ui/tests/litegraph/subgraph/fixtures/subgraphFixtures.ts index e4a255b2f2..88a3db3fb4 100644 --- a/tests-ui/tests/litegraph/subgraph/fixtures/subgraphFixtures.ts +++ b/tests-ui/tests/litegraph/subgraph/fixtures/subgraphFixtures.ts @@ -169,140 +169,3 @@ export const subgraphTest = test.extend({ capture.cleanup() } }) - -/** - * Fixtures that test edge cases and error conditions. - * These may leave the system in an invalid state and should be used carefully. - */ -export interface EdgeCaseFixtures { - /** Subgraph with circular references (for testing recursion detection) */ - circularSubgraph: { - rootGraph: LGraph - subgraphA: Subgraph - subgraphB: Subgraph - nodeA: SubgraphNode - nodeB: SubgraphNode - } - - /** Deeply nested subgraphs approaching the theoretical limit */ - deeplyNestedSubgraph: ReturnType - - /** Subgraph with maximum inputs and outputs */ - maxIOSubgraph: Subgraph -} - -/** - * Test with edge case fixtures. Use sparingly and with caution. - * These tests may intentionally create invalid states. - */ -export const edgeCaseTest = subgraphTest.extend({ - // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern - circularSubgraph: async ({}, use: (value: unknown) => Promise) => { - const rootGraph = new LGraph() - - // Create two subgraphs that will reference each other - const subgraphA = createTestSubgraph({ - name: 'Subgraph A', - inputs: [{ name: 'input', type: '*' }], - outputs: [{ name: 'output', type: '*' }] - }) - - const subgraphB = createTestSubgraph({ - name: 'Subgraph B', - inputs: [{ name: 'input', type: '*' }], - outputs: [{ name: 'output', type: '*' }] - }) - - // Create instances (this doesn't create circular refs by itself) - const nodeA = createTestSubgraphNode(subgraphA, { pos: [100, 100] }) - const nodeB = createTestSubgraphNode(subgraphB, { pos: [300, 100] }) - - // Add nodes to root graph - rootGraph.add(nodeA) - rootGraph.add(nodeB) - - await use({ - rootGraph, - subgraphA, - subgraphB, - nodeA, - nodeB - }) - }, - - // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern - deeplyNestedSubgraph: async ({}, use: (value: unknown) => Promise) => { - // Create a very deep nesting structure (but not exceeding MAX_NESTED_SUBGRAPHS) - const nested = createNestedSubgraphs({ - depth: 50, // Deep but reasonable - nodesPerLevel: 1, - inputsPerSubgraph: 1, - outputsPerSubgraph: 1 - }) - - await use(nested) - }, - - // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern - maxIOSubgraph: async ({}, use: (value: unknown) => Promise) => { - // Create a subgraph with many inputs and outputs - const inputs = Array.from({ length: 20 }, (_, i) => ({ - name: `input_${i}`, - type: i % 2 === 0 ? 'number' : ('string' as const) - })) - - const outputs = Array.from({ length: 20 }, (_, i) => ({ - name: `output_${i}`, - type: i % 2 === 0 ? 'number' : ('string' as const) - })) - - const subgraph = createTestSubgraph({ - name: 'Max IO Subgraph', - inputs, - outputs, - nodeCount: 10 - }) - - await use(subgraph) - } -}) - -/** - * Helper to verify fixture integrity. - * Use this in tests to ensure fixtures are properly set up. - */ -export function verifyFixtureIntegrity>( - fixture: T, - expectedProperties: (keyof T)[] -): void { - for (const prop of expectedProperties) { - if (!(prop in fixture)) { - throw new Error(`Fixture missing required property: ${String(prop)}`) - } - if (fixture[prop] === undefined || fixture[prop] === null) { - throw new Error(`Fixture property ${String(prop)} is null or undefined`) - } - } -} - -/** - * Creates a snapshot-friendly representation of a subgraph for testing. - * Useful for serialization tests and regression detection. - */ -export function createSubgraphSnapshot(subgraph: Subgraph) { - return { - id: subgraph.id, - name: subgraph.name, - inputCount: subgraph.inputs.length, - outputCount: subgraph.outputs.length, - nodeCount: subgraph.nodes.length, - linkCount: subgraph.links.size, - inputs: subgraph.inputs.map((i) => ({ name: i.name, type: i.type })), - outputs: subgraph.outputs.map((o) => ({ name: o.name, type: o.type })), - hasInputNode: !!subgraph.inputNode, - hasOutputNode: !!subgraph.outputNode - } -} diff --git a/tests-ui/tests/litegraph/subgraph/fixtures/subgraphHelpers.ts b/tests-ui/tests/litegraph/subgraph/fixtures/subgraphHelpers.ts index fcf25ce7cb..4a3bd6c113 100644 --- a/tests-ui/tests/litegraph/subgraph/fixtures/subgraphHelpers.ts +++ b/tests-ui/tests/litegraph/subgraph/fixtures/subgraphHelpers.ts @@ -382,76 +382,6 @@ export function createTestSubgraphData( } } -/** - * Creates a complex subgraph with multiple nodes and connections. - * Useful for testing realistic scenarios. - * @param nodeCount Number of internal nodes to create - * @returns Complex subgraph data structure - */ -export function createComplexSubgraphData( - nodeCount: number = 5 -): ExportedSubgraph { - const nodes = [] - const links: Record< - string, - { - id: number - origin_id: number - origin_slot: number - target_id: number - target_slot: number - type: string - } - > = {} - - // Create internal nodes - for (let i = 0; i < nodeCount; i++) { - nodes.push({ - id: i + 1, // Start from 1 to avoid conflicts with IO nodes - type: 'basic/test', - pos: [100 + i * 150, 200], - size: [120, 60], - inputs: [{ name: 'in', type: '*', link: null }], - outputs: [{ name: 'out', type: '*', links: [] }], - properties: { value: i }, - flags: {}, - mode: 0 - }) - } - - // Create some internal links - for (let i = 0; i < nodeCount - 1; i++) { - const linkId = i + 1 - links[linkId] = { - id: linkId, - origin_id: i + 1, - origin_slot: 0, - target_id: i + 2, - target_slot: 0, - type: '*' - } - } - - return createTestSubgraphData({ - // @ts-expect-error TODO: Fix after merge - nodes parameter type - nodes, - // @ts-expect-error TODO: Fix after merge - links parameter type - links, - inputs: [ - // @ts-expect-error TODO: Fix after merge - input object type - { name: 'input1', type: 'number', pos: [0, 0] }, - // @ts-expect-error TODO: Fix after merge - input object type - { name: 'input2', type: 'string', pos: [0, 1] } - ], - outputs: [ - // @ts-expect-error TODO: Fix after merge - output object type - { name: 'output1', type: 'number', pos: [0, 0] }, - // @ts-expect-error TODO: Fix after merge - output object type - { name: 'output2', type: 'string', pos: [0, 1] } - ] - }) -} - /** * Creates an event capture system for testing event sequences. * @param eventTarget The event target to monitor @@ -493,39 +423,5 @@ export function createEventCapture( } } -/** - * Utility to log subgraph structure for debugging tests. - * @param subgraph The subgraph to inspect - * @param label Optional label for the log output - */ -export function logSubgraphStructure( - subgraph: Subgraph, - label: string = 'Subgraph' -): void { - console.log(`\n=== ${label} Structure ===`) - console.log(`Name: ${subgraph.name}`) - console.log(`ID: ${subgraph.id}`) - console.log(`Inputs: ${subgraph.inputs.length}`) - console.log(`Outputs: ${subgraph.outputs.length}`) - console.log(`Nodes: ${subgraph.nodes.length}`) - console.log(`Links: ${subgraph.links.size}`) - - if (subgraph.inputs.length > 0) { - console.log( - 'Input details:', - subgraph.inputs.map((i) => ({ name: i.name, type: i.type })) - ) - } - - if (subgraph.outputs.length > 0) { - console.log( - 'Output details:', - subgraph.outputs.map((o) => ({ name: o.name, type: o.type })) - ) - } - - console.log('========================\n') -} - // Re-export expect from vitest for convenience export { expect } from 'vitest'