mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-05 16:03:47 +00:00
fix: tolerate string app_id in GHES app config deserialization (#10923)
* fix: tolerate string app_id in GHES app config deserialization Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Rh73nHumzCbyd4Gwf6kw6 * fix: address review — strict app_id validation, drop dead variant Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Rh73nHumzCbyd4Gwf6kw6 * chore: update ee-repo-ref to b52c6471d517d979a9887f207a36347b1af376c8 This commit updates the EE repository reference after PR #767 was merged in windmill-ee-private. Previous ee-repo-ref: ab2dc653719f9d65eb10964d1e2b5bc1b94d6535 New ee-repo-ref: b52c6471d517d979a9887f207a36347b1af376c8 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Fable 5
windmill-internal-app[bot]
parent
9074de25ea
commit
af8ff38687
@@ -1 +1 @@
|
||||
6efe7a73c745c2e1377a34498523c00d89010a3d
|
||||
b52c6471d517d979a9887f207a36347b1af376c8
|
||||
|
||||
@@ -38,6 +38,25 @@ pub fn is_default<T: Default + std::cmp::PartialEq>(t: &T) -> bool {
|
||||
&T::default() == t
|
||||
}
|
||||
|
||||
pub fn maybe_number<'de, T, D>(deserializer: D) -> Result<T, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
T: FromStr + serde::Deserialize<'de>,
|
||||
<T as FromStr>::Err: Display,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum NumericOrString<T> {
|
||||
String(String),
|
||||
RawT(T),
|
||||
}
|
||||
|
||||
match NumericOrString::<T>::deserialize(deserializer)? {
|
||||
NumericOrString::String(s) => T::from_str(&s).map_err(serde::de::Error::custom),
|
||||
NumericOrString::RawT(i) => Ok(i),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn maybe_number_opt<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
@@ -85,3 +104,41 @@ where
|
||||
{
|
||||
serde::Deserialize::deserialize(deserializer).map(Some)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct WithMaybeNumber {
|
||||
#[serde(deserialize_with = "super::maybe_number")]
|
||||
n: i64,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maybe_number_accepts_number() {
|
||||
let v: WithMaybeNumber = serde_json::from_value(serde_json::json!({ "n": 12345 })).unwrap();
|
||||
assert_eq!(v.n, 12345);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maybe_number_accepts_string() {
|
||||
let v: WithMaybeNumber =
|
||||
serde_json::from_value(serde_json::json!({ "n": "12345" })).unwrap();
|
||||
assert_eq!(v.n, 12345);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maybe_number_rejects_non_numeric_string() {
|
||||
assert!(
|
||||
serde_json::from_value::<WithMaybeNumber>(serde_json::json!({ "n": "abc" })).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maybe_number_rejects_null() {
|
||||
assert!(
|
||||
serde_json::from_value::<WithMaybeNumber>(serde_json::json!({ "n": null })).is_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +283,17 @@
|
||||
placeholder: '12345',
|
||||
disabled: fieldsDisabled
|
||||
}}
|
||||
bind:value={$values['github_enterprise_app'].app_id}
|
||||
bind:value={
|
||||
() => $values['github_enterprise_app'].app_id,
|
||||
(v) => {
|
||||
// The backend expects app_id as a positive integer (i64). Reject
|
||||
// fractional/out-of-range values instead of truncating them, and store
|
||||
// undefined (never a string or 0) so the config omits the key when unset.
|
||||
const n = typeof v === 'string' ? Number(v.trim() || NaN) : (v ?? NaN)
|
||||
$values['github_enterprise_app'].app_id =
|
||||
Number.isSafeInteger(n) && n > 0 ? n : undefined
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
|
||||
Reference in New Issue
Block a user