ordinary-api 0.6.0-pre.13

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

use crate::client::OrdinaryApiClient;
use anyhow::bail;
use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD as b64};
use ordinary_config::OrdinaryConfig;
use ordinary_types::flexbuffer_reader_to_json;

pub async fn items_list(
    api_client: &OrdinaryApiClient<'_>,
    proj_path: &str,
    model_name: &str,
) -> anyhow::Result<String> {
    let correlation_id = api_client.correlation_id.map(|id| id.to_string());

    let config = OrdinaryConfig::get(proj_path)?;

    let mut idx = None;

    if let Some(model_configs) = &config.models {
        for model_config in model_configs {
            if model_config.name == model_name {
                idx = Some(model_config.idx);
                break;
            }
        }
    }

    let access_token = api_client.get_access(None, correlation_id.clone()).await?;

    let Some(model_idx) = idx else {
        bail!("no model by that name");
    };

    tracing::info!("fetching...");
    let mut req = api_client
        .client
        .get(format!("{}/v1/models/items", api_client.addr))
        .query(&[("d", config.domain), ("i", model_idx.to_string())])
        .header(
            "Authorization",
            format!("Bearer {}", b64.encode(access_token)),
        );

    if let Some(correlation_id) = correlation_id {
        req = req.header("x-correlation-id", correlation_id);
    }

    let res = req.send().await?.bytes().await?;

    if res.is_empty() {
        let vec: Vec<u8> = vec![];
        Ok(serde_json::to_string(&vec)?)
    } else {
        let root = flexbuffers::Reader::get_root(&res[..])?;

        let mut out = vec![];

        if let Some(models) = &config.models
            && let Some(model) = models.iter().find(|m| m.idx == model_idx)
        {
            for item in &root.as_vector() {
                let mut item_out = vec![];

                for field in &model.fields {
                    let json_val = flexbuffer_reader_to_json(
                        &field.kind,
                        &item.as_vector().idx(field.idx as usize),
                    )?;
                    item_out.push(json_val);
                }

                out.push(item_out);
            }
        }

        tracing::info!("done.");

        Ok(serde_json::to_string(&out)?)
    }
}