import { CustomIconName } from 'components/CustomIcon' import { AllMachines } from 'hooks/useStateMachineCommands' import { AnyStateMachine, ContextFrom, EventFrom, InterpreterFrom, } from 'xstate' import { Selection } from './selections' type Icon = CustomIconName const PLATFORMS = ['both', 'web', 'desktop'] as const const INPUT_TYPES = ['options', 'string', 'number', 'selection'] as const export type CommandInputType = (typeof INPUT_TYPES)[number] export type CommandSetSchema = Partial<{ [EventType in EventFrom['type']]: Record }> export type CommandSet< T extends AllMachines, Schema extends CommandSetSchema > = Partial<{ [EventType in EventFrom['type']]: Command< T, EventFrom['type'], Schema[EventType] > }> export type CommandSetConfig< T extends AllMachines, Schema extends CommandSetSchema > = Partial<{ [EventType in EventFrom['type']]: CommandConfig< T, EventFrom['type'], Schema[EventType] > }> export type Command< T extends AnyStateMachine = AnyStateMachine, CommandName extends EventFrom['type'] = EventFrom['type'], CommandSchema extends CommandSetSchema[CommandName] = CommandSetSchema[CommandName] > = { name: CommandName ownerMachine: T['id'] needsReview: boolean onSubmit: (data?: CommandSchema) => void onCancel?: () => void args?: { [ArgName in keyof CommandSchema]: CommandArgument } description?: string icon?: Icon hide?: (typeof PLATFORMS)[number] } export type CommandConfig< T extends AnyStateMachine = AnyStateMachine, CommandName extends EventFrom['type'] = EventFrom['type'], CommandSchema extends CommandSetSchema[CommandName] = CommandSetSchema[CommandName] > = Omit< Command, 'name' | 'ownerMachine' | 'onSubmit' | 'onCancel' | 'args' | 'needsReview' > & { needsReview?: true args?: { [ArgName in keyof CommandSchema]: CommandArgumentConfig< CommandSchema[ArgName], T > } } export type CommandArgumentConfig< OutputType, T extends AnyStateMachine = AnyStateMachine > = | { description?: string required: boolean skip?: true defaultValue?: OutputType | ((context: ContextFrom) => OutputType) } & ( | { inputType: Extract options: | CommandArgumentOption[] | ((context: ContextFrom) => CommandArgumentOption[]) } | { inputType: Extract selectionTypes: Selection['type'][] multiple: boolean } | { inputType: Exclude } ) export type CommandArgument< OutputType, T extends AnyStateMachine = AnyStateMachine > = | { description?: string required: boolean skip?: true defaultValue?: OutputType | ((context: ContextFrom) => OutputType) } & ( | { inputType: Extract options: CommandArgumentOption[] } | { inputType: Extract selectionTypes: Selection['type'][] actor: InterpreterFrom multiple: boolean } | { inputType: Exclude } ) export type CommandArgumentWithName< OutputType, T extends AnyStateMachine = AnyStateMachine > = CommandArgument & { name: string } export type CommandArgumentOption = { name: string isCurrent?: boolean value: A }