mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-07 06:00:03 +00:00
[Type] Disallow type upcasting for node input spec (#2790)
This commit is contained in:
@@ -17,6 +17,7 @@ export const useBooleanWidget = () => {
|
||||
}
|
||||
|
||||
return {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
widget: node.addWidget('toggle', inputName, defaultVal, () => {}, options)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ export const useComboWidget = () => {
|
||||
|
||||
const res = {
|
||||
widget: node.addWidget('combo', inputName, defaultValue, () => {}, {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
values: options ?? inputData[0]
|
||||
}) as IComboWidget
|
||||
}
|
||||
@@ -31,6 +32,7 @@ export const useComboWidget = () => {
|
||||
node,
|
||||
widget: res.widget
|
||||
})
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
if (remote.refresh_button) remoteWidget.addRefreshButton()
|
||||
|
||||
const origOptions = res.widget.options
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { LGraphNode } from '@comfyorg/litegraph'
|
||||
import type { INumericWidget } from '@comfyorg/litegraph/dist/types/widgets'
|
||||
import _ from 'lodash'
|
||||
|
||||
import type { InputSpec } from '@/schemas/nodeDefSchema'
|
||||
import type { FloatInputOptions, InputSpec } from '@/schemas/nodeDefSchema'
|
||||
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
import { getNumberDefaults } from '@/utils/mathUtil'
|
||||
@@ -45,11 +45,14 @@ export const useFloatWidget = () => {
|
||||
settingStore.get('Comfy.FloatRoundingPrecision') || undefined
|
||||
const enableRounding = !settingStore.get('Comfy.DisableFloatRounding')
|
||||
|
||||
const { val, config } = getNumberDefaults(inputOptions, {
|
||||
defaultStep: 0.5,
|
||||
precision,
|
||||
enableRounding
|
||||
})
|
||||
const { val, config } = getNumberDefaults(
|
||||
inputOptions as FloatInputOptions,
|
||||
{
|
||||
defaultStep: 0.5,
|
||||
precision,
|
||||
enableRounding
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
widget: node.addWidget(
|
||||
@@ -57,6 +60,7 @@ export const useFloatWidget = () => {
|
||||
inputName,
|
||||
val,
|
||||
onFloatValueChange,
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
config
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,9 +44,11 @@ export const useImageUploadWidget = () => {
|
||||
const { showPreview } = isVideo ? useNodeVideo(node) : useNodeImage(node)
|
||||
|
||||
const fileFilter = isVideo ? isVideoFile : isImageFile
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
const fileComboWidget = findFileComboWidget(node, imageInputName)
|
||||
const initialFile = `${fileComboWidget.value}`
|
||||
const formatPath = (value: InternalFile) =>
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
createAnnotatedPath(value, { rootFolder: image_folder })
|
||||
|
||||
const transform = (internalValue: InternalValue): ExposedValue => {
|
||||
@@ -66,6 +68,7 @@ export const useImageUploadWidget = () => {
|
||||
|
||||
// Setup file upload handling
|
||||
const { openFileSelection } = useNodeImageUpload(node, {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
allow_batch,
|
||||
fileFilter,
|
||||
accept,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { LGraphNode } from '@comfyorg/litegraph'
|
||||
import type { INumericWidget } from '@comfyorg/litegraph/dist/types/widgets'
|
||||
|
||||
import type { InputSpec } from '@/schemas/nodeDefSchema'
|
||||
import type { InputSpec, IntInputOptions } from '@/schemas/nodeDefSchema'
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import {
|
||||
type ComfyWidgetConstructor,
|
||||
@@ -50,7 +50,7 @@ export const useIntWidget = () => {
|
||||
: 'number'
|
||||
: 'number'
|
||||
|
||||
const { val, config } = getNumberDefaults(inputOptions, {
|
||||
const { val, config } = getNumberDefaults(inputOptions as IntInputOptions, {
|
||||
defaultStep: 1,
|
||||
precision: 0,
|
||||
enableRounding: true
|
||||
@@ -58,6 +58,7 @@ export const useIntWidget = () => {
|
||||
config.precision = 0
|
||||
|
||||
const result = {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
widget: node.addWidget(widgetType, inputName, val, onValueChange, config)
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ export function useRemoteWidget<
|
||||
widget: IWidget
|
||||
}) {
|
||||
const { inputData, defaultValue, node, widget } = options
|
||||
const config: RemoteWidgetConfig = inputData[1].remote
|
||||
const config = (inputData[1]?.remote ?? {}) as RemoteWidgetConfig
|
||||
const { refresh = 0, max_retries = MAX_RETRIES } = config
|
||||
const isPermanent = refresh <= 0
|
||||
const cacheKey = createCacheKey(config)
|
||||
|
||||
@@ -82,6 +82,7 @@ export const useStringWidget = () => {
|
||||
}
|
||||
|
||||
if (inputData[1]?.dynamicPrompts != undefined)
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
res.widget.dynamicPrompts = inputData[1].dynamicPrompts
|
||||
|
||||
return res
|
||||
|
||||
@@ -1162,6 +1162,7 @@ export class GroupNodeHandler {
|
||||
def?.input?.optional?.[old.inputName]
|
||||
if (!input) continue
|
||||
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
widget.options.values = input[0]
|
||||
|
||||
if (
|
||||
|
||||
@@ -337,6 +337,7 @@ app.registerExtension({
|
||||
// @ts-expect-error ComfyNode
|
||||
['Preview3D'].includes(nodeType.comfyClass)
|
||||
) {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
nodeData.input.required.image = ['PREVIEW_3D']
|
||||
}
|
||||
},
|
||||
@@ -439,6 +440,7 @@ app.registerExtension({
|
||||
// @ts-expect-error ComfyNode
|
||||
['Preview3DAnimation'].includes(nodeType.comfyClass)
|
||||
) {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
nodeData.input.required.image = ['PREVIEW_3D_ANIMATION']
|
||||
}
|
||||
},
|
||||
|
||||
@@ -91,6 +91,7 @@ app.registerExtension({
|
||||
// @ts-expect-error ComfyNode
|
||||
['LoadAudio', 'SaveAudio', 'PreviewAudio'].includes(nodeType.comfyClass)
|
||||
) {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
nodeData.input.required.audioUI = ['AUDIO_UI']
|
||||
}
|
||||
},
|
||||
@@ -149,6 +150,7 @@ app.registerExtension({
|
||||
name: 'Comfy.UploadAudio',
|
||||
async beforeRegisterNodeDef(nodeType, nodeData: ComfyNodeDef) {
|
||||
if (nodeData?.input?.required?.audio?.[1]?.audio_upload === true) {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
nodeData.input.required.upload = ['AUDIOUPLOAD']
|
||||
}
|
||||
},
|
||||
|
||||
@@ -245,6 +245,7 @@ export class PrimitiveNode extends LGraphNode {
|
||||
if (type in ComfyWidgets) {
|
||||
widget = (ComfyWidgets[type](this, 'value', inputData, app) || {}).widget
|
||||
} else {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
widget = this.addWidget(type, 'value', null, () => {}, {})
|
||||
}
|
||||
|
||||
@@ -452,6 +453,7 @@ function getConfig(widgetName: string) {
|
||||
|
||||
function isConvertibleWidget(widget: IWidget, config: InputSpec): boolean {
|
||||
return (
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
(VALID_TYPES.includes(widget.type) || VALID_TYPES.includes(config[0])) &&
|
||||
!widget.options?.forceInput
|
||||
)
|
||||
@@ -677,6 +679,7 @@ export function mergeIfValid(
|
||||
return
|
||||
}
|
||||
getCustomConfig()[k] =
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
v1 == null ? v2 : v2 == null ? v1 : Math.max(v1, v2)
|
||||
continue
|
||||
} else if (k === 'max') {
|
||||
@@ -686,6 +689,7 @@ export function mergeIfValid(
|
||||
return
|
||||
}
|
||||
getCustomConfig()[k] =
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
v1 == null ? v2 : v2 == null ? v1 : Math.min(v1, v2)
|
||||
continue
|
||||
} else if (k === 'step') {
|
||||
@@ -703,6 +707,7 @@ export function mergeIfValid(
|
||||
v2 = v1
|
||||
v1 = a
|
||||
}
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
if (v1 % v2) {
|
||||
console.log(
|
||||
'connection rejected: steps not divisible',
|
||||
|
||||
@@ -1,24 +1,6 @@
|
||||
import type { ZodType } from 'zod'
|
||||
import { z } from 'zod'
|
||||
import { fromZodError } from 'zod-validation-error'
|
||||
|
||||
function inputSpec<TType extends ZodType, TSpec extends ZodType>(
|
||||
spec: [TType, TSpec],
|
||||
allowUpcast: boolean = true
|
||||
) {
|
||||
const [inputType, inputSpec] = spec
|
||||
// e.g. "INT" => ["INT", {}]
|
||||
const upcastTypes = allowUpcast
|
||||
? [inputType.transform((type) => [type, {}])]
|
||||
: []
|
||||
|
||||
return z.union([
|
||||
z.tuple([inputType, inputSpec]),
|
||||
z.tuple([inputType]).transform(([type]) => [type, {}]),
|
||||
...upcastTypes
|
||||
])
|
||||
}
|
||||
|
||||
const zRemoteWidgetConfig = z.object({
|
||||
route: z.string().url().or(z.string().startsWith('/')),
|
||||
refresh: z.number().gte(128).safe().or(z.number().lte(0).safe()).optional(),
|
||||
@@ -89,21 +71,27 @@ const zComboInputOptions = zBaseInputOptions.extend({
|
||||
remote: zRemoteWidgetConfig.optional()
|
||||
})
|
||||
|
||||
const zIntInputSpec = inputSpec([z.literal('INT'), zIntInputOptions])
|
||||
const zFloatInputSpec = inputSpec([z.literal('FLOAT'), zFloatInputOptions])
|
||||
const zBooleanInputSpec = inputSpec([
|
||||
z.literal('BOOLEAN'),
|
||||
zBooleanInputOptions
|
||||
const zIntInputSpec = z.tuple([z.literal('INT'), zIntInputOptions.optional()])
|
||||
const zFloatInputSpec = z.tuple([
|
||||
z.literal('FLOAT'),
|
||||
zFloatInputOptions.optional()
|
||||
])
|
||||
const zBooleanInputSpec = z.tuple([
|
||||
z.literal('BOOLEAN'),
|
||||
zBooleanInputOptions.optional()
|
||||
])
|
||||
const zStringInputSpec = z.tuple([
|
||||
z.literal('STRING'),
|
||||
zStringInputOptions.optional()
|
||||
])
|
||||
const zComboInputSpec = z.tuple([
|
||||
z.array(z.union([z.string(), z.number()])),
|
||||
zComboInputOptions.optional()
|
||||
])
|
||||
const zComboInputSpecV2 = z.tuple([
|
||||
z.literal('COMBO'),
|
||||
zComboInputOptions.optional()
|
||||
])
|
||||
const zStringInputSpec = inputSpec([z.literal('STRING'), zStringInputOptions])
|
||||
const zComboInputSpec = inputSpec(
|
||||
[z.array(z.any()), zComboInputOptions],
|
||||
/* allowUpcast=*/ false
|
||||
)
|
||||
const zComboInputSpecV2 = inputSpec(
|
||||
[z.literal('COMBO'), zComboInputOptions],
|
||||
/* allowUpcast=*/ false
|
||||
)
|
||||
|
||||
export function isComboInputSpecV1(
|
||||
inputSpec: InputSpec
|
||||
@@ -154,9 +142,9 @@ export function isComboInputSpec(
|
||||
}
|
||||
|
||||
const excludedLiterals = new Set(['INT', 'FLOAT', 'BOOLEAN', 'STRING', 'COMBO'])
|
||||
const zCustomInputSpec = inputSpec([
|
||||
const zCustomInputSpec = z.tuple([
|
||||
z.string().refine((value) => !excludedLiterals.has(value)),
|
||||
zBaseInputOptions
|
||||
zBaseInputOptions.optional()
|
||||
])
|
||||
|
||||
const zInputSpec = z.union([
|
||||
|
||||
@@ -1606,8 +1606,10 @@ export class ComfyApp {
|
||||
const widget = node.widgets[widgetNum]
|
||||
if (widget.type === 'combo') {
|
||||
if (def['input'].required?.[widget.name] !== undefined) {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
widget.options.values = def['input'].required[widget.name][0]
|
||||
} else if (def['input'].optional?.[widget.name] !== undefined) {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
widget.options.values = def['input'].optional[widget.name][0]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,11 +74,13 @@ export const useLitegraphService = () => {
|
||||
if (widgetType === 'COMBO') {
|
||||
Object.assign(
|
||||
config,
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
app.widgets.COMBO(this, inputName, inputData, app) || {}
|
||||
)
|
||||
} else {
|
||||
Object.assign(
|
||||
config,
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
app.widgets[widgetType](this, inputName, inputData, app) || {}
|
||||
)
|
||||
}
|
||||
@@ -95,6 +97,7 @@ export const useLitegraphService = () => {
|
||||
...shapeOptions,
|
||||
localized_name: st(nameKey, inputName)
|
||||
}
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
this.addInput(inputName, type, inputOptions)
|
||||
widgetCreated = false
|
||||
}
|
||||
@@ -104,15 +107,19 @@ export const useLitegraphService = () => {
|
||||
if (!inputIsRequired) {
|
||||
config.widget.options.inputIsOptional = true
|
||||
}
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
if (inputData[1]?.forceInput) {
|
||||
config.widget.options.forceInput = true
|
||||
}
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
if (inputData[1]?.defaultInput) {
|
||||
config.widget.options.defaultInput = true
|
||||
}
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
if (inputData[1]?.advanced) {
|
||||
config.widget.advanced = true
|
||||
}
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
if (inputData[1]?.hidden) {
|
||||
config.widget.hidden = true
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ export const SYSTEM_NODE_DEFS: Record<string, ComfyNodeDef> = {
|
||||
name: 'Reroute',
|
||||
display_name: 'Reroute',
|
||||
category: 'utils',
|
||||
input: { required: { '': ['*'] }, optional: {} },
|
||||
input: { required: { '': ['*', {}] }, optional: {} },
|
||||
output: ['*'],
|
||||
output_name: [''],
|
||||
output_is_list: [false],
|
||||
|
||||
@@ -47,6 +47,7 @@ export const useWidgetStore = defineStore('widget', () => {
|
||||
if (Array.isArray(inputData[0]))
|
||||
return getDefaultValue(transformComboInput(inputData))
|
||||
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
const widgetType = getWidgetType(inputData[0], inputData[1]?.name)
|
||||
|
||||
const [_, props] = inputData
|
||||
@@ -54,12 +55,14 @@ export const useWidgetStore = defineStore('widget', () => {
|
||||
if (!props) return undefined
|
||||
if (props.default) return props.default
|
||||
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
if (widgetType === 'COMBO' && props.options?.length) return props.options[0]
|
||||
if (props.remote) return 'Loading...'
|
||||
return undefined
|
||||
}
|
||||
|
||||
const transformComboInput = (inputData: InputSpec): ComboInputSpecV2 => {
|
||||
// @ts-expect-error InputSpec is not typed correctly
|
||||
return isComboInputSpecV1(inputData)
|
||||
? [
|
||||
'COMBO',
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import type { InputSpec } from '@/schemas/nodeDefSchema'
|
||||
import type {
|
||||
FloatInputOptions,
|
||||
IntInputOptions
|
||||
} from '@/schemas/nodeDefSchema'
|
||||
|
||||
export function getNumberDefaults(
|
||||
inputOptions: InputSpec[1],
|
||||
inputOptions: IntInputOptions | FloatInputOptions,
|
||||
options: {
|
||||
defaultStep: number
|
||||
precision?: number
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
const EXAMPLE_NODE_DEF: ComfyNodeDef = {
|
||||
input: {
|
||||
required: {
|
||||
ckpt_name: [['model1.safetensors', 'model2.ckpt']]
|
||||
ckpt_name: [['model1.safetensors', 'model2.ckpt'], {}]
|
||||
}
|
||||
},
|
||||
output: ['MODEL', 'CLIP', 'VAE'],
|
||||
@@ -31,8 +31,6 @@ describe('validateNodeDef', () => {
|
||||
})
|
||||
|
||||
describe.each([
|
||||
[{ ckpt_name: 'foo' }, ['foo', {}]],
|
||||
[{ ckpt_name: ['foo'] }, ['foo', {}]],
|
||||
[{ ckpt_name: ['foo', { default: 1 }] }, ['foo', { default: 1 }]],
|
||||
// Extra input spec should be preserved
|
||||
[{ ckpt_name: ['foo', { bar: 1 }] }, ['foo', { bar: 1 }]],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @ts-strict-ignore
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
import {
|
||||
BooleanInputSpec,
|
||||
ComfyInputsSpec,
|
||||
@@ -27,7 +28,7 @@ describe('ComfyInputsSpec', () => {
|
||||
hidden: {
|
||||
someHiddenValue: 42
|
||||
}
|
||||
}
|
||||
} as ComfyNodeDef['input']
|
||||
|
||||
const result = new ComfyInputsSpec(plainObject)
|
||||
|
||||
@@ -43,7 +44,7 @@ describe('ComfyInputsSpec', () => {
|
||||
intInput: ['INT', { min: 0, max: 100, default: 50 }],
|
||||
stringInput: ['STRING', { default: 'Hello', multiline: true }]
|
||||
}
|
||||
}
|
||||
} as ComfyNodeDef['input']
|
||||
|
||||
const result = new ComfyInputsSpec(plainObject)
|
||||
|
||||
@@ -68,7 +69,7 @@ describe('ComfyInputsSpec', () => {
|
||||
],
|
||||
floatInput: ['FLOAT', { min: 0, max: 1, step: 0.1 }]
|
||||
}
|
||||
}
|
||||
} as ComfyNodeDef['input']
|
||||
|
||||
const result = new ComfyInputsSpec(plainObject)
|
||||
|
||||
@@ -88,7 +89,7 @@ describe('ComfyInputsSpec', () => {
|
||||
optional: {
|
||||
comboInput: [[1, 2, 3], { default: 2 }]
|
||||
}
|
||||
}
|
||||
} as ComfyNodeDef['input']
|
||||
|
||||
const result = new ComfyInputsSpec(plainObject)
|
||||
expect(result.optional.comboInput.type).toBe('COMBO')
|
||||
@@ -100,7 +101,7 @@ describe('ComfyInputsSpec', () => {
|
||||
optional: {
|
||||
comboInput: [[1, 2, 3], {}]
|
||||
}
|
||||
}
|
||||
} as ComfyNodeDef['input']
|
||||
|
||||
const result = new ComfyInputsSpec(plainObject)
|
||||
expect(result.optional.comboInput.type).toBe('COMBO')
|
||||
@@ -113,7 +114,7 @@ describe('ComfyInputsSpec', () => {
|
||||
optional: {
|
||||
customInput: ['CUSTOM_TYPE', { default: 'custom value' }]
|
||||
}
|
||||
}
|
||||
} as ComfyNodeDef['input']
|
||||
|
||||
const result = new ComfyInputsSpec(plainObject)
|
||||
expect(result.optional.customInput.type).toBe('CUSTOM_TYPE')
|
||||
@@ -126,7 +127,7 @@ describe('ComfyInputsSpec', () => {
|
||||
someHiddenValue: 42,
|
||||
anotherHiddenValue: { nested: 'object' }
|
||||
}
|
||||
}
|
||||
} as ComfyNodeDef['input']
|
||||
|
||||
const result = new ComfyInputsSpec(plainObject)
|
||||
|
||||
@@ -163,7 +164,7 @@ describe('ComfyNodeDefImpl', () => {
|
||||
output: ['INT'],
|
||||
output_is_list: [false],
|
||||
output_name: ['intOutput']
|
||||
}
|
||||
} as ComfyNodeDef
|
||||
|
||||
const result = new ComfyNodeDefImpl(plainObject)
|
||||
|
||||
@@ -201,7 +202,7 @@ describe('ComfyNodeDefImpl', () => {
|
||||
output_is_list: [false],
|
||||
output_name: ['intOutput'],
|
||||
deprecated: true
|
||||
}
|
||||
} as ComfyNodeDef
|
||||
|
||||
const result = new ComfyNodeDefImpl(plainObject)
|
||||
expect(result.deprecated).toBe(true)
|
||||
@@ -224,7 +225,7 @@ describe('ComfyNodeDefImpl', () => {
|
||||
output: ['INT'],
|
||||
output_is_list: [false],
|
||||
output_name: ['intOutput']
|
||||
}
|
||||
} as ComfyNodeDef
|
||||
|
||||
const result = new ComfyNodeDefImpl(plainObject)
|
||||
expect(result.deprecated).toBe(true)
|
||||
@@ -393,7 +394,7 @@ describe('ComfyNodeDefImpl', () => {
|
||||
output: ['INT'],
|
||||
output_is_list: [false],
|
||||
output_name: ['result']
|
||||
}
|
||||
} as ComfyNodeDef
|
||||
|
||||
const result = new ComfyNodeDefImpl(plainObject)
|
||||
|
||||
|
||||
@@ -1,59 +1,62 @@
|
||||
// @ts-strict-ignore
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
import { NodeSearchService } from '@/services/nodeSearchService'
|
||||
import { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
|
||||
|
||||
const EXAMPLE_NODE_DEFS: ComfyNodeDefImpl[] = [
|
||||
{
|
||||
input: {
|
||||
required: {
|
||||
ckpt_name: [['model1.safetensors', 'model2.ckpt'], {}]
|
||||
}
|
||||
const EXAMPLE_NODE_DEFS: ComfyNodeDefImpl[] = (
|
||||
[
|
||||
{
|
||||
input: {
|
||||
required: {
|
||||
ckpt_name: [['model1.safetensors', 'model2.ckpt'], {}]
|
||||
}
|
||||
},
|
||||
output: ['MODEL', 'CLIP', 'VAE'],
|
||||
output_is_list: [false, false, false],
|
||||
output_name: ['MODEL', 'CLIP', 'VAE'],
|
||||
name: 'CheckpointLoaderSimple',
|
||||
display_name: 'Load Checkpoint',
|
||||
description: '',
|
||||
python_module: 'nodes',
|
||||
category: 'loaders',
|
||||
output_node: false
|
||||
},
|
||||
output: ['MODEL', 'CLIP', 'VAE'],
|
||||
output_is_list: [false, false, false],
|
||||
output_name: ['MODEL', 'CLIP', 'VAE'],
|
||||
name: 'CheckpointLoaderSimple',
|
||||
display_name: 'Load Checkpoint',
|
||||
description: '',
|
||||
python_module: 'nodes',
|
||||
category: 'loaders',
|
||||
output_node: false
|
||||
},
|
||||
{
|
||||
input: {
|
||||
required: {
|
||||
samples: ['LATENT'],
|
||||
batch_index: [
|
||||
'INT',
|
||||
{
|
||||
default: 0,
|
||||
min: 0,
|
||||
max: 63
|
||||
}
|
||||
],
|
||||
length: [
|
||||
'INT',
|
||||
{
|
||||
default: 1,
|
||||
min: 1,
|
||||
max: 64
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
output: ['LATENT'],
|
||||
output_is_list: [false],
|
||||
output_name: ['LATENT'],
|
||||
name: 'LatentFromBatch',
|
||||
display_name: 'Latent From Batch',
|
||||
description: '',
|
||||
python_module: 'nodes',
|
||||
category: 'latent/batch',
|
||||
output_node: false
|
||||
}
|
||||
].map((nodeDef) => {
|
||||
{
|
||||
input: {
|
||||
required: {
|
||||
samples: ['LATENT'],
|
||||
batch_index: [
|
||||
'INT',
|
||||
{
|
||||
default: 0,
|
||||
min: 0,
|
||||
max: 63
|
||||
}
|
||||
],
|
||||
length: [
|
||||
'INT',
|
||||
{
|
||||
default: 1,
|
||||
min: 1,
|
||||
max: 64
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
output: ['LATENT'],
|
||||
output_is_list: [false],
|
||||
output_name: ['LATENT'],
|
||||
name: 'LatentFromBatch',
|
||||
display_name: 'Latent From Batch',
|
||||
description: '',
|
||||
python_module: 'nodes',
|
||||
category: 'latent/batch',
|
||||
output_node: false
|
||||
}
|
||||
] as ComfyNodeDef[]
|
||||
).map((nodeDef: ComfyNodeDef) => {
|
||||
const def = new ComfyNodeDefImpl(nodeDef)
|
||||
def['postProcessSearchScores'] = (s) => s
|
||||
return def
|
||||
|
||||
Reference in New Issue
Block a user