ordinary 0.10.2

Ordinary CLI
Documentation
// Copyright (C) 2026 Ordinary Labs, LLC.
//
// SPDX-License-Identifier: AGPL-3.0-only

use crate::cmds::accounts::get_current_account;
use clap::Subcommand;
use ordinary_api::client::OrdinaryApiClient;
use ordinary_config::ManagedTemplate;
use std::path::Path;
use tracing::instrument;

#[derive(Subcommand, Debug)]
pub enum Templates {
    /// add a new template to the Ordinary project
    Add {
        /// template name
        name: String,
        /// HTTP route (must start with leading "/")
        route: String,
        /// MIME type for template output:
        /// [reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types)
        mime: String,
        /// whether the template is an error template
        #[arg(long, default_value_t = false)]
        error: bool,
        /// [lang]-[engine] slug for template initialization
        #[arg(short, long, default_value = "v2-rust-askama")]
        managed: ManagedTemplate,
        /// whether you'd like to immediately eject the managed
        /// template into self-managed mode.
        #[arg(short, long, default_value_t = false)]
        eject: bool,
    },
    /// ejects a managed template into a self-managed state
    Eject {
        /// template name
        name: String,
    },
    /// upload templates to application running on `ordinaryd` instance
    Upload {
        /// name of a specific template to upload (optional).
        /// will upload all when the `--name` flag is not passed.
        #[arg(short, long)]
        name: Option<String>,
    },
}

impl Templates {
    #[instrument(skip_all, name = "templates")]
    pub async fn handle(
        &self,
        api_domain: Option<&str>,
        accept_invalid_certs: bool,
        project: &str,
        insecure: bool,
    ) -> anyhow::Result<()> {
        let account = get_current_account(insecure)?;
        let client = OrdinaryApiClient::new(
            &account.host,
            &account.name,
            api_domain,
            accept_invalid_certs,
            crate::USER_AGENT,
            false,
        )?;

        match self {
            Self::Add {
                name,
                route,
                mime,
                error,
                managed,
                eject,
            } => {
                ordinary_template::modify::add(
                    Path::new(project),
                    name,
                    route,
                    mime,
                    managed,
                    *eject,
                    *error,
                    None,
                    None,
                    None,
                )?;
            }
            Self::Eject { name } => {
                ordinary_template::modify::eject(Path::new(project), name)?;
            }
            Self::Upload { name } => {
                if let Some(name) = name {
                    client.upload(project, name).await?;
                } else {
                    client.upload_all(project).await?;
                }
            }
        }

        Ok(())
    }
}