Skip to main content

worker/
secret_store.rs

1use crate::{
2    error::Error,
3    send::{SendFuture, SendWrapper},
4    EnvBinding, Result,
5};
6use wasm_bindgen::{JsCast, JsValue};
7use wasm_bindgen_futures::JsFuture;
8
9/// A binding to a Cloudflare Secret Store secret.
10///
11/// Each `[[secrets_store_secrets]]` entry in your wrangler.toml maps a single
12/// secret (identified by `store_id` + `secret_name`) to a binding name.
13/// Use [`SecretStore::get`] to retrieve the secret value.
14#[derive(Debug, Clone)]
15pub struct SecretStore(SendWrapper<worker_sys::SecretStoreSys>);
16
17// Workers will never allow multithreading.
18unsafe impl Send for SecretStore {}
19unsafe impl Sync for SecretStore {}
20
21impl EnvBinding for SecretStore {
22    const TYPE_NAME: &'static str = "Fetcher";
23}
24
25impl JsCast for SecretStore {
26    fn instanceof(val: &JsValue) -> bool {
27        val.is_instance_of::<worker_sys::SecretStoreSys>()
28    }
29
30    fn unchecked_from_js(val: JsValue) -> Self {
31        Self(SendWrapper::new(val.unchecked_into()))
32    }
33
34    fn unchecked_from_js_ref(val: &JsValue) -> &Self {
35        unsafe { &*(val as *const JsValue as *const Self) }
36    }
37}
38
39impl AsRef<JsValue> for SecretStore {
40    fn as_ref(&self) -> &JsValue {
41        self.0.as_ref()
42    }
43}
44
45impl From<JsValue> for SecretStore {
46    fn from(val: JsValue) -> Self {
47        Self::unchecked_from_js(val)
48    }
49}
50
51impl From<SecretStore> for JsValue {
52    fn from(secret_store: SecretStore) -> Self {
53        let sys_obj: &worker_sys::SecretStoreSys = secret_store.0.as_ref();
54        sys_obj.clone().into()
55    }
56}
57
58impl SecretStore {
59    /// Get a secret value from the secret store.
60    ///
61    /// Returns `Ok(None)` if the secret doesn't exist,
62    /// or propagates any JS error that occurs.
63    pub async fn get(&self) -> Result<Option<String>> {
64        let promise = self.0.get().map_err(Error::from)?;
65
66        let fut = SendFuture::new(JsFuture::from(promise));
67
68        let output = fut.await.map_err(Error::from)?;
69
70        if output.is_null() || output.is_undefined() {
71            Ok(None)
72        } else {
73            Ok(Some(::serde_wasm_bindgen::from_value(output)?))
74        }
75    }
76}