mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-25 00:01:55 +00:00
fix unsafe mutation in input picker getter (#6428)
* fix bad mutation * remove unnecessary data structure for step args
This commit is contained in:
@@ -98,14 +98,11 @@
|
||||
|
||||
loadResourceTypes()
|
||||
|
||||
let args = $state(<Record<string, any>>{})
|
||||
|
||||
onMount(() => {
|
||||
if (!testSteps) {
|
||||
sendUserToast('testSteps module not initialized. Preview will not work.', true)
|
||||
}
|
||||
testSteps?.updateStepArgs(mod.id, flowStateStore.val, flowStore?.val, previewArgs?.val)
|
||||
args = testSteps?.getStepArgs(mod.id)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -120,14 +117,17 @@
|
||||
)}
|
||||
data-arg={argName}
|
||||
>
|
||||
{#if typeof args.value == 'object' && schema?.properties?.[argName]}
|
||||
{#if schema?.properties?.[argName]}
|
||||
<ArgInput
|
||||
{resourceTypes}
|
||||
minW={false}
|
||||
autofocus={autofocus && !focusArg && i == 0}
|
||||
label={argName}
|
||||
description={schema.properties[argName].description}
|
||||
bind:value={args.value[argName]}
|
||||
bind:value={
|
||||
() => testSteps?.getStepInputArgs(mod.id, argName) ?? {},
|
||||
(v) => testSteps?.setStepInputArgs(mod.id, argName, v)
|
||||
}
|
||||
type={schema.properties[argName].type}
|
||||
oneOf={schema.properties[argName].oneOf}
|
||||
required={schema?.required?.includes(argName)}
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
let stepHistoryLoader = getStepHistoryLoaderContext()
|
||||
|
||||
export function runTestWithStepArgs() {
|
||||
runTest(testSteps.getStepArgs(mod.id)?.value)
|
||||
runTest(testSteps.getStepArgs(mod.id))
|
||||
}
|
||||
|
||||
export function loadArgsAndRunTest() {
|
||||
testSteps?.updateStepArgs(mod.id, flowStateStore.val, flowStore?.val, previewArgs?.val)
|
||||
runTest(testSteps.getStepArgs(mod.id)?.value)
|
||||
runTest(testSteps.getStepArgs(mod.id))
|
||||
}
|
||||
|
||||
export async function runTest(args: any) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
testSteps?.updateStepArgs(id, flowStateStore?.val, flowStore?.val, previewArgs?.val)
|
||||
})
|
||||
|
||||
const input = $derived(testSteps?.getStepArgs(id)?.value)
|
||||
const input = $derived(testSteps?.getStepArgs(id))
|
||||
</script>
|
||||
|
||||
<div class="p-4 pr-6 h-full overflow-y-auto">
|
||||
|
||||
@@ -6,34 +6,35 @@ import {
|
||||
getStepPropPicker,
|
||||
type PickableProperties
|
||||
} from './previousResults'
|
||||
import { evalValue, type ModuleArgs } from './utils'
|
||||
import { evalValue } from './utils'
|
||||
|
||||
export class TestSteps {
|
||||
#stepsEvaluated = $state<Record<string, ModuleArgs>>({})
|
||||
#steps = $state<Record<string, { value: any }>>({})
|
||||
#stepsEvaluated = $state<Record<string, Record<string, any>>>({})
|
||||
#steps = $state<Record<string, Record<string, any>>>({})
|
||||
|
||||
constructor() { }
|
||||
constructor() {}
|
||||
|
||||
setStepArgsManually(moduleId: string, args: Record<string, any>) {
|
||||
if (!this.#steps[moduleId]) {
|
||||
this.#steps[moduleId] = { value: {} }
|
||||
}
|
||||
this.#steps[moduleId].value = args
|
||||
this.#steps[moduleId] = args
|
||||
}
|
||||
|
||||
getStepArgs(moduleId: string): ModuleArgs {
|
||||
let args = this.#steps[moduleId]
|
||||
if (!args) {
|
||||
this.#steps[moduleId] = { value: {} }
|
||||
}
|
||||
getStepArgs(moduleId: string): Record<string, any> | undefined {
|
||||
return this.#steps[moduleId]
|
||||
}
|
||||
|
||||
getStepInputArgs(moduleId: string, argName: string): any | undefined {
|
||||
return this.#steps[moduleId]?.[argName]
|
||||
}
|
||||
|
||||
setStepArgs(moduleId: string, args: Record<string, any>) {
|
||||
this.#steps[moduleId] = args
|
||||
}
|
||||
|
||||
setStepInputArgs(moduleId: string, argName: string, value: any) {
|
||||
if (!this.#steps[moduleId]) {
|
||||
this.#steps[moduleId] = { value: {} }
|
||||
this.#steps[moduleId] = {}
|
||||
}
|
||||
this.#steps[moduleId].value = args
|
||||
this.#steps[moduleId][argName] = value
|
||||
}
|
||||
|
||||
getStepArg(moduleId: string, argName: string): any | undefined {
|
||||
@@ -42,26 +43,26 @@ export class TestSteps {
|
||||
|
||||
setEvaluatedStepArg(moduleId: string, argName: string, value: any) {
|
||||
if (!this.#steps[moduleId]) {
|
||||
this.#steps[moduleId] = { value: {} }
|
||||
this.#steps[moduleId] = {}
|
||||
}
|
||||
if (!this.#stepsEvaluated[moduleId]) {
|
||||
this.#stepsEvaluated[moduleId] = { value: {} }
|
||||
this.#stepsEvaluated[moduleId] = {}
|
||||
}
|
||||
this.#steps[moduleId].value[argName] = $state.snapshot(value)
|
||||
this.#stepsEvaluated[moduleId].value[argName] = $state.snapshot(value)
|
||||
this.#steps[moduleId][argName] = $state.snapshot(value)
|
||||
this.#stepsEvaluated[moduleId][argName] = $state.snapshot(value)
|
||||
}
|
||||
|
||||
isArgManuallySet(moduleId: string, argName: string): boolean {
|
||||
return (
|
||||
JSON.stringify(this.#steps[moduleId]?.value?.[argName]) !==
|
||||
JSON.stringify(this.#stepsEvaluated[moduleId]?.value?.[argName])
|
||||
JSON.stringify(this.#steps[moduleId]?.[argName]) !==
|
||||
JSON.stringify(this.#stepsEvaluated[moduleId]?.[argName])
|
||||
)
|
||||
}
|
||||
|
||||
getManuallyEditedArgs(moduleId: string): string[] {
|
||||
const manuallyEditedArgs: string[] = []
|
||||
|
||||
const moduleArgs = this.#steps[moduleId]?.value ?? {}
|
||||
const moduleArgs = this.#steps[moduleId] ?? {}
|
||||
|
||||
Object.keys(moduleArgs).forEach((argName) => {
|
||||
if (this.isArgManuallySet(moduleId, argName)) {
|
||||
@@ -105,8 +106,8 @@ export class TestSteps {
|
||||
const pickableProperties = stepPropPicker.pickableProperties
|
||||
|
||||
const argSnapshot = $state.snapshot(evalValue(argName, modules[0], pickableProperties, false))
|
||||
this.#stepsEvaluated[moduleId].value[argName] = argSnapshot
|
||||
this.#steps[moduleId].value[argName] = structuredClone(argSnapshot)
|
||||
this.#stepsEvaluated[moduleId][argName] = argSnapshot
|
||||
this.#steps[moduleId][argName] = structuredClone(argSnapshot)
|
||||
}
|
||||
|
||||
initializeFromSchema(
|
||||
@@ -124,21 +125,21 @@ export class TestSteps {
|
||||
const manuallyEditedArgs = this.getManuallyEditedArgs(mod.id)
|
||||
|
||||
if (!this.#steps[mod.id]) {
|
||||
this.#steps[mod.id] = { value: {} }
|
||||
this.#steps[mod.id] = {}
|
||||
}
|
||||
if (!this.#stepsEvaluated[mod.id]) {
|
||||
this.#stepsEvaluated[mod.id] = { value: {} }
|
||||
this.#stepsEvaluated[mod.id] = {}
|
||||
}
|
||||
this.#stepsEvaluated[mod.id].value = $state.snapshot(args)
|
||||
this.#stepsEvaluated[mod.id] = $state.snapshot(args)
|
||||
|
||||
// Preserve manually edited args
|
||||
const argsSnapshot = $state.snapshot(args)
|
||||
Object.keys(argsSnapshot).forEach((key) => {
|
||||
if (manuallyEditedArgs.includes(key)) {
|
||||
argsSnapshot[key] = this.#steps[mod.id]?.value?.[key]
|
||||
argsSnapshot[key] = this.#steps[mod.id]?.[key]
|
||||
}
|
||||
})
|
||||
this.#steps[mod.id].value = argsSnapshot
|
||||
this.#steps[mod.id] = argsSnapshot
|
||||
}
|
||||
|
||||
updateStepArgs(
|
||||
@@ -177,11 +178,11 @@ export class TestSteps {
|
||||
return
|
||||
}
|
||||
const nargs = {}
|
||||
Object.keys(this.#stepsEvaluated[moduleId]?.value ?? {}).forEach((key) => {
|
||||
Object.keys(this.#stepsEvaluated[moduleId] ?? {}).forEach((key) => {
|
||||
if (keys.includes(key)) {
|
||||
nargs[key] = this.#stepsEvaluated[moduleId]?.value?.[key]
|
||||
nargs[key] = this.#stepsEvaluated[moduleId]?.[key]
|
||||
}
|
||||
})
|
||||
this.#stepsEvaluated[moduleId].value = nargs
|
||||
this.#stepsEvaluated[moduleId] = nargs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ return ${eval_string}
|
||||
}`
|
||||
}
|
||||
|
||||
export type ModuleArgs = { value: Record<string, any> }
|
||||
|
||||
function make_context_evaluator(eval_string, context): (context) => any {
|
||||
let template = create_context_function_template(eval_string, context)
|
||||
let functor = Function(template)
|
||||
|
||||
Reference in New Issue
Block a user