mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-06-09 01:35:18 +02:00
refactor: extract omnigraph-api-types crate from omnigraph-server
Move api.rs (HTTP request/response DTOs + OpenAPI schemas) into omnigraph-api-types (deps: engine, compiler, queries, serde, serde_json, utoipa). Repoint crate::queries::StoredQuery -> omnigraph_queries. Relocate the two catalog-projection tests here, where query_catalog_entry lives, eliminating the queries<->api dev-dep cycle (no cycle, tests at their boundary). Server aliases via 'pub use omnigraph_api_types as api;'. openapi.json byte-identical (drift test passes; no regen). 2 api-types tests pass; server+cli compile. No behavior change.
This commit is contained in:
parent
628ecf428a
commit
c51b9e1e20
6 changed files with 118 additions and 2 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
|
@ -4541,6 +4541,18 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "omnigraph-api-types"
|
||||
version = "0.6.1"
|
||||
dependencies = [
|
||||
"omnigraph-compiler",
|
||||
"omnigraph-engine",
|
||||
"omnigraph-queries",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"utoipa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "omnigraph-cli"
|
||||
version = "0.6.1"
|
||||
|
|
@ -4673,6 +4685,7 @@ dependencies = [
|
|||
"futures",
|
||||
"lance",
|
||||
"lance-index",
|
||||
"omnigraph-api-types",
|
||||
"omnigraph-compiler",
|
||||
"omnigraph-config",
|
||||
"omnigraph-engine",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ members = [
|
|||
"crates/omnigraph-server",
|
||||
"crates/omnigraph-config",
|
||||
"crates/omnigraph-queries",
|
||||
"crates/omnigraph-api-types",
|
||||
]
|
||||
default-members = [
|
||||
"crates/omnigraph",
|
||||
|
|
|
|||
17
crates/omnigraph-api-types/Cargo.toml
Normal file
17
crates/omnigraph-api-types/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "omnigraph-api-types"
|
||||
version = "0.6.1"
|
||||
edition = "2024"
|
||||
description = "HTTP request/response types (OpenAPI schemas) for the Omnigraph graph database."
|
||||
license = "MIT"
|
||||
repository = "https://github.com/ModernRelay/omnigraph"
|
||||
homepage = "https://github.com/ModernRelay/omnigraph"
|
||||
documentation = "https://docs.rs/omnigraph-api-types"
|
||||
|
||||
[dependencies]
|
||||
omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.6.1" }
|
||||
omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.1" }
|
||||
omnigraph-queries = { path = "../omnigraph-queries", version = "0.6.1" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
utoipa = { workspace = true }
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use omnigraph::db::{GraphCommit, MergeOutcome, ReadTarget, SchemaApplyResult, Snapshot};
|
||||
use omnigraph::error::{MergeConflict, MergeConflictKind};
|
||||
use omnigraph::loader::{IngestResult, LoadMode};
|
||||
use crate::queries::StoredQuery;
|
||||
use omnigraph_queries::StoredQuery;
|
||||
use omnigraph_compiler::SchemaMigrationStep;
|
||||
use omnigraph_compiler::query::ast::Param;
|
||||
use omnigraph_compiler::result::QueryResult;
|
||||
|
|
@ -693,3 +693,87 @@ pub struct GraphInfo {
|
|||
pub struct GraphListResponse {
|
||||
pub graphs: Vec<GraphInfo>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
// Catalog-projection tests for `query_catalog_entry`: relocated here from
|
||||
// `omnigraph-queries` because the function under test lives in this crate
|
||||
// (keeps the test at its boundary and keeps `omnigraph-queries` free of a
|
||||
// dev-dependency cycle on `omnigraph-api-types`).
|
||||
use super::{ParamKind, query_catalog_entry};
|
||||
use omnigraph_queries::{QueryRegistry, RegistrySpec};
|
||||
|
||||
fn spec(name: &str, source: &str, expose: bool) -> RegistrySpec {
|
||||
RegistrySpec {
|
||||
name: name.to_string(),
|
||||
source: source.to_string(),
|
||||
expose,
|
||||
tool_name: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn spec_tool(name: &str, source: &str, expose: bool, tool_name: &str) -> RegistrySpec {
|
||||
RegistrySpec {
|
||||
name: name.to_string(),
|
||||
source: source.to_string(),
|
||||
expose,
|
||||
tool_name: Some(tool_name.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn catalog_entry_projects_every_param_kind() {
|
||||
let reg = QueryRegistry::from_specs(vec![spec_tool(
|
||||
"all_types",
|
||||
"query all_types($s: String, $i: I32, $big: I64, $u: U64, $f: F64, $b: Bool, \
|
||||
$d: Date, $dt: DateTime, $blob: Blob, $opt: String?, $list: [I32], $vec: Vector(4)) \
|
||||
{ match { $x: User } return { $x.name } }",
|
||||
true,
|
||||
"all",
|
||||
)])
|
||||
.unwrap();
|
||||
let entry = query_catalog_entry(reg.lookup("all_types").unwrap());
|
||||
assert_eq!(entry.name, "all_types");
|
||||
assert_eq!(entry.tool_name, "all");
|
||||
assert!(!entry.mutation);
|
||||
|
||||
let by: std::collections::HashMap<_, _> =
|
||||
entry.params.iter().map(|p| (p.name.as_str(), p)).collect();
|
||||
assert_eq!(by["s"].kind, ParamKind::String);
|
||||
assert_eq!(by["i"].kind, ParamKind::Int);
|
||||
assert_eq!(by["big"].kind, ParamKind::BigInt, "I64 → bigint (string on the wire)");
|
||||
assert_eq!(by["u"].kind, ParamKind::BigInt, "U64 → bigint");
|
||||
assert_eq!(by["f"].kind, ParamKind::Float);
|
||||
assert_eq!(by["b"].kind, ParamKind::Bool);
|
||||
assert_eq!(by["d"].kind, ParamKind::Date);
|
||||
assert_eq!(by["dt"].kind, ParamKind::DateTime);
|
||||
assert_eq!(by["blob"].kind, ParamKind::Blob);
|
||||
assert!(!by["s"].nullable);
|
||||
assert!(by["opt"].nullable, "String? → nullable");
|
||||
assert_eq!(by["list"].kind, ParamKind::List);
|
||||
assert_eq!(by["list"].item_kind, Some(ParamKind::Int), "[I32] → list of int");
|
||||
assert_eq!(by["vec"].kind, ParamKind::Vector);
|
||||
assert_eq!(by["vec"].vector_dim, Some(4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn catalog_entry_flags_mutation_and_empty_params() {
|
||||
let reg = QueryRegistry::from_specs(vec![spec(
|
||||
"add_user",
|
||||
"query add_user($name: String) { insert User { name: $name } }",
|
||||
true,
|
||||
)])
|
||||
.unwrap();
|
||||
let entry = query_catalog_entry(reg.lookup("add_user").unwrap());
|
||||
assert!(entry.mutation, "insert body → mutation flag");
|
||||
|
||||
let reg2 = QueryRegistry::from_specs(vec![spec(
|
||||
"no_params",
|
||||
"query no_params() { match { $u: User } return { $u.name } }",
|
||||
true,
|
||||
)])
|
||||
.unwrap();
|
||||
let entry2 = query_catalog_entry(reg2.lookup("no_params").unwrap());
|
||||
assert!(entry2.params.is_empty(), "no declared params → empty list");
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.1" }
|
|||
omnigraph-policy = { path = "../omnigraph-policy", version = "0.6.1" }
|
||||
omnigraph-config = { path = "../omnigraph-config", version = "0.6.1" }
|
||||
omnigraph-queries = { path = "../omnigraph-queries", version = "0.6.1" }
|
||||
omnigraph-api-types = { path = "../omnigraph-api-types", version = "0.6.1" }
|
||||
axum = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
color-eyre = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
pub mod api;
|
||||
pub use omnigraph_api_types as api;
|
||||
pub mod auth;
|
||||
pub use omnigraph_config as config;
|
||||
pub mod graph_id;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue