wrangler/upload/form/
service_worker.rs

1use anyhow::Result;
2use reqwest::blocking::multipart::{Form, Part};
3use serde::Serialize;
4
5use crate::settings::binding::Binding;
6
7use super::{ServiceWorkerAssets, UsageModel};
8
9#[derive(Serialize, Debug)]
10struct Metadata {
11    pub body_part: String,
12    pub bindings: Vec<Binding>,
13    pub usage_model: Option<UsageModel>,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub compatibility_date: Option<String>,
16    #[serde(skip_serializing_if = "Vec::is_empty")]
17    pub compatibility_flags: Vec<String>,
18}
19
20pub fn build_form(
21    assets: &ServiceWorkerAssets,
22    session_config: Option<serde_json::Value>,
23) -> Result<Form> {
24    let mut form = Form::new();
25
26    // The preview service in particular streams the request form, and requires that the
27    // "metadata" part be set first, so this order is important.
28    form = add_metadata(form, assets)?;
29    form = add_files(form, assets)?;
30    if let Some(session_config) = session_config {
31        form = add_session_config(form, session_config)?
32    }
33
34    log::info!("building form");
35    log::info!("{:#?}", &form);
36
37    Ok(form)
38}
39
40fn add_files(mut form: Form, assets: &ServiceWorkerAssets) -> Result<Form> {
41    form = form.file(assets.script_name()?, assets.script_path())?;
42
43    for wasm_module in &assets.wasm_modules {
44        form = form.file(wasm_module.filename(), wasm_module.path())?;
45    }
46
47    for text_blob in &assets.text_blobs {
48        let part = Part::text(text_blob.data.clone())
49            .file_name(text_blob.binding.clone())
50            .mime_str("text/plain")?;
51
52        form = form.part(text_blob.binding.clone(), part);
53    }
54
55    Ok(form)
56}
57
58fn add_metadata(mut form: Form, assets: &ServiceWorkerAssets) -> Result<Form> {
59    let metadata_json = serde_json::json!(&Metadata {
60        body_part: assets.script_name()?,
61        bindings: assets.bindings(),
62        usage_model: assets.usage_model,
63        compatibility_date: assets.compatibility_date.clone(),
64        compatibility_flags: assets.compatibility_flags.clone(),
65    });
66
67    let metadata = Part::text(metadata_json.to_string())
68        .file_name("metadata.json")
69        .mime_str("application/json")?;
70
71    form = form.part("metadata", metadata);
72
73    Ok(form)
74}
75
76fn add_session_config(mut form: Form, session_config: serde_json::Value) -> Result<Form> {
77    let wrangler_session_config = Part::text(session_config.to_string())
78        .file_name("")
79        .mime_str("application/json")?;
80
81    form = form.part("wrangler-session-config", wrangler_session_config);
82
83    Ok(form)
84}