Skip to main content

auth_cloudflare/
schema.rs

1//! Schema - versioned JSON contract metadata for the catalog cache and the
2//! `auth-cloudflare version --format json` CLI contract (feedback 06).
3//!
4//! The Hermes plugin (`auth-hermes-cloudflare`) validates protocol and
5//! catalog-schema compatibility against `VersionInfo::current()` before
6//! invoking catalog commands; a newer unsupported schema version must be
7//! rejected rather than silently guessed (feedback 02).
8
9use serde::Serialize;
10
11/// Catalog cache/snapshot JSON schema version (integer, not SemVer).
12///
13/// Bump when the on-disk `catalog.json`/`catalog.meta.json` layout or the
14/// `catalog get --format json` envelope changes incompatibly.
15pub const CATALOG_SCHEMA_VERSION: u32 = 1;
16
17/// JSON CLI protocol version (`version`, `catalog`, `doctor` commands).
18pub const PROTOCOL_VERSION: u32 = 1;
19
20/// Version metadata returned by `auth-cloudflare version --format json`.
21#[derive(Debug, Clone, Serialize)]
22pub struct VersionInfo {
23	/// Binary/package name, e.g. `auth-cloudflare`.
24	pub name: &'static str,
25	/// Cargo package version, e.g. `0.0.1` (from `crate::VERSION`).
26	pub package_version: &'static str,
27	/// Supported JSON CLI protocol version.
28	pub protocol_version: u32,
29	/// Catalog schema versions this binary can read/write.
30	pub catalog_schema_versions: &'static [u32],
31	/// Minimum `auth-hermes-cloudflare` plugin version this binary accepts.
32	pub minimum_hermes_plugin_version: &'static str,
33}
34
35impl VersionInfo {
36	/// Current crate version metadata - single source of truth for the
37	/// `version --format json` command.
38	pub fn current() -> Self {
39		Self {
40			name: "auth-cloudflare",
41			package_version: crate::VERSION,
42			protocol_version: PROTOCOL_VERSION,
43			catalog_schema_versions: &[CATALOG_SCHEMA_VERSION],
44			minimum_hermes_plugin_version: "0.0.1",
45		}
46	}
47}
48
49#[cfg(test)]
50mod tests {
51	use super::*;
52
53	#[test]
54	fn version_info_current_matches_contract() {
55		let info = VersionInfo::current();
56		assert_eq!(info.name, "auth-cloudflare");
57		assert_eq!(info.package_version, crate::VERSION);
58		assert_eq!(info.protocol_version, 1);
59		assert_eq!(info.catalog_schema_versions, &[1]);
60		assert_eq!(info.minimum_hermes_plugin_version, "0.0.1");
61	}
62
63	#[test]
64	fn version_info_serializes_to_feedback_06_shape() {
65		let value = serde_json::to_value(VersionInfo::current()).expect("serialize");
66		let object = value.as_object().expect("object");
67		// Exact feedback-06 key set: name, package_version, protocol_version,
68		// catalog_schema_versions, minimum_hermes_plugin_version.
69		assert_eq!(
70			object.keys().cloned().collect::<std::collections::BTreeSet<_>>(),
71			[
72				"name",
73				"package_version",
74				"protocol_version",
75				"catalog_schema_versions",
76				"minimum_hermes_plugin_version",
77			]
78			.into_iter()
79			.map(String::from)
80			.collect()
81		);
82		assert_eq!(value["name"], "auth-cloudflare");
83		assert_eq!(value["package_version"], crate::VERSION);
84		assert_eq!(value["protocol_version"], 1);
85		assert_eq!(value["catalog_schema_versions"], serde_json::json!([1]));
86		assert_eq!(value["minimum_hermes_plugin_version"], "0.0.1");
87	}
88}