mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-26 00:03:59 +00:00
fix: inline get_draft query field instead of flattening
This commit is contained in:
@@ -20,10 +20,8 @@ use windmill_api_auth::{
|
||||
};
|
||||
use windmill_common::workspaces::{check_deploy_rules, RuleCheckResult};
|
||||
use windmill_common::{
|
||||
user_drafts::{
|
||||
fetch_draft_only, maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery,
|
||||
},
|
||||
utils::{WithStarredInfoQuery, HTTP_CLIENT},
|
||||
user_drafts::{fetch_draft_only, maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay},
|
||||
utils::HTTP_CLIENT,
|
||||
webhook::{WebhookMessage, WebhookShared},
|
||||
DB,
|
||||
};
|
||||
@@ -1368,12 +1366,15 @@ async fn get_deployment_status(
|
||||
Ok(Json(deployment_status))
|
||||
}
|
||||
|
||||
// Fields inlined rather than flattened from WithStarredInfoQuery /
|
||||
// WithDraftQuery — see the same comment on `GetScriptByPathQuery` in
|
||||
// scripts.rs: axum's `serde_urlencoded` query extractor doesn't preserve
|
||||
// the "true"/"false" → bool conversion through `#[serde(flatten)]`.
|
||||
#[derive(Deserialize)]
|
||||
struct GetFlowByPathQuery {
|
||||
#[serde(flatten)]
|
||||
starred: WithStarredInfoQuery,
|
||||
#[serde(flatten)]
|
||||
draft: WithDraftQuery,
|
||||
with_starred_info: Option<bool>,
|
||||
#[serde(default)]
|
||||
get_draft: bool,
|
||||
}
|
||||
|
||||
async fn get_flow_by_path(
|
||||
@@ -1386,7 +1387,7 @@ async fn get_flow_by_path(
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("flows:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
let flow_o = if query.starred.with_starred_info.unwrap_or(false) {
|
||||
let flow_o = if query.with_starred_info.unwrap_or(false) {
|
||||
sqlx::query_as::<_, FlowWithStarred>(
|
||||
r#"
|
||||
SELECT
|
||||
@@ -1478,12 +1479,12 @@ async fn get_flow_by_path(
|
||||
&authed.email,
|
||||
UserDraftItemKind::Flow,
|
||||
path,
|
||||
query.draft.get_draft,
|
||||
query.get_draft,
|
||||
flow,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
None if query.draft.get_draft => {
|
||||
None if query.get_draft => {
|
||||
fetch_draft_only(&db, &w_id, &authed.email, UserDraftItemKind::Flow, path)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
|
||||
@@ -12,9 +12,7 @@ use windmill_api_auth::{
|
||||
check_scopes, maybe_refresh_folders, require_owner_of_path, ApiAuthed,
|
||||
};
|
||||
use windmill_common::{
|
||||
user_drafts::{
|
||||
fetch_draft_only, maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery,
|
||||
},
|
||||
user_drafts::{fetch_draft_only, maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay},
|
||||
utils::{BulkDeleteRequest, WithStarredInfoQuery, HTTP_CLIENT},
|
||||
webhook::{WebhookMessage, WebhookShared},
|
||||
workspaces::{check_deploy_rules, RuleCheckResult},
|
||||
@@ -1640,12 +1638,18 @@ pub async fn pick_hub_script_by_path(
|
||||
Ok::<_, Error>((status_code, headers, response))
|
||||
}
|
||||
|
||||
// NOTE: inlined fields rather than `#[serde(flatten)]` on
|
||||
// `WithStarredInfoQuery` / `WithDraftQuery`. axum's default query
|
||||
// extractor uses `serde_urlencoded`, and flatten there routes through an
|
||||
// internal map that drops type info — so `?get_draft=true` arrives as a
|
||||
// `String` and fails the inner `bool` deserializer. Inlining keeps the
|
||||
// fields on the top-level struct so `serde_urlencoded`'s own bool
|
||||
// adapter sees the value directly.
|
||||
#[derive(Deserialize)]
|
||||
struct GetScriptByPathQuery {
|
||||
#[serde(flatten)]
|
||||
starred: WithStarredInfoQuery,
|
||||
#[serde(flatten)]
|
||||
draft: WithDraftQuery,
|
||||
with_starred_info: Option<bool>,
|
||||
#[serde(default)]
|
||||
get_draft: bool,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
@@ -1660,7 +1664,7 @@ async fn get_script_by_path(
|
||||
check_scopes(&authed, || format!("scripts:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
|
||||
let script_o = if query.starred.with_starred_info.unwrap_or(false) {
|
||||
let script_o = if query.with_starred_info.unwrap_or(false) {
|
||||
sqlx::query_as::<_, ScriptWithStarred<ScriptRunnableSettingsHandle>>(
|
||||
"SELECT s.*, favorite.path IS NOT NULL as starred
|
||||
FROM script s
|
||||
@@ -1707,12 +1711,12 @@ async fn get_script_by_path(
|
||||
&authed.email,
|
||||
UserDraftItemKind::Script,
|
||||
path,
|
||||
query.draft.get_draft,
|
||||
query.get_draft,
|
||||
script,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
None if query.draft.get_draft => {
|
||||
None if query.get_draft => {
|
||||
fetch_draft_only(&db, &w_id, &authed.email, UserDraftItemKind::Script, path)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
db::{ApiAuthed, DB},
|
||||
jobs::RunJobQuery,
|
||||
users::{require_owner_of_path, require_path_read_access_for_preview, OptAuthed},
|
||||
utils::{check_scopes, WithStarredInfoQuery},
|
||||
utils::check_scopes,
|
||||
webhook_util::{WebhookMessage, WebhookShared},
|
||||
HTTP_CLIENT,
|
||||
};
|
||||
@@ -58,9 +58,7 @@ use windmill_common::{
|
||||
get_payload_tag_from_prefixed_path, resolve_delete_after_secs, schedule_job_deletion,
|
||||
JobPayload, RawCode,
|
||||
},
|
||||
user_drafts::{
|
||||
fetch_draft_only, maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery,
|
||||
},
|
||||
user_drafts::{fetch_draft_only, maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay},
|
||||
users::username_to_permissioned_as,
|
||||
utils::{
|
||||
http_get_from_hub, not_found_if_none, paginate, query_elems_from_hub, require_admin,
|
||||
@@ -548,12 +546,15 @@ async fn get_raw_app_data(
|
||||
// Ok(Json(version))
|
||||
// }
|
||||
|
||||
// Fields inlined rather than flattened from WithStarredInfoQuery /
|
||||
// WithDraftQuery — see the same comment on `GetScriptByPathQuery` in
|
||||
// scripts.rs: axum's `serde_urlencoded` query extractor doesn't preserve
|
||||
// the "true"/"false" → bool conversion through `#[serde(flatten)]`.
|
||||
#[derive(Deserialize)]
|
||||
struct GetAppQuery {
|
||||
#[serde(flatten)]
|
||||
starred: WithStarredInfoQuery,
|
||||
#[serde(flatten)]
|
||||
draft: WithDraftQuery,
|
||||
with_starred_info: Option<bool>,
|
||||
#[serde(default)]
|
||||
get_draft: bool,
|
||||
/// When no deployed app exists at this path and `get_draft` is set,
|
||||
/// `raw_app` picks which draft kind to look up (`raw_app` or `app`).
|
||||
/// Ignored when a deployed row exists — the row's own `raw_app`
|
||||
@@ -574,7 +575,7 @@ async fn get_app(
|
||||
check_scopes(&authed, || format!("apps:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
|
||||
let app_o = if query.starred.with_starred_info.unwrap_or(false) {
|
||||
let app_o = if query.with_starred_info.unwrap_or(false) {
|
||||
sqlx::query_as::<_, AppWithLastVersionAndStarred>(
|
||||
"SELECT app.id, app.path, app.summary, app.versions, app.policy, app.custom_path,
|
||||
app.extra_perms, app_version.value,
|
||||
@@ -622,18 +623,9 @@ async fn get_app(
|
||||
} else {
|
||||
UserDraftItemKind::App
|
||||
};
|
||||
maybe_overlay_draft(
|
||||
&db,
|
||||
&w_id,
|
||||
&authed.email,
|
||||
kind,
|
||||
path,
|
||||
query.draft.get_draft,
|
||||
app,
|
||||
)
|
||||
.await?
|
||||
maybe_overlay_draft(&db, &w_id, &authed.email, kind, path, query.get_draft, app).await?
|
||||
}
|
||||
None if query.draft.get_draft => {
|
||||
None if query.get_draft => {
|
||||
let kind = if query.raw_app.unwrap_or(false) {
|
||||
UserDraftItemKind::RawApp
|
||||
} else {
|
||||
|
||||
@@ -35,7 +35,7 @@ use windmill_common::{
|
||||
db::{DbWithOptAuthed, UserDB},
|
||||
error::{Error, JsonResult, Result},
|
||||
scripts::ScriptHash,
|
||||
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery},
|
||||
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay},
|
||||
utils::{not_found_if_none, paginate, Pagination, StripPath, WarnAfterExt},
|
||||
variables::{
|
||||
build_crypt, get_reserved_variables, ContextualVariable, CreateVariable, ListableVariable,
|
||||
@@ -204,12 +204,16 @@ async fn list_variables(
|
||||
Ok(Json(rows))
|
||||
}
|
||||
|
||||
// `get_draft` inlined rather than flattened from WithDraftQuery — see
|
||||
// the same comment on `GetScriptByPathQuery` in scripts.rs: axum's
|
||||
// `serde_urlencoded` query extractor doesn't preserve the "true"/"false"
|
||||
// → bool conversion through `#[serde(flatten)]`.
|
||||
#[derive(Deserialize)]
|
||||
struct GetVariableQuery {
|
||||
decrypt_secret: Option<bool>,
|
||||
include_encrypted: Option<bool>,
|
||||
#[serde(flatten)]
|
||||
draft: WithDraftQuery,
|
||||
#[serde(default)]
|
||||
get_draft: bool,
|
||||
}
|
||||
|
||||
async fn get_variable(
|
||||
@@ -311,7 +315,7 @@ async fn get_variable(
|
||||
&authed.email,
|
||||
UserDraftItemKind::Variable,
|
||||
path,
|
||||
q.draft.get_draft,
|
||||
q.get_draft,
|
||||
r,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Reference in New Issue
Block a user