diff --git a/src/lib/litegraph/src/interfaces.ts b/src/lib/litegraph/src/interfaces.ts index aad3dff3fa..9df7339af1 100644 --- a/src/lib/litegraph/src/interfaces.ts +++ b/src/lib/litegraph/src/interfaces.ts @@ -254,7 +254,10 @@ type KeysOfType = Exclude< > /** The names of all (optional) methods and functions in T */ -export type MethodNames = KeysOfType any) | undefined> +export type MethodNames = KeysOfType< + T, + ((...args: unknown[]) => unknown) | undefined +> export interface NewNodePosition { node: LGraphNode newPos: { @@ -459,28 +462,6 @@ export interface ISubgraphInput extends INodeInputSlot { _subgraphSlot: SubgraphInput } -/** - * Shorthand for {@link Parameters} of optional callbacks. - * @example - * ```ts - * const { onClick } = CustomClass.prototype - * CustomClass.prototype.onClick = function (...args: CallbackParams) { - * const r = onClick?.apply(this, args) - * // ... - * return r - * } - * ``` - */ -export type CallbackParams any) | undefined> = - Parameters> - -/** - * Shorthand for {@link ReturnType} of optional callbacks. - * @see {@link CallbackParams} - */ -export type CallbackReturn any) | undefined> = - ReturnType> - /** * An object that can be hovered over. */ diff --git a/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts b/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts index 9e9454a817..366dbb96d3 100644 --- a/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts +++ b/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts @@ -4,11 +4,7 @@ import { InvalidLinkError } from '@/lib/litegraph/src/infrastructure/InvalidLink import { NullGraphError } from '@/lib/litegraph/src/infrastructure/NullGraphError' import { RecursionError } from '@/lib/litegraph/src/infrastructure/RecursionError' import { SlotIndexError } from '@/lib/litegraph/src/infrastructure/SlotIndexError' -import type { - CallbackParams, - CallbackReturn, - ISlotType -} from '@/lib/litegraph/src/interfaces' +import type { ISlotType } from '@/lib/litegraph/src/interfaces' import { LGraphEventMode, LiteGraph } from '@/lib/litegraph/src/litegraph' import type { Subgraph } from './Subgraph' @@ -45,8 +41,8 @@ type ResolvedInput = { */ export class ExecutableNodeDTO implements ExecutableLGraphNode { applyToGraph?( - ...args: CallbackParams - ): CallbackReturn + ...args: Parameters> + ): ReturnType> /** The graph that this node is a part of. */ readonly graph: LGraph | Subgraph diff --git a/src/lib/litegraph/src/subgraph/SubgraphMemory.test.ts b/src/lib/litegraph/src/subgraph/SubgraphMemory.test.ts index 7b936392a6..92699283e9 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphMemory.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphMemory.test.ts @@ -10,6 +10,12 @@ import { createTestSubgraphNode } from './__fixtures__/subgraphHelpers' +type InputWithWidget = { + _widget?: IWidget | { type: string; value: unknown; name: string } + _connection?: { id: number; type: string } + _listenerController?: AbortController +} + describe.skip('SubgraphNode Memory Management', () => { describe.skip('Event Listener Cleanup', () => { it('should register event listeners on construction', () => { @@ -308,14 +314,14 @@ describe.skip('SubgraphMemory - Widget Reference Management', () => { // Set widget reference if (input && '_widget' in input) { - ;(input as any)._widget = mockWidget - expect((input as any)._widget).toBe(mockWidget) + ;(input as InputWithWidget)._widget = mockWidget + expect((input as InputWithWidget)._widget).toBe(mockWidget) } // Clear widget reference if (input && '_widget' in input) { - ;(input as any)._widget = undefined - expect((input as any)._widget).toBeUndefined() + ;(input as InputWithWidget)._widget = undefined + expect((input as InputWithWidget)._widget).toBeUndefined() } } ) @@ -360,30 +366,34 @@ describe.skip('SubgraphMemory - Widget Reference Management', () => { // Set up references that should be cleaned up const mockReferences = { - widget: { type: 'number', value: 42 }, + widget: { type: 'number', value: 42, name: 'mock_widget' }, connection: { id: 1, type: 'number' }, listener: vi.fn() } // Set references if (input) { - ;(input as any)._widget = mockReferences.widget - ;(input as any)._connection = mockReferences.connection + ;(input as InputWithWidget)._widget = mockReferences.widget + ;(input as InputWithWidget)._connection = mockReferences.connection } if (output) { - ;(input as any)._connection = mockReferences.connection + ;(input as InputWithWidget)._connection = mockReferences.connection } // Verify references are set - expect((input as any)?._widget).toBe(mockReferences.widget) - expect((input as any)?._connection).toBe(mockReferences.connection) + expect((input as InputWithWidget)?._widget).toBe(mockReferences.widget) + expect((input as InputWithWidget)?._connection).toBe( + mockReferences.connection + ) // Simulate proper cleanup (what onRemoved should do) subgraphNode.onRemoved() // Input-specific listeners should be cleaned up (this works) if (input && '_listenerController' in input) { - expect((input as any)._listenerController?.signal.aborted).toBe(true) + expect( + (input as InputWithWidget)._listenerController?.signal.aborted + ).toBe(true) } } ) diff --git a/src/lib/litegraph/src/subgraph/SubgraphNode.test.ts b/src/lib/litegraph/src/subgraph/SubgraphNode.test.ts index 96e2e5dd38..10493cfd44 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphNode.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphNode.test.ts @@ -9,6 +9,7 @@ import { describe, expect, it, vi } from 'vitest' import type { SubgraphNode } from '@/lib/litegraph/src/litegraph' import { LGraph, Subgraph } from '@/lib/litegraph/src/litegraph' +import type { SubgraphInput } from '@/lib/litegraph/src/subgraph/SubgraphInput' import { subgraphTest } from './__fixtures__/subgraphFixtures' import { @@ -531,7 +532,7 @@ describe.skip('SubgraphNode Cleanup', () => { // Now trigger an event - only node1 should respond subgraph.events.dispatch('input-added', { - input: { name: 'test', type: 'number', id: 'test-id' } as any + input: { name: 'test', type: 'number', id: 'test-id' } as SubgraphInput }) // Only node1 should have added an input @@ -558,7 +559,7 @@ describe.skip('SubgraphNode Cleanup', () => { // Trigger an event - no nodes should respond subgraph.events.dispatch('input-added', { - input: { name: 'test', type: 'number', id: 'test-id' } as any + input: { name: 'test', type: 'number', id: 'test-id' } as SubgraphInput }) // Without cleanup: all 3 removed nodes would have added an input diff --git a/src/lib/litegraph/src/subgraph/SubgraphNode.titleButton.test.ts b/src/lib/litegraph/src/subgraph/SubgraphNode.titleButton.test.ts index c76e9d5ee0..55c9ade745 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphNode.titleButton.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphNode.titleButton.test.ts @@ -3,12 +3,18 @@ import { describe, expect, it, vi } from 'vitest' import { LGraphButton } from '@/lib/litegraph/src/litegraph' import type { LGraphCanvas } from '@/lib/litegraph/src/litegraph' +import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events' import { createTestSubgraph, createTestSubgraphNode } from './__fixtures__/subgraphHelpers' +interface MockPointerEvent { + canvasX: number + canvasY: number +} + describe.skip('SubgraphNode Title Button', () => { describe.skip('Constructor', () => { it('should automatically add enter_subgraph button', () => { @@ -58,7 +64,7 @@ describe.skip('SubgraphNode Title Button', () => { const canvas = { openSubgraph: vi.fn(), dispatch: vi.fn() - } as unknown as LGraphCanvas + } as Partial as LGraphCanvas subgraphNode.onTitleButtonClick(enterButton, canvas) @@ -78,7 +84,7 @@ describe.skip('SubgraphNode Title Button', () => { const canvas = { openSubgraph: vi.fn(), dispatch: vi.fn() - } as unknown as LGraphCanvas + } as Partial as LGraphCanvas subgraphNode.onTitleButtonClick(customButton, canvas) @@ -119,16 +125,16 @@ describe.skip('SubgraphNode Title Button', () => { const canvas = { ctx: { measureText: vi.fn().mockReturnValue({ width: 25 }) - } as unknown as CanvasRenderingContext2D, + } as Partial as CanvasRenderingContext2D, openSubgraph: vi.fn(), dispatch: vi.fn() - } as unknown as LGraphCanvas + } as Partial as LGraphCanvas // Simulate click on the enter button - const event = { + const event: MockPointerEvent = { canvasX: 275, // Near right edge where button should be canvasY: 80 // In title area - } as any + } // Calculate node-relative position const clickPosRelativeToNode: [number, number] = [ @@ -138,7 +144,7 @@ describe.skip('SubgraphNode Title Button', () => { // @ts-expect-error onMouseDown possibly undefined const handled = subgraphNode.onMouseDown( - event, + event as Partial as CanvasPointerEvent, clickPosRelativeToNode, canvas ) @@ -156,16 +162,16 @@ describe.skip('SubgraphNode Title Button', () => { const canvas = { ctx: { measureText: vi.fn().mockReturnValue({ width: 25 }) - } as unknown as CanvasRenderingContext2D, + } as Partial as CanvasRenderingContext2D, openSubgraph: vi.fn(), dispatch: vi.fn() - } as unknown as LGraphCanvas + } as Partial as LGraphCanvas // Click in the body of the node, not on button - const event = { + const event: MockPointerEvent = { canvasX: 200, // Middle of node canvasY: 150 // Body area - } as any + } // Calculate node-relative position const clickPosRelativeToNode: [number, number] = [ @@ -175,7 +181,7 @@ describe.skip('SubgraphNode Title Button', () => { // @ts-expect-error onMouseDown possibly undefined const handled = subgraphNode.onMouseDown( - event, + event as Partial as CanvasPointerEvent, clickPosRelativeToNode, canvas ) @@ -204,16 +210,16 @@ describe.skip('SubgraphNode Title Button', () => { const canvas = { ctx: { measureText: vi.fn().mockReturnValue({ width: 25 }) - } as unknown as CanvasRenderingContext2D, + } as Partial as CanvasRenderingContext2D, openSubgraph: vi.fn(), dispatch: vi.fn() - } as unknown as LGraphCanvas + } as Partial as LGraphCanvas // Try to click on where the button would be - const event = { + const event: MockPointerEvent = { canvasX: 275, canvasY: 80 - } as any + } const clickPosRelativeToNode: [number, number] = [ 275 - subgraphNode.pos[0], // 175 @@ -222,7 +228,7 @@ describe.skip('SubgraphNode Title Button', () => { // @ts-expect-error onMouseDown possibly undefined const handled = subgraphNode.onMouseDown( - event, + event as Partial as CanvasPointerEvent, clickPosRelativeToNode, canvas ) diff --git a/src/lib/litegraph/src/subgraph/SubgraphSlotVisualFeedback.test.ts b/src/lib/litegraph/src/subgraph/SubgraphSlotVisualFeedback.test.ts index baf842812f..9a85ddb185 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphSlotVisualFeedback.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphSlotVisualFeedback.test.ts @@ -1,13 +1,21 @@ // TODO: Fix these tests after migration import { beforeEach, describe, expect, it, vi } from 'vitest' +import type { DefaultConnectionColors } from '@/lib/litegraph/src/interfaces' import { LGraphNode } from '@/lib/litegraph/src/litegraph' import { createTestSubgraph } from './__fixtures__/subgraphHelpers' +interface MockColorContext { + defaultInputColor: string + defaultOutputColor: string + getConnectedColor: ReturnType + getDisconnectedColor: ReturnType +} + describe.skip('SubgraphSlot visual feedback', () => { let mockCtx: CanvasRenderingContext2D - let mockColorContext: any + let mockColorContext: MockColorContext let globalAlphaValues: number[] beforeEach(() => { @@ -34,7 +42,8 @@ describe.skip('SubgraphSlot visual feedback', () => { rect: vi.fn(), fillText: vi.fn() } - mockCtx = mockContext as unknown as CanvasRenderingContext2D + mockCtx = + mockContext as Partial as CanvasRenderingContext2D // Create a mock color context mockColorContext = { @@ -42,7 +51,7 @@ describe.skip('SubgraphSlot visual feedback', () => { defaultOutputColor: '#00FF00', getConnectedColor: vi.fn().mockReturnValue('#0000FF'), getDisconnectedColor: vi.fn().mockReturnValue('#AAAAAA') - } + } as Partial as MockColorContext }) it('should render SubgraphInput slots with full opacity when dragging from compatible slot', () => { @@ -60,7 +69,8 @@ describe.skip('SubgraphSlot visual feedback', () => { // Draw the slot with a compatible fromSlot subgraphInput.draw({ ctx: mockCtx, - colorContext: mockColorContext, + colorContext: + mockColorContext as Partial as DefaultConnectionColors, fromSlot: nodeInput, editorAlpha: 1 }) @@ -80,7 +90,8 @@ describe.skip('SubgraphSlot visual feedback', () => { // Draw subgraphInput2 while dragging from subgraphInput1 (incompatible - both are outputs inside subgraph) subgraphInput2.draw({ ctx: mockCtx, - colorContext: mockColorContext, + colorContext: + mockColorContext as Partial as DefaultConnectionColors, fromSlot: subgraphInput1, editorAlpha: 1 }) @@ -105,7 +116,8 @@ describe.skip('SubgraphSlot visual feedback', () => { // Draw the slot with a compatible fromSlot subgraphOutput.draw({ ctx: mockCtx, - colorContext: mockColorContext, + colorContext: + mockColorContext as Partial as DefaultConnectionColors, fromSlot: nodeOutput, editorAlpha: 1 }) @@ -125,7 +137,8 @@ describe.skip('SubgraphSlot visual feedback', () => { // Draw subgraphOutput2 while dragging from subgraphOutput1 (incompatible - both are inputs inside subgraph) subgraphOutput2.draw({ ctx: mockCtx, - colorContext: mockColorContext, + colorContext: + mockColorContext as Partial as DefaultConnectionColors, fromSlot: subgraphOutput1, editorAlpha: 1 }) @@ -170,7 +183,8 @@ describe.skip('SubgraphSlot visual feedback', () => { // Draw the SubgraphOutput slot while dragging from a node output with incompatible type subgraphOutput.draw({ ctx: mockCtx, - colorContext: mockColorContext, + colorContext: + mockColorContext as Partial as DefaultConnectionColors, fromSlot: nodeStringOutput, editorAlpha: 1 }) diff --git a/src/lib/litegraph/src/subgraph/SubgraphWidgetPromotion.test.ts b/src/lib/litegraph/src/subgraph/SubgraphWidgetPromotion.test.ts index d47ca186d9..1d609fe017 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphWidgetPromotion.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphWidgetPromotion.test.ts @@ -18,7 +18,7 @@ import { function createNodeWithWidget( title: string, widgetType: TWidgetType = 'number', - widgetValue: any = 42, + widgetValue: unknown = 42, slotType: ISlotType = 'number', tooltip?: string ) { diff --git a/src/platform/assets/services/assetService.test.ts b/src/platform/assets/services/assetService.test.ts index e126fd66c5..7541a9eecd 100644 --- a/src/platform/assets/services/assetService.test.ts +++ b/src/platform/assets/services/assetService.test.ts @@ -67,7 +67,7 @@ const MOCK_ASSETS = { } as const // Helper functions -function mockApiResponse(assets: any[], options = {}) { +function mockApiResponse(assets: unknown[], options = {}) { const response = { assets, total: assets.length, diff --git a/src/platform/settings/settingStore.test.ts b/src/platform/settings/settingStore.test.ts index 60d7acd1c4..43b79d2fd9 100644 --- a/src/platform/settings/settingStore.test.ts +++ b/src/platform/settings/settingStore.test.ts @@ -6,6 +6,7 @@ import { useSettingStore } from '@/platform/settings/settingStore' import type { SettingParams } from '@/platform/settings/types' +import type { Settings } from '@/schemas/apiSchema' import { api } from '@/scripts/api' import { app } from '@/scripts/app' @@ -45,7 +46,7 @@ describe('useSettingStore', () => { describe('loadSettingValues', () => { it('should load settings from API', async () => { const mockSettings = { 'test.setting': 'value' } - vi.mocked(api.getSettings).mockResolvedValue(mockSettings as any) + vi.mocked(api.getSettings).mockResolvedValue(mockSettings as Settings) await store.loadSettingValues() diff --git a/src/platform/telemetry/types.ts b/src/platform/telemetry/types.ts index 07daf3874f..2ce9c7f0f9 100644 --- a/src/platform/telemetry/types.ts +++ b/src/platform/telemetry/types.ts @@ -37,6 +37,13 @@ export interface SurveyResponses { making?: string[] } +export interface SurveyResponsesNormalized extends SurveyResponses { + industry_normalized?: string + industry_raw?: string + useCase_normalized?: string + useCase_raw?: string +} + /** * Run button tracking properties */ diff --git a/src/platform/telemetry/utils/__tests__/surveyNormalization.test.ts b/src/platform/telemetry/utils/__tests__/surveyNormalization.test.ts index ea85bd6eba..059f7d67db 100644 --- a/src/platform/telemetry/utils/__tests__/surveyNormalization.test.ts +++ b/src/platform/telemetry/utils/__tests__/surveyNormalization.test.ts @@ -328,9 +328,9 @@ describe('normalizeIndustry', () => { }) it('should handle null and invalid inputs', () => { - expect(normalizeIndustry(null as any)).toBe('Other / Undefined') - expect(normalizeIndustry(undefined as any)).toBe('Other / Undefined') - expect(normalizeIndustry(123 as any)).toBe('Other / Undefined') + expect(normalizeIndustry(null)).toBe('Other / Undefined') + expect(normalizeIndustry(undefined)).toBe('Other / Undefined') + expect(normalizeIndustry(123)).toBe('Other / Undefined') }) }) @@ -508,7 +508,7 @@ describe('normalizeUseCase', () => { expect(normalizeUseCase('none')).toBe('Other / Undefined') expect(normalizeUseCase('undefined')).toBe('Other / Undefined') expect(normalizeUseCase('')).toBe('Other / Undefined') - expect(normalizeUseCase(null as any)).toBe('Other / Undefined') + expect(normalizeUseCase(null)).toBe('Other / Undefined') }) }) diff --git a/src/platform/telemetry/utils/surveyNormalization.ts b/src/platform/telemetry/utils/surveyNormalization.ts index fdffd62c7b..61e57954be 100644 --- a/src/platform/telemetry/utils/surveyNormalization.ts +++ b/src/platform/telemetry/utils/surveyNormalization.ts @@ -6,6 +6,7 @@ * Uses Fuse.js for fuzzy matching against category keywords. */ import Fuse from 'fuse.js' +import type { SurveyResponses, SurveyResponsesNormalized } from '../types' interface CategoryMapping { name: string @@ -583,21 +584,19 @@ export function normalizeUseCase(rawUseCase: unknown): string { * Apply normalization to survey responses * Creates both normalized and raw versions of responses */ -export function normalizeSurveyResponses(responses: { - industry?: string - useCase?: string - [key: string]: any -}) { - const normalized = { ...responses } +export function normalizeSurveyResponses( + responses: SurveyResponses +): SurveyResponsesNormalized { + const normalized: SurveyResponsesNormalized = { ...responses } // Normalize industry - if (responses.industry) { + if ('industry' in responses && typeof responses.industry === 'string') { normalized.industry_normalized = normalizeIndustry(responses.industry) normalized.industry_raw = responses.industry } // Normalize use case - if (responses.useCase) { + if ('useCase' in responses && typeof responses.useCase === 'string') { normalized.useCase_normalized = normalizeUseCase(responses.useCase) normalized.useCase_raw = responses.useCase }