import { textOf } from '../../../model/Properties'; import type { NodeDef } from '../../NodeRegistry'; import { type EmptyMode, isEmptyValue } from '../../values'; import { any } from '../shared'; const MODES: Record = { any: 'any', nothing: 'nothing', null: 'null', }; export const FirstNotEmpty: NodeDef = { type: 'FirstNotEmpty', label: 'First not empty', category: 'data', description: 'a, unless it is empty, then b. The setting says what is empty.', inputs: [any('a'), any('b')], outputs: [any('value')], // Whatever goes in comes out: with both inputs on the same type, `value` is that type too (#207). sharedType: { inputs: ['a', 'b'], outputs: ['value'] }, params: [ { key: 'empty', label: 'Empty means', kind: 'enum', default: 'any', options: [ { value: 'any', label: 'Any empty value' }, { value: 'nothing', label: 'Nothing there (0 and false count)' }, { value: 'null', label: 'Only a missing value' }, ], }, ], run: (_ctx, inputs, params) => { // The fallback matches the param's declared default, so a node with no setting behaves // like a freshly created one. const mode = MODES[textOf(params.empty)] ?? 'any'; return { outputs: { value: (isEmptyValue(inputs.a, mode) ? inputs.b : inputs.a) ?? null } }; }, };