mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 00:02:19 +00:00
consistent sort + minor nits
This commit is contained in:
+17
-25
@@ -1001,7 +1001,6 @@ async fn test_deno_flow(db: Pool<Postgres>) {
|
||||
path: None,
|
||||
lock: None,
|
||||
},
|
||||
input_transforms: Default::default(),
|
||||
stop_after_if: Default::default(),
|
||||
summary: Default::default(),
|
||||
suspend: Default::default(),
|
||||
@@ -1029,7 +1028,6 @@ async fn test_deno_flow(db: Pool<Postgres>) {
|
||||
path: None,
|
||||
lock: None,
|
||||
},
|
||||
input_transforms: Default::default(),
|
||||
stop_after_if: Default::default(),
|
||||
summary: Default::default(),
|
||||
suspend: Default::default(),
|
||||
@@ -1037,7 +1035,6 @@ async fn test_deno_flow(db: Pool<Postgres>) {
|
||||
sleep: None,
|
||||
}],
|
||||
},
|
||||
input_transforms: Default::default(),
|
||||
stop_after_if: Default::default(),
|
||||
summary: Default::default(),
|
||||
suspend: Default::default(),
|
||||
@@ -1131,7 +1128,6 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
path: None,
|
||||
lock: None,
|
||||
},
|
||||
input_transforms: Default::default(),
|
||||
stop_after_if: Default::default(),
|
||||
summary: Default::default(),
|
||||
suspend: Default::default(),
|
||||
@@ -1147,25 +1143,24 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
modules: vec![
|
||||
FlowModule {
|
||||
id: "d".to_string(),
|
||||
input_transforms: [
|
||||
(
|
||||
"i".to_string(),
|
||||
InputTransform::Javascript {
|
||||
expr: "flow_input.iter.value".to_string(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"loop".to_string(),
|
||||
InputTransform::Static { value: json!(true) },
|
||||
),
|
||||
(
|
||||
"path".to_string(),
|
||||
InputTransform::Static { value: json!("inner.txt") },
|
||||
),
|
||||
]
|
||||
.into(),
|
||||
value: FlowModuleValue::RawScript {
|
||||
input_transforms: [].into(),
|
||||
input_transforms: [
|
||||
(
|
||||
"i".to_string(),
|
||||
InputTransform::Javascript {
|
||||
expr: "flow_input.iter.value".to_string(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"loop".to_string(),
|
||||
InputTransform::Static { value: json!(true) },
|
||||
),
|
||||
(
|
||||
"path".to_string(),
|
||||
InputTransform::Static { value: json!("inner.txt") },
|
||||
),
|
||||
]
|
||||
.into(),
|
||||
language: ScriptLang::Deno,
|
||||
content: write_file,
|
||||
path: None,
|
||||
@@ -1196,7 +1191,6 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
path: None,
|
||||
lock: None,
|
||||
},
|
||||
input_transforms: [].into(),
|
||||
stop_after_if: Default::default(),
|
||||
summary: Default::default(),
|
||||
suspend: Default::default(),
|
||||
@@ -1205,7 +1199,6 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
},
|
||||
],
|
||||
},
|
||||
input_transforms: Default::default(),
|
||||
stop_after_if: Default::default(),
|
||||
summary: Default::default(),
|
||||
suspend: Default::default(),
|
||||
@@ -1240,7 +1233,6 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
path: None,
|
||||
lock: None,
|
||||
},
|
||||
input_transforms: [].into(),
|
||||
stop_after_if: Default::default(),
|
||||
summary: Default::default(),
|
||||
suspend: Default::default(),
|
||||
|
||||
@@ -552,7 +552,6 @@ mod tests {
|
||||
modules: vec![
|
||||
FlowModule {
|
||||
id: "a".to_string(),
|
||||
input_transforms: [].into(),
|
||||
value: FlowModuleValue::Script {
|
||||
path: "test".to_string(),
|
||||
input_transforms: [(
|
||||
@@ -570,7 +569,6 @@ mod tests {
|
||||
},
|
||||
FlowModule {
|
||||
id: "b".to_string(),
|
||||
input_transforms: HashMap::new(),
|
||||
value: FlowModuleValue::RawScript {
|
||||
input_transforms: HashMap::new(),
|
||||
content: "test".to_string(),
|
||||
@@ -589,7 +587,6 @@ mod tests {
|
||||
},
|
||||
FlowModule {
|
||||
id: "c".to_string(),
|
||||
input_transforms: HashMap::new(),
|
||||
value: FlowModuleValue::ForloopFlow {
|
||||
iterator: InputTransform::Static { value: serde_json::json!([1, 2, 3]) },
|
||||
modules: vec![],
|
||||
@@ -608,7 +605,6 @@ mod tests {
|
||||
],
|
||||
failure_module: Some(FlowModule {
|
||||
id: "d".to_string(),
|
||||
input_transforms: HashMap::new(),
|
||||
value: FlowModuleValue::Script {
|
||||
path: "test".to_string(),
|
||||
input_transforms: HashMap::new(),
|
||||
@@ -695,31 +691,6 @@ mod tests {
|
||||
assert_eq!(dbg!(serde_json::json!(fv)), dbg!(expect));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_back_compat() {
|
||||
/* renamed input_transform -> input_transforms but should deserialize old name */
|
||||
let s = r#"
|
||||
{
|
||||
"value": {
|
||||
"type": "rawscript",
|
||||
"content": "def main(n): return",
|
||||
"language": "python3"
|
||||
},
|
||||
"input_transform": {
|
||||
"n": {
|
||||
"expr": "flow_input.iter.value",
|
||||
"type": "javascript"
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let module: FlowModule = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(
|
||||
module.input_transforms["n"],
|
||||
InputTransform::Javascript { expr: "flow_input.iter.value".to_string() }
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn retry_serde() {
|
||||
assert_eq!(Retry::default(), serde_json::from_str(r#"{}"#).unwrap());
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
* LICENSE-AGPL for a copy of the license.
|
||||
*/
|
||||
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use serde::{self, Deserialize, Serialize};
|
||||
use serde::{self, Deserialize, Serialize, Serializer};
|
||||
|
||||
use crate::{
|
||||
more_serde::{
|
||||
@@ -149,9 +152,6 @@ pub struct Suspend {
|
||||
pub struct FlowModule {
|
||||
#[serde(default = "default_id")]
|
||||
pub id: String,
|
||||
#[serde(default)]
|
||||
#[serde(alias = "input_transform")]
|
||||
pub input_transforms: HashMap<String, InputTransform>,
|
||||
pub value: FlowModuleValue,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub stop_after_if: Option<StopAfterIf>,
|
||||
@@ -245,7 +245,7 @@ pub enum FlowModuleValue {
|
||||
},
|
||||
RawScript {
|
||||
#[serde(default)]
|
||||
#[serde(alias = "input_transform")]
|
||||
#[serde(alias = "input_transform", serialize_with = "ordered_map")]
|
||||
input_transforms: HashMap<String, InputTransform>,
|
||||
content: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -257,6 +257,14 @@ pub enum FlowModuleValue {
|
||||
Identity,
|
||||
}
|
||||
|
||||
fn ordered_map<S>(value: &HashMap<String, InputTransform>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let ordered: BTreeMap<_, _> = value.iter().collect();
|
||||
ordered.serialize(serializer)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ListFlowQuery {
|
||||
pub path_start: Option<String>,
|
||||
|
||||
@@ -489,7 +489,6 @@ pub async fn push<'c>(
|
||||
modules.push(FlowModule {
|
||||
id: format!("{}-v", flow.modules[flow.modules.len() - 1].id),
|
||||
value: FlowModuleValue::Identity,
|
||||
input_transforms: HashMap::new(),
|
||||
stop_after_if: None,
|
||||
summary: Some(
|
||||
"Virtual module needed for suspend/sleep when last module".to_string(),
|
||||
|
||||
@@ -1124,11 +1124,7 @@ async fn push_next_flow_job(
|
||||
transform_input(
|
||||
&flow_job.args,
|
||||
last_result.clone(),
|
||||
if !input_transforms.is_empty() {
|
||||
input_transforms
|
||||
} else {
|
||||
&module.input_transforms
|
||||
},
|
||||
input_transforms,
|
||||
resume_messages.as_slice(),
|
||||
approvers,
|
||||
by_id,
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import type { Flow, FlowModule, ForloopFlow, InputTransform } from '$lib/gen'
|
||||
import type { Flow, FlowModule } from '$lib/gen'
|
||||
import { writable, type Writable } from 'svelte/store'
|
||||
import { initFlowState, type FlowState } from './flowState'
|
||||
import { numberToChars } from './utils'
|
||||
|
||||
export type FlowMode = 'push' | 'pull'
|
||||
|
||||
export const importFlowStore = writable<Flow | undefined>(undefined)
|
||||
|
||||
|
||||
export function dfs<T>(modules: FlowModule[], f: (x: FlowModule) => T): T[] {
|
||||
let result: T[] = []
|
||||
for (const module of modules) {
|
||||
@@ -16,7 +14,15 @@ export function dfs<T>(modules: FlowModule[], f: (x: FlowModule) => T): T[] {
|
||||
result = result.concat(dfs(module.value.modules, f))
|
||||
} else if (module.value.type == 'branchone') {
|
||||
result = result.concat(f(module))
|
||||
result = result.concat(dfs(module.value.branches.map((b) => b.modules).flat().concat(module.value.default), f))
|
||||
result = result.concat(
|
||||
dfs(
|
||||
module.value.branches
|
||||
.map((b) => b.modules)
|
||||
.flat()
|
||||
.concat(module.value.default),
|
||||
f
|
||||
)
|
||||
)
|
||||
} else if (module.value.type == 'branchall') {
|
||||
result = result.concat(f(module))
|
||||
result = result.concat(dfs(module.value.branches.map((b) => b.modules).flat(), f))
|
||||
@@ -27,57 +33,13 @@ export function dfs<T>(modules: FlowModule[], f: (x: FlowModule) => T): T[] {
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
export async function initFlow(flow: Flow, flowStore: Writable<Flow>, flowStateStore: Writable<FlowState>) {
|
||||
let counter = 0
|
||||
for (const mod of flow.value.modules) {
|
||||
migrateFlowModule(mod)
|
||||
let val = mod.value
|
||||
if (val.type == 'forloopflow') {
|
||||
let flowVal = val as ForloopFlow & { value?: { modules?: FlowModule[] } }
|
||||
if (flowVal.value && flowVal.value.modules) {
|
||||
flowVal.modules = flowVal.value.modules
|
||||
flowVal.value = undefined
|
||||
}
|
||||
flowVal.modules.forEach(migrateFlowModule)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export async function initFlow(
|
||||
flow: Flow,
|
||||
flowStore: Writable<Flow>,
|
||||
flowStateStore: Writable<FlowState>
|
||||
) {
|
||||
await initFlowState(flow, flowStateStore)
|
||||
flowStore.set(flow)
|
||||
|
||||
function migrateFlowModule(mod: FlowModule) {
|
||||
if (mod.id == undefined) {
|
||||
mod.id = numberToChars(counter++)
|
||||
}
|
||||
let modVal = mod as FlowModule & {
|
||||
input_transform?: Record<string, InputTransform>
|
||||
stop_after_if_expr?: string
|
||||
skip_if_stopped?: boolean
|
||||
}
|
||||
if (modVal.input_transform) {
|
||||
modVal.input_transforms = modVal.input_transform
|
||||
delete modVal.input_transform
|
||||
}
|
||||
if (
|
||||
(modVal.input_transforms && modVal.value.type == 'script') ||
|
||||
modVal.value.type == 'rawscript'
|
||||
) {
|
||||
if (modVal.input_transforms && Object.keys(modVal.input_transforms).length > 0) {
|
||||
modVal.value.input_transforms = modVal.input_transforms
|
||||
delete modVal.input_transforms
|
||||
}
|
||||
}
|
||||
if (modVal.stop_after_if_expr) {
|
||||
modVal.stop_after_if = {
|
||||
expr: modVal.stop_after_if_expr,
|
||||
skip_if_stopped: modVal.skip_if_stopped
|
||||
}
|
||||
delete modVal.stop_after_if_expr
|
||||
delete modVal.skip_if_stopped
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function copyFirstStepSchema(flowState: FlowState, flowStore: Writable<Flow>) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ScriptService, type MainArgSignature } from '$lib/gen'
|
||||
import { get, writable } from 'svelte/store'
|
||||
import type { Schema, SchemaProperty } from './common.js'
|
||||
import { sortObject } from './utils.js'
|
||||
|
||||
const loadSchemaLastRun = writable<[string | undefined, MainArgSignature | undefined]>(undefined)
|
||||
|
||||
@@ -49,6 +50,7 @@ export async function inferArgs(
|
||||
} else {
|
||||
schema.properties[arg.name] = oldProperties[arg.name]
|
||||
}
|
||||
schema.properties[arg.name] = sortObject(schema.properties[arg.name])
|
||||
argSigToJsonSchemaType(arg.typ, schema.properties[arg.name])
|
||||
schema.properties[arg.name].default = arg.default
|
||||
|
||||
|
||||
@@ -717,3 +717,12 @@ export function getModifierKey(): string {
|
||||
export function isValidHexColor(color: string): boolean {
|
||||
return /^#(([A-F0-9]{2}){3,4}|[A-F0-9]{3})$/i.test(color)
|
||||
}
|
||||
|
||||
export function sortObject<T>(o: T & object): T {
|
||||
return Object.keys(o)
|
||||
.sort()
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = obj[key]
|
||||
return obj
|
||||
}, {}) as T
|
||||
}
|
||||
|
||||
@@ -75,11 +75,6 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
# to be removed in favor of raw/script input_transforms once migration is over
|
||||
input_transforms:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: "#/components/schemas/InputTransform"
|
||||
value:
|
||||
$ref: "#/components/schemas/FlowModuleValue"
|
||||
stop_after_if:
|
||||
@@ -327,7 +322,7 @@ components:
|
||||
type: boolean
|
||||
required:
|
||||
- type
|
||||
|
||||
|
||||
FlowStatus:
|
||||
type: object
|
||||
properties:
|
||||
@@ -344,7 +339,7 @@ components:
|
||||
properties:
|
||||
parent_module:
|
||||
type: string
|
||||
|
||||
|
||||
retry:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user