diff --git a/backend/parsers/windmill-parser-ts/src/lib.rs b/backend/parsers/windmill-parser-ts/src/lib.rs index 8cdd5ac45e..92e81fd5bd 100644 --- a/backend/parsers/windmill-parser-ts/src/lib.rs +++ b/backend/parsers/windmill-parser-ts/src/lib.rs @@ -403,71 +403,9 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) { } else { if types.len() > 1 { let one_of_values: Vec = types - .into_iter() - .map_while(|x| match &**x { - TsType::TsTypeLit(TsTypeLit { members, .. }) => { - let label = members - .iter() - .find_map(|y| match y { - TsTypeElement::TsPropertySignature( - TsPropertySignature { key, type_ann, .. }, - ) => match (&**key, type_ann) { - (Expr::Ident(Ident { sym, .. }), type_ann) => { - if sym.to_string() == "label" { - type_ann.as_ref().map(|z| match &*z.type_ann { - TsType::TsLitType(TsLitType { - lit: TsLit::Str(Str { value, .. }), - .. - }) => Some(value.to_string()), - _ => None, - }) - } else { - None - } - } - _ => None, - }, - _ => None, - }) - .flatten(); - - match label { - Some(label) => { - let properties: Vec = members - .into_iter() - .filter_map(|x| match x { - TsTypeElement::TsPropertySignature( - TsPropertySignature { key, type_ann, .. }, - ) => match (*key.to_owned(), type_ann) { - (Expr::Ident(Ident { sym, .. }), type_ann) => { - Some(ObjectProperty { - key: sym.to_string(), - typ: type_ann - .as_ref() - .map(|typ| { - Box::new( - tstype_to_typ( - &*typ.type_ann, - ) - .0, - ) - }) - .unwrap_or(Box::new(Typ::Unknown)), - }) - } - _ => None, - }, - _ => None, - }) - .collect(); - Some(OneOfVariant { label, properties }) - } - _ => None, - } - } - _ => None, - }) - .collect(); + .into_iter() + .map_while(parse_one_of_type) + .collect(); if one_of_values.len() == types.len() { return (Typ::OneOf(one_of_values), false); @@ -533,6 +471,42 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) { } } +fn parse_one_of_type(x: &Box) -> Option { + match &**x { + TsType::TsTypeLit(TsTypeLit { members, .. }) => { + let label = one_of_label(members)?; + let properties = one_of_properties(members); + Some(OneOfVariant { label, properties }) + } + _ => None, + } + } + +fn one_of_label(members: &Vec) -> Option { + members.iter().find_map(|y| { + let TsTypeElement::TsPropertySignature(TsPropertySignature { key, type_ann, .. }) = y else { return None; }; + + let Expr::Ident(Ident { sym, .. }) = &**key else { return None; }; + if sym != "label" { return None; } + + let Some(type_ann) = type_ann.as_ref() else { return None; }; + let TsType::TsLitType(TsLitType { lit: TsLit::Str(Str { value, .. }), .. }) = &*type_ann.type_ann else { return None; }; + + Some(value.to_string()) + }) +} + +fn one_of_properties(members: &Vec) -> Vec { + members.iter().filter_map(|x| { + let TsTypeElement::TsPropertySignature(TsPropertySignature { key, type_ann, .. }) = x else { return None; }; + + let Expr::Ident(Ident { sym, .. }) = *key.to_owned() else { return None; }; + let typ = type_ann.as_ref().map(|typ| Box::new(tstype_to_typ(&*typ.type_ann).0)).unwrap_or(Box::new(Typ::Unknown)); + + Some(ObjectProperty { key: sym.to_string(), typ }) + }).collect() +} + fn find_undefined(types: &Vec>) -> Option { types.into_iter().position(|x| match **x { TsType::TsKeywordType(TsKeywordType { kind, .. }) => {