uarp-sdk 0.5.7

Async Rust client for the UARP (Snaga) Universal Agent Runtime Platform API
Documentation
// Code generated by @uarp/codegen from spec/openapi.json. DO NOT EDIT.
//!
//! Spec registry — publish, search, yank, share spec artifacts

#![allow(unused_imports, clippy::too_many_arguments)]

use reqwest::Method;
use serde::{Deserialize, Serialize};

use crate::client::{Client, Request, NO_BODY, NO_QUERY};
use crate::error::Result;
use crate::generated::models;
use crate::multipart::{field_text, FilePart};
use crate::util::encode_path;

/// Query and header parameters for `registryAdminListSpecs`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RegistryAdminListSpecsParams {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub limit: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub cursor: Option<String>,
}

/// Query and header parameters for `registryGetFile`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RegistryGetFileParams {
    /// Relative path within the artifact.
    pub path: String,
}

/// Query and header parameters for `registrySearch`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RegistrySearchParams {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub q: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub scope: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub category: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub keyword: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub limit: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub cursor: Option<String>,
}

/// Spec registry — publish, search, yank, share spec artifacts
#[derive(Debug, Clone)]
pub struct RegistryApi {
    pub(crate) client: Client,
}

impl Client {
    /// Spec registry — publish, search, yank, share spec artifacts
    pub fn registry(&self) -> RegistryApi {
        RegistryApi { client: self.clone() }
    }
}

impl RegistryApi {
    /// Admin: list all specs (regardless of visibility)
    ///
    /// `GET /api/v1/registry/admin/specs`
    pub async fn registry_admin_list_specs(&self, params: &RegistryAdminListSpecsParams) -> Result<models::RegistryAdminListSpecsResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/registry/admin/specs".to_string(),
                query: Some(params),
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Download tarball/artifact bundle for a spec version
    ///
    /// `GET /api/v1/registry/spec/{scope}/{name}/{version}/artifact`
    pub async fn registry_get_artifact(&self, scope: &str, name: &str, version: &str) -> Result<bytes::Bytes> {
        self.client
            .request_bytes(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/spec/{}/{}/{}/artifact", encode_path(scope), encode_path(name), encode_path(version)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get a single file from inside a spec version artifact
    ///
    /// `GET /api/v1/registry/spec/{scope}/{name}/{version}/file`
    pub async fn registry_get_file(&self, scope: &str, name: &str, version: &str, params: &RegistryGetFileParams) -> Result<models::RegistryGetFileResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/spec/{}/{}/{}/file", encode_path(scope), encode_path(name), encode_path(version)),
                query: Some(params),
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get README for a spec version
    ///
    /// `GET /api/v1/registry/spec/{scope}/{name}/{version}/readme`
    pub async fn registry_get_readme(&self, scope: &str, name: &str, version: &str) -> Result<models::RegistryGetReadmeResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/spec/{}/{}/{}/readme", encode_path(scope), encode_path(name), encode_path(version)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get share/visibility settings for a spec
    ///
    /// `GET /api/v1/registry/spec/{scope}/{name}/share`
    pub async fn registry_get_share(&self, scope: &str, name: &str) -> Result<models::RegistryGetShareResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/spec/{}/{}/share", encode_path(scope), encode_path(name)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get sparse-index entry for a spec
    ///
    /// `GET /api/v1/registry/index/{shard}/{scope}/{name}`
    pub async fn registry_get_sparse_index(&self, shard: &str, scope: &str, name: &str) -> Result<models::RegistryGetSparseIndexResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/index/{}/{}/{}", encode_path(shard), encode_path(scope), encode_path(name)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get spec metadata (latest version pointers, owners)
    ///
    /// `GET /api/v1/registry/spec/{scope}/{name}`
    pub async fn registry_get_spec_metadata(&self, scope: &str, name: &str) -> Result<models::RegistryGetSpecMetadataResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/spec/{}/{}", encode_path(scope), encode_path(name)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get a specific version of a spec
    ///
    /// Returns the full PublishedSpec record plus a `download_url` pointing at the artifact
    /// endpoint.
    ///
    /// `GET /api/v1/registry/spec/{scope}/{name}/{version}`
    pub async fn registry_get_spec_version(&self, scope: &str, name: &str, version: &str) -> Result<models::RegistryGetSpecVersionResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/spec/{}/{}/{}", encode_path(scope), encode_path(name), encode_path(version)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// List files inside a spec version artifact
    ///
    /// `GET /api/v1/registry/spec/{scope}/{name}/{version}/files`
    pub async fn registry_list_files(&self, scope: &str, name: &str, version: &str) -> Result<models::RegistryListFilesResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/registry/spec/{}/{}/{}/files", encode_path(scope), encode_path(name), encode_path(version)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Publish a new spec version to the registry
    ///
    /// Multipart upload of a tarball + manifest. Server validates manifest, verifies optional
    /// sha256, and persists the artifact. Returns the full PublishedSpec record. `Location` header
    /// points at the version's metadata endpoint.
    ///
    /// `POST /api/v1/registry/publish`
    pub async fn registry_publish(&self, body: &models::RegistryPublishRequest) -> Result<models::RegistryPublishResponse> {
        self.client
            .request_multipart(
                Request {
                    method: Method::POST,
                    path: "/api/v1/registry/publish".to_string(),
                    query: NO_QUERY,
                    body: NO_BODY,
                    headers: Vec::new(),
                    idempotent: true,
                },
                || {
                    let mut form = reqwest::multipart::Form::new();
                    form = form.text("manifest", field_text(&body.manifest)?);
                    form = form.part("artifact", body.artifact.clone().into_part()?);
                    if let Some(value) = &body.sha256 {
                        form = form.text("sha256", field_text(value)?);
                    }
                    if let Some(value) = &body.attestation {
                        form = form.text("attestation", field_text(value)?);
                    }
                    Ok(form)
                },
            )
            .await
    }

    /// Search the registry for specs
    ///
    /// `GET /api/v1/registry/search`
    pub async fn registry_search(&self, params: &RegistrySearchParams) -> Result<models::RegistrySearchResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/registry/search".to_string(),
                query: Some(params),
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Set share/visibility settings for a spec
    ///
    /// `POST /api/v1/registry/spec/{scope}/{name}/share`
    pub async fn registry_set_share(&self, scope: &str, name: &str, body: &models::RegistrySetShareRequest) -> Result<models::RegistrySetShareResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: format!("/api/v1/registry/spec/{}/{}/share", encode_path(scope), encode_path(name)),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Reverse a yank on a published spec version
    ///
    /// `POST /api/v1/registry/spec/{scope}/{name}/{version}/unyank`
    pub async fn registry_unyank_version(&self, scope: &str, name: &str, version: &str) -> Result<()> {
        self.client
            .request_empty(Request {
                method: Method::POST,
                path: format!("/api/v1/registry/spec/{}/{}/{}/unyank", encode_path(scope), encode_path(name), encode_path(version)),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Yank (mark unsafe) a published spec version
    ///
    /// `POST /api/v1/registry/spec/{scope}/{name}/{version}/yank`
    pub async fn registry_yank_version(&self, scope: &str, name: &str, version: &str, body: &models::RegistryYankVersionRequest) -> Result<()> {
        self.client
            .request_empty(Request {
                method: Method::POST,
                path: format!("/api/v1/registry/spec/{}/{}/{}/yank", encode_path(scope), encode_path(name), encode_path(version)),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }
}