Merge _configs/ into config/ for single configuration directory. Update all path references. Changes: - Move _configs/* to config/ - Update .gitignore for new patterns - No code references to _configs/ found Impact: -1 root directory (layout_conventions.md compliance)
125 lines
3.6 KiB
Rust
125 lines
3.6 KiB
Rust
//! Runtime configuration for the Syntaxis Dashboard
|
|
//!
|
|
//! This module handles loading API configuration at runtime from the browser environment.
|
|
//! The configuration is injected into `window.SYNTAXIS_CONFIG` by `index.html`.
|
|
//!
|
|
//! # Configuration Sources
|
|
//!
|
|
//! In order of precedence:
|
|
//! 1. URL query parameter: `?apiUrl=http://custom-api:3000`
|
|
//! 2. `window.SYNTAXIS_CONFIG.apiUrl` (set by index.html)
|
|
//! 3. Default: `window.location.origin` (same-origin, current domain)
|
|
//!
|
|
//! # Example
|
|
//!
|
|
//! ```
|
|
//! // Default behavior (auto-detect from current domain)
|
|
//! let url = get_api_base_url();
|
|
//! // Result: "http://localhost:3000" (if served on localhost:3000)
|
|
//!
|
|
//! // Override via URL parameter
|
|
//! // Visit: http://localhost:8080?apiUrl=http://remote-api:3000
|
|
//! let url = get_api_base_url();
|
|
//! // Result: "http://remote-api:3000"
|
|
//! ```
|
|
|
|
#![forbid(unsafe_code)]
|
|
|
|
use js_sys::Reflect;
|
|
use wasm_bindgen::JsValue;
|
|
use web_sys::window;
|
|
|
|
/// Get the API base URL from browser configuration
|
|
///
|
|
/// Returns the configured API URL with priority:
|
|
/// 1. URL parameter `?apiUrl=...`
|
|
/// 2. `window.SYNTAXIS_CONFIG.apiUrl`
|
|
/// 3. `window.location.origin` (same-origin default)
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics if `window` is not available (shouldn't happen in browser context)
|
|
#[must_use]
|
|
pub fn get_api_base_url() -> String {
|
|
let window = window().expect("window should be available");
|
|
|
|
// Try to get apiUrl from window.SYNTAXIS_CONFIG
|
|
let config_url = get_config_api_url(&window);
|
|
if let Some(url) = config_url {
|
|
return url;
|
|
}
|
|
|
|
// Fall back to window.location.origin
|
|
window
|
|
.location()
|
|
.origin()
|
|
.unwrap_or_else(|_| "http://localhost:3000".to_string())
|
|
}
|
|
|
|
/// Get the API path prefix from configuration (default: /api)
|
|
#[must_use]
|
|
pub fn get_api_path() -> String {
|
|
let window = match window() {
|
|
Some(w) => w,
|
|
None => return "/api".to_string(),
|
|
};
|
|
|
|
get_config_api_path(&window).unwrap_or_else(|| "/api".to_string())
|
|
}
|
|
|
|
/// Get the full API URL including path prefix
|
|
///
|
|
/// Example: `http://localhost:3000/api`
|
|
#[must_use]
|
|
pub fn get_api_url() -> String {
|
|
format!("{}{}", get_api_base_url(), get_api_path())
|
|
}
|
|
|
|
fn get_config_api_url(window: &web_sys::Window) -> Option<String> {
|
|
// First, try URL parameter (?apiUrl=...)
|
|
if let Some(url) = get_url_param_api_url(window) {
|
|
return Some(url);
|
|
}
|
|
|
|
// Then try window.SYNTAXIS_CONFIG.apiUrl
|
|
let config = Reflect::get(window, &JsValue::from_str("SYNTAXIS_CONFIG")).ok()?;
|
|
Reflect::get(&config, &JsValue::from_str("apiUrl"))
|
|
.ok()?
|
|
.as_string()
|
|
}
|
|
|
|
fn get_config_api_path(window: &web_sys::Window) -> Option<String> {
|
|
let config = Reflect::get(window, &JsValue::from_str("SYNTAXIS_CONFIG")).ok()?;
|
|
Reflect::get(&config, &JsValue::from_str("apiPath"))
|
|
.ok()?
|
|
.as_string()
|
|
}
|
|
|
|
fn get_url_param_api_url(window: &web_sys::Window) -> Option<String> {
|
|
let location = window.location();
|
|
let search = location.search().ok()?;
|
|
|
|
// Parse URL parameters
|
|
let params = web_sys::UrlSearchParams::new_with_str(&search).ok()?;
|
|
params.get("apiUrl")
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
#[test]
|
|
fn test_get_api_path() {
|
|
// This test runs in a test environment without a browser
|
|
// The actual function requires window, so we just verify the default
|
|
let path = "/api".to_string();
|
|
assert_eq!(path, "/api");
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_url_construction() {
|
|
let base = "http://localhost:3000".to_string();
|
|
let path = "/api".to_string();
|
|
let full_url = format!("{}{}", base, path);
|
|
assert_eq!(full_url, "http://localhost:3000/api");
|
|
}
|
|
}
|