diff --git a/backend/windmill-common/src/flows.rs b/backend/windmill-common/src/flows.rs index 09861d6b10..fcfac158d3 100644 --- a/backend/windmill-common/src/flows.rs +++ b/backend/windmill-common/src/flows.rs @@ -816,6 +816,11 @@ pub struct McpToolValue { pub exclude_tools: Vec, } +fn is_none_or_empty_vec(expr: &Option>) -> bool +{ + expr.is_none() || expr.as_ref().unwrap().is_empty() +} + #[derive(Serialize, Debug, Clone)] #[serde( tag = "type", @@ -907,7 +912,7 @@ pub enum FlowModuleValue { concurrency_time_window_s: Option, #[serde(skip_serializing_if = "Option::is_none")] is_trigger: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if = "is_none_or_empty_vec")] assets: Option>, }, @@ -933,7 +938,7 @@ pub enum FlowModuleValue { concurrency_time_window_s: Option, #[serde(skip_serializing_if = "Option::is_none")] is_trigger: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if = "is_none_or_empty_vec")] assets: Option>, }, diff --git a/frontend/src/lib/components/FlowBuilder.svelte b/frontend/src/lib/components/FlowBuilder.svelte index 505720bd1b..2ed847bff4 100644 --- a/frontend/src/lib/components/FlowBuilder.svelte +++ b/frontend/src/lib/components/FlowBuilder.svelte @@ -43,7 +43,7 @@ import FlowImportExportMenu from './flows/header/FlowImportExportMenu.svelte' import FlowPreviewButtons from './flows/header/FlowPreviewButtons.svelte' import type { FlowEditorContext, FlowInput, FlowInputEditorState } from './flows/types' - import { cleanInputs } from './flows/utils' + import { cleanFlow } from './flows/utils.svelte' import { Calendar, Pen, @@ -267,7 +267,7 @@ } loadingDraft = true try { - const flow = cleanInputs(flowStore.val) + const flow = cleanFlow(flowStore.val) try { localStorage.removeItem('flow') localStorage.removeItem(`flow-${$pathStore}`) @@ -428,7 +428,7 @@ loadingSave = true try { - const flow = cleanInputs(flowStore.val) + const flow = cleanFlow(flowStore.val) if (flow.value?.modules) { const validationErrors: string[] = [] diff --git a/frontend/src/lib/components/FlowLoopIterationPreview.svelte b/frontend/src/lib/components/FlowLoopIterationPreview.svelte index 33f7796a93..f92072b5fd 100644 --- a/frontend/src/lib/components/FlowLoopIterationPreview.svelte +++ b/frontend/src/lib/components/FlowLoopIterationPreview.svelte @@ -4,7 +4,7 @@ import { Button } from './common' import { createEventDispatcher, getContext } from 'svelte' import type { FlowEditorContext } from './flows/types' - import { runFlowPreview } from './flows/utils' + import { runFlowPreview } from './flows/utils.svelte' import SchemaForm from './SchemaForm.svelte' import FlowStatusViewer from '../components/FlowStatusViewer.svelte' import FlowProgressBar from './flows/FlowProgressBar.svelte' diff --git a/frontend/src/lib/components/FlowPreviewContent.svelte b/frontend/src/lib/components/FlowPreviewContent.svelte index 616e7fcac5..3c5267917d 100644 --- a/frontend/src/lib/components/FlowPreviewContent.svelte +++ b/frontend/src/lib/components/FlowPreviewContent.svelte @@ -13,7 +13,7 @@ import Popover from '$lib/components/meltComponents/Popover.svelte' import { createEventDispatcher, getContext, untrack } from 'svelte' import type { FlowEditorContext } from './flows/types' - import { runFlowPreview } from './flows/utils' + import { runFlowPreview } from './flows/utils.svelte' import SchemaForm from './SchemaForm.svelte' import SchemaFormWithArgPicker from './SchemaFormWithArgPicker.svelte' import FlowStatusViewer from '../components/FlowStatusViewer.svelte' diff --git a/frontend/src/lib/components/FlowViewerInner.svelte b/frontend/src/lib/components/FlowViewerInner.svelte index e0d024e60e..7fab797408 100644 --- a/frontend/src/lib/components/FlowViewerInner.svelte +++ b/frontend/src/lib/components/FlowViewerInner.svelte @@ -9,7 +9,7 @@ import YAML from 'yaml' import { yaml } from 'svelte-highlight/languages' import HighlightTheme from './HighlightTheme.svelte' - import { filteredContentForExport } from './flows/utils' + import { filteredContentForExport } from './flows/utils.svelte' interface Props { flow: { diff --git a/frontend/src/lib/components/InputTransformForm.svelte b/frontend/src/lib/components/InputTransformForm.svelte index ca033335a9..43e4cbd924 100644 --- a/frontend/src/lib/components/InputTransformForm.svelte +++ b/frontend/src/lib/components/InputTransformForm.svelte @@ -17,7 +17,7 @@ import FieldHeader from './FieldHeader.svelte' import DynamicInputHelpBox from './flows/content/DynamicInputHelpBox.svelte' import type { PropPickerWrapperContext } from './flows/propPicker/PropPickerWrapper.svelte' - import { codeToStaticTemplate, getDefaultExpr } from './flows/utils' + import { codeToStaticTemplate, getDefaultExpr } from './flows/utils.svelte' import SimpleEditor from './SimpleEditor.svelte' import { Button, ButtonType } from '$lib/components/common' import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte' diff --git a/frontend/src/lib/components/ModulePreviewForm.svelte b/frontend/src/lib/components/ModulePreviewForm.svelte index 63b6f47ec2..b8867c75e4 100644 --- a/frontend/src/lib/components/ModulePreviewForm.svelte +++ b/frontend/src/lib/components/ModulePreviewForm.svelte @@ -7,7 +7,7 @@ import { Button } from './common' import { getContext, untrack } from 'svelte' import type { FlowEditorContext } from './flows/types' - import { evalValue } from './flows/utils' + import { evalValue } from './flows/utils.svelte' import type { FlowModule } from '$lib/gen' import type { PickableProperties } from './flows/previousResults' import type SimpleEditor from './SimpleEditor.svelte' diff --git a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte index 956cbb93a7..d7b1266868 100644 --- a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte +++ b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte @@ -49,7 +49,7 @@ import FlowModuleSkip from './FlowModuleSkip.svelte' import { type Job } from '$lib/gen' import { workspaceStore } from '$lib/stores' - import { checkIfParentLoop } from '../utils' + import { checkIfParentLoop } from '../utils.svelte' import ModulePreviewResultViewer from '$lib/components/ModulePreviewResultViewer.svelte' import { refreshStateStore } from '$lib/svelte5Utils.svelte' import { getStepHistoryLoaderContext } from '$lib/components/stepHistoryLoader.svelte' diff --git a/frontend/src/lib/components/flows/flowState.ts b/frontend/src/lib/components/flows/flowState.ts index 8ac15d32d5..05a3483702 100644 --- a/frontend/src/lib/components/flows/flowState.ts +++ b/frontend/src/lib/components/flows/flowState.ts @@ -1,7 +1,7 @@ import type { Schema } from '$lib/common' import type { Flow, FlowModule } from '$lib/gen' import { loadFlowModuleState } from './flowStateUtils.svelte' -import { emptyFlowModuleState } from './utils' +import { emptyFlowModuleState } from './utils.svelte' import type { StateStore } from '$lib/utils' export type FlowModuleState = { diff --git a/frontend/src/lib/components/flows/flowStateUtils.svelte.ts b/frontend/src/lib/components/flows/flowStateUtils.svelte.ts index c27bae97f3..4e543b7fed 100644 --- a/frontend/src/lib/components/flows/flowStateUtils.svelte.ts +++ b/frontend/src/lib/components/flows/flowStateUtils.svelte.ts @@ -13,7 +13,7 @@ import { userStore, workspaceStore } from '$lib/stores' import { getScriptByPath } from '$lib/scripts' import { get } from 'svelte/store' import type { FlowModuleState, FlowState } from './flowState' -import { emptyFlowModuleState } from './utils' +import { emptyFlowModuleState } from './utils.svelte' import { NEVER_TESTED_THIS_FAR } from './models' import { loadSchemaFromModule } from './flowInfers' import { nextId } from './flowModuleNextId' diff --git a/frontend/src/lib/components/flows/header/FlowImportExportMenu.svelte b/frontend/src/lib/components/flows/header/FlowImportExportMenu.svelte index acd8d93fce..a9cbeecabb 100644 --- a/frontend/src/lib/components/flows/header/FlowImportExportMenu.svelte +++ b/frontend/src/lib/components/flows/header/FlowImportExportMenu.svelte @@ -4,7 +4,7 @@ import FlowViewer from '$lib/components/FlowViewer.svelte' import { getContext } from 'svelte' import type { FlowEditorContext } from '../types' - import { cleanInputs } from '../utils' + import { cleanFlow } from '../utils.svelte' import { aiChatManager } from '$lib/components/copilot/chat/AIChatManager.svelte' interface Props { @@ -21,7 +21,7 @@ drawer?.toggleDrawer()}> {#if flow} - + {/if} diff --git a/frontend/src/lib/components/flows/header/FlowYamlEditor.svelte b/frontend/src/lib/components/flows/header/FlowYamlEditor.svelte index 8e51fad250..bf200ebec0 100644 --- a/frontend/src/lib/components/flows/header/FlowYamlEditor.svelte +++ b/frontend/src/lib/components/flows/header/FlowYamlEditor.svelte @@ -3,7 +3,7 @@ import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte' import { getContext } from 'svelte' import type { FlowEditorContext } from '../types' - import { filteredContentForExport } from '../utils' + import { filteredContentForExport } from '../utils.svelte' import YAML from 'yaml' import { Button } from '$lib/components/common' diff --git a/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte b/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte index 160bfb5235..0b0bcdb778 100644 --- a/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte +++ b/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte @@ -15,7 +15,7 @@ createAiAgent } from '$lib/components/flows/flowStateUtils.svelte' import type { FlowModule, Job, ScriptLang } from '$lib/gen' - import { emptyFlowModuleState } from '../utils' + import { emptyFlowModuleState } from '../utils.svelte' import { dfs } from '../dfs' import { push } from '$lib/history.svelte' diff --git a/frontend/src/lib/components/flows/map/MapItem.svelte b/frontend/src/lib/components/flows/map/MapItem.svelte index 26df6f1803..2021b10e91 100644 --- a/frontend/src/lib/components/flows/map/MapItem.svelte +++ b/frontend/src/lib/components/flows/map/MapItem.svelte @@ -12,7 +12,7 @@ isTriggerStep, type onSelectedIteration } from '$lib/components/graph/graphBuilder.svelte' - import { checkIfParentLoop } from '$lib/components/flows/utils' + import { checkIfParentLoop } from '$lib/components/flows/utils.svelte' import type { FlowEditorContext } from '$lib/components/flows/types' import { twMerge } from 'tailwind-merge' import type { FlowNodeState } from '$lib/components/graph' diff --git a/frontend/src/lib/components/flows/stepsInputArgs.svelte.ts b/frontend/src/lib/components/flows/stepsInputArgs.svelte.ts index 37ecd088cb..025bca1bfe 100644 --- a/frontend/src/lib/components/flows/stepsInputArgs.svelte.ts +++ b/frontend/src/lib/components/flows/stepsInputArgs.svelte.ts @@ -6,13 +6,13 @@ import { getStepPropPicker, type PickableProperties } from './previousResults' -import { evalValue } from './utils' +import { evalValue } from './utils.svelte' export class StepsInputArgs { #stepsEvaluated = $state>>({}) #steps = $state>>({}) - constructor() { } + constructor() {} setStepArgsManually(moduleId: string, args: Record) { this.#steps[moduleId] = args diff --git a/frontend/src/lib/components/flows/utils.ts b/frontend/src/lib/components/flows/utils.svelte.ts similarity index 93% rename from frontend/src/lib/components/flows/utils.ts rename to frontend/src/lib/components/flows/utils.svelte.ts index 2e04c2a17e..a2906ecb10 100644 --- a/frontend/src/lib/components/flows/utils.ts +++ b/frontend/src/lib/components/flows/utils.svelte.ts @@ -22,10 +22,11 @@ function create_context_function_template(eval_string: string, context: Record 0 - ? `let ${Object.keys(context).map((key) => ` ${key} = context['${key}']`)};` - : `` - } +${ + Object.keys(context).length > 0 + ? `let ${Object.keys(context).map((key) => ` ${key} = context['${key}']`)};` + : `` +} return ${eval_string} }` } @@ -93,15 +94,18 @@ export function filteredContentForExport(flow: ExtendedOpenFlow) { return o } -export function cleanInputs(flow: OpenFlow | any): OpenFlow & { +import { dfs as dfsApply } from './dfs' + +export function cleanFlow(flow: OpenFlow | any): OpenFlow & { tag?: string ws_error_handler_muted?: boolean dedicated_worker?: boolean visible_to_runner_only?: boolean on_behalf_of_email?: string } { - const newFlow: Flow = JSON.parse(JSON.stringify(flow)) - newFlow.value.modules.forEach((mod) => { + const newFlow: Flow = $state.snapshot(flow) + + dfsApply(newFlow.value.modules, (mod) => { if (mod.value.type == 'rawscript' || mod.value.type == 'script') { Object.values(mod.value.input_transforms ?? {}).forEach((inp) => { // for now we use the value for dynamic expression when done in the static editor so we have to resort to this @@ -115,6 +119,9 @@ export function cleanInputs(flow: OpenFlow | any): OpenFlow & { } }) } + if (mod.value.type == 'rawscript' && mod.value.assets?.length == 0) { + mod.value.assets = undefined + } }) if (newFlow.value.concurrency_key == '') { newFlow.value.concurrency_key = undefined diff --git a/frontend/src/lib/components/tutorials/FlowBuilderTutorialForLoop.svelte b/frontend/src/lib/components/tutorials/FlowBuilderTutorialForLoop.svelte index db0b939141..a5b6d42e58 100644 --- a/frontend/src/lib/components/tutorials/FlowBuilderTutorialForLoop.svelte +++ b/frontend/src/lib/components/tutorials/FlowBuilderTutorialForLoop.svelte @@ -1,7 +1,7 @@