Skip to main content

zlayer_types/
client.rs

1//! Client-facing wire types shared between the `ZLayer` daemon and SDK
2//! clients (CLI, `zlayer-docker`, `zlayer-py`, future language SDKs).
3//!
4//! These were originally defined in `zlayer-client`; they are pure serde
5//! DTOs with no transport or async state, so they live here so that
6//! crates which want the wire shapes don't have to pull in the full HTTP
7//! client.
8
9use std::collections::HashMap;
10
11use chrono::{DateTime, Utc};
12use serde::{Deserialize, Serialize};
13
14// ---------------------------------------------------------------------------
15// Session
16// ---------------------------------------------------------------------------
17
18/// Persisted CLI session record (lives at `~/.zlayer/session.json`,
19/// mode 0600 on Unix).
20///
21/// Stores the JWT returned by `POST /auth/token` (or `/auth/login`) so
22/// subsequent CLI invocations don't need to re-authenticate. The daemon
23/// client attaches `Authorization: Bearer <token>` from this record when
24/// present.
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct Session {
27    /// JWT access token.
28    pub token: String,
29    /// Email of the authenticated user (for `whoami` display).
30    pub email: String,
31    /// Token expiry. Used to warn the user before the token actually expires.
32    pub expires_at: DateTime<Utc>,
33}
34
35impl Session {
36    /// Whether the token is past its expiry.
37    #[must_use]
38    pub fn is_expired(&self) -> bool {
39        Utc::now() >= self.expires_at
40    }
41}
42
43// ---------------------------------------------------------------------------
44// Build DTOs (client-side mirrors of zlayer-api build request/response shapes)
45// ---------------------------------------------------------------------------
46
47/// Specification sent to the daemon's `POST /api/v1/build/json` endpoint to
48/// start an image build against a server-side context path.
49///
50/// Mirrors `zlayer_api::handlers::build::BuildRequestWithContext` on the
51/// wire; the server-side type is `Deserialize`-only so we carry a
52/// `Serialize` mirror here.
53#[derive(Debug, Clone, Default, Serialize)]
54pub struct BuildSpec {
55    /// Path to the build context on the daemon host. Must already exist.
56    pub context_path: String,
57    /// Runtime template name (e.g. `"node20"`) to use instead of a Dockerfile.
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub runtime: Option<String>,
60    /// Build arguments (Dockerfile `ARG` values).
61    #[serde(skip_serializing_if = "HashMap::is_empty")]
62    pub build_args: HashMap<String, String>,
63    /// Target stage for multi-stage Dockerfiles.
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub target: Option<String>,
66    /// Tags to apply to the resulting image.
67    #[serde(skip_serializing_if = "Vec::is_empty")]
68    pub tags: Vec<String>,
69    /// Disable the buildah layer cache.
70    #[serde(skip_serializing_if = "std::ops::Not::not")]
71    pub no_cache: bool,
72    /// Push the resulting image to its registry after the build succeeds.
73    #[serde(skip_serializing_if = "std::ops::Not::not")]
74    pub push: bool,
75}
76
77/// Handle returned by the daemon `start_build` endpoint. Mirrors the wire
78/// shape of `zlayer_api::handlers::build::TriggerBuildResponse` (which is
79/// `Serialize`-only, so we carry a `Deserialize` mirror here).
80///
81/// The `build_id` can be fed to `GET /api/v1/build/{id}`,
82/// `GET /api/v1/build/{id}/stream`, and `GET /api/v1/build/{id}/logs`.
83#[derive(Debug, Clone, Deserialize)]
84pub struct BuildHandle {
85    /// Unique build ID for tracking.
86    pub build_id: String,
87    /// Human-readable message from the daemon.
88    pub message: String,
89}