appcore_app_spec/
lib.rs

1use schemars::JsonSchema;
2use serde_derive::Deserialize;
3
4pub use crate::nextjs::*;
5
6mod nextjs;
7
8#[derive(Debug, Clone, Deserialize, JsonSchema)]
9#[serde(rename_all = "snake_case", deny_unknown_fields)]
10pub struct AppSpec {
11    pub name: String,
12
13    /// The fully qualified domain name of the app.
14    pub domain: String,
15
16    pub dev: DevConfig,
17
18    pub app: AppDetails,
19
20    pub secrets: AppSecretsConfig,
21
22    #[serde(default)]
23    pub auth: Option<AppAuthConfig>,
24
25    #[serde(default)]
26    pub db: Option<DatabaseConfig>,
27
28    #[serde(default)]
29    pub redis: Option<RedisConfig>,
30}
31
32#[derive(Debug, Clone, Deserialize, JsonSchema)]
33#[serde(tag = "kind", rename_all = "snake_case")]
34pub enum AppDetails {
35    #[serde(rename = "nextjs-app")]
36    NextJsApp(NextJsApp),
37    #[serde(rename = "nodejs-api-server")]
38    NodeJsApiServer(NodeJsApiServer),
39}
40
41#[derive(Debug, Clone, Deserialize, JsonSchema)]
42#[serde(rename_all = "snake_case")]
43pub struct NodeJsApiServer {}
44
45/// Configuration for the development environment.
46#[derive(Debug, Clone, Deserialize, JsonSchema)]
47#[serde(rename_all = "snake_case", deny_unknown_fields)]
48pub struct DevConfig {
49    pub port: u16,
50}
51
52#[derive(Debug, Clone, Deserialize, JsonSchema)]
53#[serde(tag = "provider", rename_all = "snake_case", deny_unknown_fields)]
54pub enum AppSecretsConfig {
55    #[serde(rename = "vercel")]
56    Vercel(VercelSecretsConfig),
57}
58
59#[derive(Debug, Clone, Deserialize, JsonSchema)]
60#[serde(rename_all = "snake_case", deny_unknown_fields)]
61pub struct VercelSecretsConfig {
62    pub org: String,
63    pub project: String,
64}
65
66#[derive(Debug, Clone, Deserialize, JsonSchema)]
67#[serde(tag = "provider", rename_all = "snake_case", deny_unknown_fields)]
68pub enum AppAuthConfig {
69    #[serde(rename = "logto")]
70    Logto(LogtoAuthConfig),
71}
72
73/// Configuration for the Logto authentication provider.
74///
75/// This configuration assumes `https://$domain/api/auth/callback` and
76/// `http://localhost:$port/api/auth/callback` is the callback url for the
77/// application.
78#[derive(Debug, Clone, Deserialize, JsonSchema)]
79#[serde(rename_all = "snake_case", deny_unknown_fields)]
80pub struct LogtoAuthConfig {
81    pub app_name: String,
82}
83
84#[derive(Debug, Clone, Deserialize, JsonSchema)]
85#[serde(tag = "provider", rename_all = "snake_case", deny_unknown_fields)]
86pub enum DatabaseConfig {
87    #[serde(rename = "neon")]
88    Neon(NeonDatabaseConfig),
89    #[serde(rename = "coolify")]
90    Coolify(CoolifyDatabaseConfig),
91}
92
93#[derive(Debug, Clone, Deserialize, JsonSchema)]
94#[serde(rename_all = "snake_case", deny_unknown_fields)]
95pub struct NeonDatabaseConfig {
96    pub project_name: String,
97}
98
99/// Configuration for the Coolify database provider.
100///
101/// This configuration assumes the environment for the database is `production`
102/// and `development`.
103#[derive(Debug, Clone, Deserialize, JsonSchema)]
104#[serde(rename_all = "snake_case", deny_unknown_fields)]
105pub struct CoolifyDatabaseConfig {
106    pub project_name: String,
107    pub server_name: String,
108}
109
110#[derive(Debug, Clone, Deserialize, JsonSchema)]
111#[serde(tag = "provider", rename_all = "snake_case", deny_unknown_fields)]
112pub enum RedisConfig {
113    #[serde(rename = "coolify")]
114    Coolify(CoolifyRedisConfig),
115}
116
117#[derive(Debug, Clone, Deserialize, JsonSchema)]
118#[serde(rename_all = "snake_case", deny_unknown_fields)]
119pub struct CoolifyRedisConfig {
120    pub project_name: String,
121    pub server_name: String,
122}