Skip to main content

create_commonpub/
scaffold.rs

1use std::fs;
2use std::path::{Path, PathBuf};
3
4use crate::prompts::InstanceConfig;
5use crate::template;
6
7pub fn create_instance(name: &str, config: &InstanceConfig) -> Result<PathBuf, Box<dyn std::error::Error>> {
8    let path = PathBuf::from(name);
9    if path.exists() {
10        return Err(format!("Directory '{}' already exists", name).into());
11    }
12    fs::create_dir_all(&path)?;
13    write_files(&path, config)?;
14    Ok(fs::canonicalize(&path)?)
15}
16
17pub fn create_instance_at(base: &Path, name: &str, config: &InstanceConfig) -> Result<PathBuf, Box<dyn std::error::Error>> {
18    let path = base.join(name);
19    if path.exists() {
20        return Err(format!("Directory '{}' already exists", path.display()).into());
21    }
22    fs::create_dir_all(&path)?;
23    write_files(&path, config)?;
24    Ok(fs::canonicalize(&path)?)
25}
26
27pub fn init_instance(config: &InstanceConfig) -> Result<PathBuf, Box<dyn std::error::Error>> {
28    let path = PathBuf::from(".");
29    write_files(&path, config)?;
30    Ok(fs::canonicalize(&path)?)
31}
32
33pub fn init_instance_at(dir: &Path, config: &InstanceConfig) -> Result<PathBuf, Box<dyn std::error::Error>> {
34    write_files(dir, config)?;
35    Ok(fs::canonicalize(dir)?)
36}
37
38fn write_files(dir: &Path, config: &InstanceConfig) -> Result<(), Box<dyn std::error::Error>> {
39    // Generate and write each file
40    let env_content = template::render_env(config);
41    fs::write(dir.join(".env"), env_content)?;
42
43    let config_content = template::render_config(config);
44    fs::write(dir.join("commonpub.config.ts"), config_content)?;
45
46    let nuxt_config = template::render_nuxt_config(config);
47    fs::write(dir.join("nuxt.config.ts"), nuxt_config)?;
48
49    let package_json = template::render_package_json(config);
50    fs::write(dir.join("package.json"), package_json)?;
51
52    let tsconfig = template::render_tsconfig();
53    fs::write(dir.join("tsconfig.json"), tsconfig)?;
54
55    let app_vue = template::render_app_vue(config);
56    fs::write(dir.join("app.vue"), app_vue)?;
57
58    if config.use_docker {
59        let compose = template::render_docker_compose(config);
60        fs::write(dir.join("docker-compose.yml"), compose)?;
61    }
62
63    // Nuxt 3 directory structure
64    fs::create_dir_all(dir.join("pages"))?;
65    fs::create_dir_all(dir.join("components"))?;
66    fs::create_dir_all(dir.join("composables"))?;
67    fs::create_dir_all(dir.join("layouts"))?;
68    fs::create_dir_all(dir.join("server/api"))?;
69    fs::create_dir_all(dir.join("server/utils"))?;
70    fs::create_dir_all(dir.join("server/middleware"))?;
71    fs::create_dir_all(dir.join("public"))?;
72    fs::create_dir_all(dir.join("uploads"))?;
73
74    // Server utils
75    fs::write(dir.join("server/utils/config.ts"), template::render_server_config())?;
76    fs::write(dir.join("server/utils/db.ts"), template::render_server_db())?;
77    fs::write(dir.join("server/utils/auth.ts"), template::render_server_auth())?;
78    fs::write(dir.join("server/utils/validate.ts"), template::render_server_validate())?;
79    fs::write(dir.join("server/utils/errors.ts"), template::render_server_errors())?;
80
81    // Server middleware
82    fs::write(dir.join("server/middleware/auth.ts"), template::render_middleware_auth())?;
83    fs::write(dir.join("server/middleware/security.ts"), template::render_middleware_security())?;
84
85    // Plugins
86    fs::create_dir_all(dir.join("plugins"))?;
87    fs::write(dir.join("plugins/auth.ts"), template::render_plugin_auth())?;
88
89    // Composables
90    fs::write(dir.join("composables/useAuth.ts"), template::render_composable_auth())?;
91
92    // Default layout
93    fs::write(dir.join("layouts/default.vue"), template::render_default_layout(config))?;
94
95    // Index page
96    fs::write(dir.join("pages/index.vue"), template::render_index_page(config))?;
97
98    // .gitignore
99    fs::write(dir.join(".gitignore"), template::render_gitignore())?;
100
101    // Uploads placeholder
102    fs::write(dir.join("uploads/.gitkeep"), "")?;
103
104    // README
105    let readme = format!("# {}\n\n{}\n\nPowered by [CommonPub](https://commonpub.dev).\n", config.name, config.description);
106    fs::write(dir.join("README.md"), readme)?;
107
108    Ok(())
109}