@iconsulting-dev/forgekit 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +203 -0
  2. package/dist/commands/new.d.ts +3 -0
  3. package/dist/commands/new.d.ts.map +1 -0
  4. package/dist/commands/new.js +120 -0
  5. package/dist/commands/new.js.map +1 -0
  6. package/dist/config.d.ts +4 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +21 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/generators/backend/index.d.ts +4 -0
  11. package/dist/generators/backend/index.d.ts.map +1 -0
  12. package/dist/generators/backend/index.js +69 -0
  13. package/dist/generators/backend/index.js.map +1 -0
  14. package/dist/generators/base-generator.d.ts +9 -0
  15. package/dist/generators/base-generator.d.ts.map +1 -0
  16. package/dist/generators/base-generator.js +13 -0
  17. package/dist/generators/base-generator.js.map +1 -0
  18. package/dist/generators/ci/index.d.ts +3 -0
  19. package/dist/generators/ci/index.d.ts.map +1 -0
  20. package/dist/generators/ci/index.js +18 -0
  21. package/dist/generators/ci/index.js.map +1 -0
  22. package/dist/generators/claude-code/index.d.ts +4 -0
  23. package/dist/generators/claude-code/index.d.ts.map +1 -0
  24. package/dist/generators/claude-code/index.js +47 -0
  25. package/dist/generators/claude-code/index.js.map +1 -0
  26. package/dist/generators/docker/index.d.ts +3 -0
  27. package/dist/generators/docker/index.d.ts.map +1 -0
  28. package/dist/generators/docker/index.js +14 -0
  29. package/dist/generators/docker/index.js.map +1 -0
  30. package/dist/generators/frontend/index.d.ts +4 -0
  31. package/dist/generators/frontend/index.d.ts.map +1 -0
  32. package/dist/generators/frontend/index.js +60 -0
  33. package/dist/generators/frontend/index.js.map +1 -0
  34. package/dist/generators/git.d.ts +2 -0
  35. package/dist/generators/git.d.ts.map +1 -0
  36. package/dist/generators/git.js +16 -0
  37. package/dist/generators/git.js.map +1 -0
  38. package/dist/generators/root/index.d.ts +4 -0
  39. package/dist/generators/root/index.d.ts.map +1 -0
  40. package/dist/generators/root/index.js +29 -0
  41. package/dist/generators/root/index.js.map +1 -0
  42. package/dist/index.d.ts +3 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +11 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/prompts/project.d.ts +3 -0
  47. package/dist/prompts/project.d.ts.map +1 -0
  48. package/dist/prompts/project.js +70 -0
  49. package/dist/prompts/project.js.map +1 -0
  50. package/dist/templates/backend/ApiError.java.hbs +4 -0
  51. package/dist/templates/backend/Application.java.hbs +12 -0
  52. package/dist/templates/backend/ApplicationTests.java.hbs +12 -0
  53. package/dist/templates/backend/GlobalExceptionHandler.java.hbs +27 -0
  54. package/dist/templates/backend/OpenApiConfig.java.hbs +19 -0
  55. package/dist/templates/backend/PageResponse.java.hbs +12 -0
  56. package/dist/templates/backend/SecurityConfig.java.hbs +43 -0
  57. package/dist/templates/backend/application-dev.yml.hbs +7 -0
  58. package/dist/templates/backend/application.yml.hbs +37 -0
  59. package/dist/templates/backend/gitignore.hbs +16 -0
  60. package/dist/templates/backend/maven-wrapper.properties.hbs +2 -0
  61. package/dist/templates/backend/mvnw.cmd.hbs +4 -0
  62. package/dist/templates/backend/mvnw.hbs +17 -0
  63. package/dist/templates/backend/pom.xml.hbs +136 -0
  64. package/dist/templates/ci/ci.yml.hbs +87 -0
  65. package/dist/templates/claude-code/CLAUDE.md.hbs +79 -0
  66. package/dist/templates/claude-code/settings.json.hbs +9 -0
  67. package/dist/templates/docker/docker-compose.yml.hbs +34 -0
  68. package/dist/templates/frontend/angular.json.hbs +71 -0
  69. package/dist/templates/frontend/app.component.ts.hbs +11 -0
  70. package/dist/templates/frontend/app.config.ts.hbs +16 -0
  71. package/dist/templates/frontend/app.routes.ts.hbs +14 -0
  72. package/dist/templates/frontend/auth.guard.ts.hbs +14 -0
  73. package/dist/templates/frontend/auth.interceptor.ts.hbs +13 -0
  74. package/dist/templates/frontend/auth.service.ts.hbs +18 -0
  75. package/dist/templates/frontend/environment.development.ts.hbs +4 -0
  76. package/dist/templates/frontend/environment.ts.hbs +4 -0
  77. package/dist/templates/frontend/error.interceptor.ts.hbs +14 -0
  78. package/dist/templates/frontend/gitignore.hbs +4 -0
  79. package/dist/templates/frontend/index.html.hbs +13 -0
  80. package/dist/templates/frontend/layout.component.ts.hbs +42 -0
  81. package/dist/templates/frontend/main.ts.hbs +6 -0
  82. package/dist/templates/frontend/package.json.hbs +35 -0
  83. package/dist/templates/frontend/sidebar.component.ts.hbs +58 -0
  84. package/dist/templates/frontend/styles.scss.hbs +8 -0
  85. package/dist/templates/frontend/topbar.component.ts.hbs +59 -0
  86. package/dist/templates/frontend/tsconfig.app.json.hbs +13 -0
  87. package/dist/templates/frontend/tsconfig.json.hbs +24 -0
  88. package/dist/templates/root/README.md.hbs +37 -0
  89. package/dist/templates/root/gitignore.hbs +12 -0
  90. package/dist/types.d.ts +15 -0
  91. package/dist/types.d.ts.map +1 -0
  92. package/dist/types.js +2 -0
  93. package/dist/types.js.map +1 -0
  94. package/dist/utils/__tests__/validation.test.d.ts +2 -0
  95. package/dist/utils/__tests__/validation.test.d.ts.map +1 -0
  96. package/dist/utils/__tests__/validation.test.js +59 -0
  97. package/dist/utils/__tests__/validation.test.js.map +1 -0
  98. package/dist/utils/template-engine.d.ts +5 -0
  99. package/dist/utils/template-engine.d.ts.map +1 -0
  100. package/dist/utils/template-engine.js +23 -0
  101. package/dist/utils/template-engine.js.map +1 -0
  102. package/dist/utils/validation.d.ts +3 -0
  103. package/dist/utils/validation.d.ts.map +1 -0
  104. package/dist/utils/validation.js +19 -0
  105. package/dist/utils/validation.js.map +1 -0
  106. package/dist/versions.d.ts +18 -0
  107. package/dist/versions.d.ts.map +1 -0
  108. package/dist/versions.js +91 -0
  109. package/dist/versions.js.map +1 -0
  110. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ <p align="center">
2
+ <img src="assets/logo.svg" alt="ForgeKit" width="120" />
3
+ </p>
4
+
5
+ <h1 align="center">ForgeKit</h1>
6
+
7
+ <p align="center">
8
+ CLI de scaffolding full-stack qui génère des projets <strong>Spring Boot + Angular</strong> préconfigurés et prêts à l'emploi.<br/>
9
+ Fini la configuration répétitive : une commande, un projet complet.
10
+ </p>
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ git clone https://github.com/iconsulting/forgekit.git
16
+ cd forgekit
17
+ npm install
18
+ npm run build
19
+ npm link
20
+ ```
21
+
22
+ ## Utilisation
23
+
24
+ ### Mode interactif (wizard)
25
+
26
+ ```bash
27
+ forgekit new
28
+ ```
29
+
30
+ Un wizard vous guide avec des valeurs par défaut modifiables :
31
+
32
+ ```
33
+ ? Nom du projet : (mon-app)
34
+ ? Group ID : (com.example)
35
+ ? Description : (Mon application)
36
+ ? Que voulez-vous générer ? (Backend + Frontend)
37
+ ? Configurer Docker Compose ? (Oui)
38
+ ? Configurer Claude Code ? (Oui)
39
+ ? Initialiser Git ? (Oui)
40
+ ```
41
+
42
+ ### Mode commande directe
43
+
44
+ ```bash
45
+ forgekit new mon-app --group com.salim --backend --frontend --docker --claude-code
46
+ ```
47
+
48
+ ### Options disponibles
49
+
50
+ | Flag | Description |
51
+ |---|---|
52
+ | `--group <id>` | Group ID Java (ex: `com.salim`) |
53
+ | `--description <desc>` | Description du projet |
54
+ | `--backend` | Inclure le backend Spring Boot |
55
+ | `--frontend` | Inclure le frontend Angular |
56
+ | `--docker` | Inclure Docker Compose |
57
+ | `--claude-code` | Inclure la config Claude Code |
58
+ | `--no-git` | Ne pas initialiser Git |
59
+
60
+ ## Projet généré
61
+
62
+ ```
63
+ mon-projet/
64
+ ├── backend/ # Spring Boot 4.0.2 / Java 21
65
+ ├── frontend/ # Angular 21 / PrimeNG 21
66
+ ├── docker-compose.yml # PostgreSQL 17 + pgAdmin
67
+ ├── CLAUDE.md # Conventions Claude Code
68
+ ├── .claude/settings.json # Permissions Claude Code
69
+ ├── .gitignore
70
+ └── README.md
71
+ ```
72
+
73
+ ### Backend — Spring Boot
74
+
75
+ **Dépendances incluses :**
76
+ Spring Web, Spring Data JPA, PostgreSQL, Spring Security, Spring Validation, Lombok, MapStruct, SpringDoc OpenAPI, Flyway, Spring Actuator.
77
+
78
+ **Structure :**
79
+
80
+ ```
81
+ backend/src/main/java/com/{group}/{name}/
82
+ ├── Application.java
83
+ ├── config/
84
+ │ ├── SecurityConfig.java # CORS, CSRF, JWT-ready
85
+ │ └── OpenApiConfig.java
86
+ ├── shared/
87
+ │ ├── exception/
88
+ │ │ ├── GlobalExceptionHandler.java
89
+ │ │ └── ApiError.java # Record
90
+ │ └── dto/
91
+ │ └── PageResponse.java # Record pagination
92
+ └── feature/ # Structure par feature
93
+ ```
94
+
95
+ **Configurations :**
96
+ - `application.yml` — Config principale avec variables d'env
97
+ - `application-dev.yml` — Profil dev pointant vers Docker Compose
98
+ - `db/migration/V1__init.sql` — Migration Flyway prête
99
+
100
+ ### Frontend — Angular
101
+
102
+ **Dépendances incluses :**
103
+ Angular (dernière version), PrimeNG (thème Aura), PrimeIcons, PrimeFlex, NgRx SignalStore.
104
+
105
+ **Structure :**
106
+
107
+ ```
108
+ frontend/src/app/
109
+ ├── app.component.ts # Standalone, OnPush
110
+ ├── app.routes.ts # Routes lazy-loaded
111
+ ├── app.config.ts # Providers
112
+ ├── layout/
113
+ │ ├── layout.component.ts # Shell (sidebar + topbar + router-outlet)
114
+ │ ├── sidebar/
115
+ │ └── topbar/
116
+ ├── core/
117
+ │ ├── interceptors/ # Auth + Error interceptors
118
+ │ ├── guards/ # Auth guard
119
+ │ └── services/ # Auth service (signals)
120
+ ├── shared/ # Composants et pipes réutilisables
121
+ └── features/ # Structure par feature
122
+ ```
123
+
124
+ **Prêt à l'emploi :**
125
+ - Layout sidebar/topbar fonctionnel
126
+ - Thème Aura PrimeNG appliqué
127
+ - Intercepteurs HTTP câblés
128
+ - NgRx SignalStore prêt par feature
129
+ - Standalone components, signals, `@if`/`@for`, OnPush
130
+
131
+ ### Docker Compose
132
+
133
+ | Service | Port | Description |
134
+ |---|---|---|
135
+ | PostgreSQL 17 | 5432 | Base de données avec volume persistant |
136
+ | pgAdmin | 5050 | Interface web (admin@admin.com / admin) |
137
+
138
+ ### Claude Code
139
+
140
+ Génère automatiquement :
141
+ - **`CLAUDE.md`** — Conventions du projet, commandes, structure
142
+ - **`.claude/settings.json`** — Permissions préconfigurées (mvn, ng, npm, docker)
143
+
144
+ ## Démarrage rapide d'un projet généré
145
+
146
+ ```bash
147
+ # Générer le projet
148
+ forgekit new mon-app --group com.salim --backend --frontend --docker --claude-code
149
+
150
+ # Démarrer l'infrastructure
151
+ cd mon-app
152
+ docker compose up -d
153
+
154
+ # Démarrer le backend (port 8080)
155
+ cd backend && ./mvnw spring-boot:run
156
+
157
+ # Démarrer le frontend (port 4200)
158
+ cd frontend && npm install && ng serve
159
+ ```
160
+
161
+ ## Config persistante
162
+
163
+ ForgeKit retient vos préférences dans `~/.forgekit/config.json` (Group ID, etc.) pour les réutiliser automatiquement.
164
+
165
+ ## Architecture du CLI
166
+
167
+ ```
168
+ src/
169
+ ├── commands/new.ts # Commande principale (try/catch + rollback)
170
+ ├── prompts/project.ts # Wizard interactif avec validation
171
+ ├── generators/
172
+ │ ├── base-generator.ts # Classe abstraite commune
173
+ │ ├── backend/index.ts # BackendGenerator
174
+ │ ├── frontend/index.ts # FrontendGenerator
175
+ │ ├── docker/index.ts # DockerGenerator
176
+ │ ├── claude-code/index.ts # ClaudeCodeGenerator
177
+ │ ├── root/index.ts # RootGenerator (README + .gitignore)
178
+ │ └── git.ts # Initialisation Git
179
+ ├── templates/ # 39 templates Handlebars (.hbs)
180
+ │ ├── backend/ # 14 templates
181
+ │ ├── frontend/ # 20 templates
182
+ │ ├── docker/ # 1 template
183
+ │ ├── claude-code/ # 2 templates
184
+ │ └── root/ # 2 templates
185
+ ├── utils/
186
+ │ ├── template-engine.ts # Handlebars compile + render
187
+ │ └── validation.ts # Validation inputs
188
+ ├── types.ts
189
+ ├── versions.ts # Résolution dynamique Maven + NPM
190
+ └── config.ts # Config persistante (~/.forgekit)
191
+ ```
192
+
193
+ ### Stack technique
194
+
195
+ - **Runtime :** Node.js / TypeScript (ESM)
196
+ - **Templates :** Handlebars
197
+ - **Commandes :** Commander.js
198
+ - **Prompts :** Inquirer.js
199
+ - **Utilitaires :** fs-extra, chalk
200
+
201
+ ## Licence
202
+
203
+ MIT
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const newCommand: Command;
3
+ //# sourceMappingURL=new.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,eAAO,MAAM,UAAU,SAgIpB,CAAC"}
@@ -0,0 +1,120 @@
1
+ import { Command } from "commander";
2
+ import path from "node:path";
3
+ import fs from "fs-extra";
4
+ import chalk from "chalk";
5
+ import { promptProjectConfig } from "../prompts/project.js";
6
+ import { saveConfig } from "../config.js";
7
+ import { generateBackend } from "../generators/backend/index.js";
8
+ import { generateFrontend } from "../generators/frontend/index.js";
9
+ import { generateDocker } from "../generators/docker/index.js";
10
+ import { generateCI } from "../generators/ci/index.js";
11
+ import { generateClaudeCode } from "../generators/claude-code/index.js";
12
+ import { generateRoot } from "../generators/root/index.js";
13
+ import { initGit } from "../generators/git.js";
14
+ import { resolveVersions } from "../versions.js";
15
+ export const newCommand = new Command("new")
16
+ .description("Créer un nouveau projet full-stack")
17
+ .argument("[name]", "Nom du projet")
18
+ .option("--group <groupId>", "Group ID Java")
19
+ .option("--description <desc>", "Description du projet")
20
+ .option("--backend", "Inclure le backend Spring Boot")
21
+ .option("--frontend", "Inclure le frontend Angular")
22
+ .option("--docker", "Inclure Docker Compose")
23
+ .option("--ci", "Inclure GitHub Actions CI")
24
+ .option("--claude-code", "Inclure config Claude Code")
25
+ .option("--no-git", "Ne pas initialiser Git")
26
+ .action(async (name, options) => {
27
+ console.log(chalk.bold.hex("#FF6B35")("\n🔨 ForgeKit — Scaffolding full-stack\n"));
28
+ const defaults = {};
29
+ if (name)
30
+ defaults.name = name;
31
+ if (options.group)
32
+ defaults.groupId = options.group;
33
+ if (options.description)
34
+ defaults.description = options.description;
35
+ if (options.backend)
36
+ defaults.backend = true;
37
+ if (options.frontend)
38
+ defaults.frontend = true;
39
+ if (options.ci)
40
+ defaults.ci = true;
41
+ if (options.docker)
42
+ defaults.docker = true;
43
+ if (options.claudeCode)
44
+ defaults.claudeCode = true;
45
+ if (typeof options.git === "boolean")
46
+ defaults.gitInit = options.git;
47
+ let config;
48
+ try {
49
+ config = await promptProjectConfig(defaults);
50
+ }
51
+ catch {
52
+ console.log(chalk.yellow("\n\n👋 Génération annulée."));
53
+ process.exit(0);
54
+ }
55
+ const projectDir = path.resolve(process.cwd(), config.name);
56
+ if (await fs.pathExists(projectDir)) {
57
+ console.log(chalk.red(`\nLe dossier "${config.name}" existe déjà.`));
58
+ process.exit(1);
59
+ }
60
+ try {
61
+ await fs.ensureDir(projectDir);
62
+ console.log(chalk.gray(`\nCréation du projet ${config.name}...\n`));
63
+ const versions = await resolveVersions({
64
+ backend: config.backend,
65
+ frontend: config.frontend,
66
+ });
67
+ if (config.backend) {
68
+ process.stdout.write(chalk.yellow(" ⏳ Backend Spring Boot..."));
69
+ await generateBackend(projectDir, config, versions);
70
+ console.log(chalk.green(`\r ✔ Backend Spring Boot ${versions.springBoot} généré `));
71
+ }
72
+ if (config.frontend) {
73
+ process.stdout.write(chalk.yellow(" ⏳ Frontend Angular..."));
74
+ await generateFrontend(projectDir, config, versions);
75
+ console.log(chalk.green(`\r ✔ Frontend Angular ${versions.angular} généré `));
76
+ }
77
+ if (config.docker) {
78
+ process.stdout.write(chalk.yellow(" ⏳ Docker Compose..."));
79
+ await generateDocker(projectDir, config);
80
+ console.log(chalk.green("\r ✔ Docker Compose généré "));
81
+ }
82
+ if (config.ci) {
83
+ process.stdout.write(chalk.yellow(" ⏳ GitHub Actions CI..."));
84
+ await generateCI(projectDir, config);
85
+ console.log(chalk.green("\r ✔ GitHub Actions CI configuré "));
86
+ }
87
+ if (config.claudeCode) {
88
+ process.stdout.write(chalk.yellow(" ⏳ Claude Code..."));
89
+ await generateClaudeCode(projectDir, config, versions);
90
+ console.log(chalk.green("\r ✔ Claude Code configuré "));
91
+ }
92
+ await generateRoot(projectDir, config, versions);
93
+ if (config.gitInit) {
94
+ process.stdout.write(chalk.yellow(" ⏳ Git..."));
95
+ await initGit(projectDir);
96
+ console.log(chalk.green("\r ✔ Git initialisé + premier commit "));
97
+ }
98
+ await saveConfig({ groupId: config.groupId });
99
+ console.log(chalk.bold.green(`\n🚀 Projet "${config.name}" prêt !\n`));
100
+ console.log(chalk.white("Pour démarrer :"));
101
+ console.log(chalk.cyan(` cd ${config.name}`));
102
+ if (config.docker)
103
+ console.log(chalk.cyan(" docker compose up -d"));
104
+ if (config.backend)
105
+ console.log(chalk.cyan(" cd backend && ./mvnw spring-boot:run"));
106
+ if (config.frontend)
107
+ console.log(chalk.cyan(" cd frontend && npm install && ng serve"));
108
+ console.log("");
109
+ }
110
+ catch (error) {
111
+ console.log(chalk.red(`\n✖ Erreur lors de la génération : ${error instanceof Error ? error.message : error}`));
112
+ // Rollback: remove the partially created project directory
113
+ if (await fs.pathExists(projectDir)) {
114
+ await fs.remove(projectDir);
115
+ console.log(chalk.gray(` Dossier "${config.name}" supprimé (rollback).`));
116
+ }
117
+ process.exit(1);
118
+ }
119
+ });
120
+ //# sourceMappingURL=new.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,oCAAoC,CAAC;KACjD,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;KACnC,MAAM,CAAC,mBAAmB,EAAE,eAAe,CAAC;KAC5C,MAAM,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;KACvD,MAAM,CAAC,WAAW,EAAE,gCAAgC,CAAC;KACrD,MAAM,CAAC,YAAY,EAAE,6BAA6B,CAAC;KACnD,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;KAC5C,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC;KAC3C,MAAM,CAAC,eAAe,EAAE,4BAA4B,CAAC;KACrD,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;KAC5C,MAAM,CACL,KAAK,EAAE,IAAwB,EAAE,OAAgC,EAAE,EAAE;IACnE,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,0CAA0C,CAAC,CACtE,CAAC;IAEF,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,IAAI,IAAI;QAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;IAC/B,IAAI,OAAO,CAAC,KAAK;QAAE,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,KAAe,CAAC;IAC9D,IAAI,OAAO,CAAC,WAAW;QACrB,QAAQ,CAAC,WAAW,GAAG,OAAO,CAAC,WAAqB,CAAC;IACvD,IAAI,OAAO,CAAC,OAAO;QAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;IAC7C,IAAI,OAAO,CAAC,QAAQ;QAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC/C,IAAI,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC;IACnC,IAAI,OAAO,CAAC,MAAM;QAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC;IAC3C,IAAI,OAAO,CAAC,UAAU;QAAE,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;IACnD,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,SAAS;QAAE,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;IAErE,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAE5D,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;QAEpE,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC;YACrC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACjE,MAAM,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CACT,6BAA6B,QAAQ,CAAC,UAAU,gBAAgB,CACjE,CACF,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAC9D,MAAM,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CACT,0BAA0B,QAAQ,CAAC,OAAO,oBAAoB,CAC/D,CACF,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC5D,MAAM,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAC/D,MAAM,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;YACzD,MAAM,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEjD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YACjD,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAE9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACrE,IAAI,MAAM,CAAC,OAAO;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,QAAQ;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,sCAAsC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CACvF,CACF,CAAC;QAEF,2DAA2D;QAC3D,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,IAAI,wBAAwB,CAAC,CAC9D,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { SavedConfig } from "./types.js";
2
+ export declare function loadConfig(): Promise<SavedConfig>;
3
+ export declare function saveConfig(config: SavedConfig): Promise<void>;
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CASvD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnE"}
package/dist/config.js ADDED
@@ -0,0 +1,21 @@
1
+ import fs from "fs-extra";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ const CONFIG_DIR = path.join(os.homedir(), ".forgekit");
5
+ const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
6
+ export async function loadConfig() {
7
+ try {
8
+ if (await fs.pathExists(CONFIG_FILE)) {
9
+ return await fs.readJson(CONFIG_FILE);
10
+ }
11
+ }
12
+ catch {
13
+ // Ignore corrupt config
14
+ }
15
+ return {};
16
+ }
17
+ export async function saveConfig(config) {
18
+ await fs.ensureDir(CONFIG_DIR);
19
+ await fs.writeJson(CONFIG_FILE, config, { spaces: 2 });
20
+ }
21
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACxD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAmB;IAClD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ProjectConfig } from "../../types.js";
2
+ import type { ResolvedVersions } from "../../versions.js";
3
+ export declare function generateBackend(projectDir: string, config: ProjectConfig, versions: ResolvedVersions): Promise<void>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/backend/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAyI1D,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -0,0 +1,69 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { renderAndWrite } from "../../utils/template-engine.js";
4
+ import { BaseGenerator } from "../base-generator.js";
5
+ class BackendGenerator extends BaseGenerator {
6
+ versions;
7
+ artifactId;
8
+ packageName;
9
+ groupPath;
10
+ dbName;
11
+ constructor(projectDir, config, versions) {
12
+ super(projectDir, config);
13
+ this.versions = versions;
14
+ this.artifactId = config.name.toLowerCase().replace(/[^a-z0-9]/g, "-");
15
+ this.packageName = `${config.groupId}.${config.name.toLowerCase().replace(/[^a-z0-9]/g, "")}`;
16
+ this.groupPath = config.groupId.replace(/\./g, "/");
17
+ this.dbName = config.name.toLowerCase().replace(/[^a-z0-9]/g, "_");
18
+ }
19
+ async generate() {
20
+ const backendDir = path.join(this.projectDir, "backend");
21
+ const javaDir = path.join(backendDir, "src/main/java", this.groupPath, this.config.name.toLowerCase().replace(/[^a-z0-9]/g, ""));
22
+ const resourcesDir = path.join(backendDir, "src/main/resources");
23
+ const testDir = path.join(backendDir, "src/test/java", this.groupPath, this.config.name.toLowerCase().replace(/[^a-z0-9]/g, ""));
24
+ await this.ensureDirs([
25
+ javaDir,
26
+ path.join(javaDir, "config"),
27
+ path.join(javaDir, "shared/exception"),
28
+ path.join(javaDir, "shared/dto"),
29
+ path.join(javaDir, "feature"),
30
+ path.join(resourcesDir, "db/migration"),
31
+ testDir,
32
+ path.join(backendDir, ".mvn/wrapper"),
33
+ ]);
34
+ const data = {
35
+ groupId: this.config.groupId,
36
+ artifactId: this.artifactId,
37
+ packageName: this.packageName,
38
+ name: this.config.name,
39
+ description: this.config.description,
40
+ dbName: this.dbName,
41
+ datasourceUrl: `\${DB_URL:jdbc:postgresql://localhost:5432/${this.dbName}}`,
42
+ versions: this.versions,
43
+ };
44
+ await Promise.all([
45
+ renderAndWrite("backend/pom.xml.hbs", path.join(backendDir, "pom.xml"), data),
46
+ renderAndWrite("backend/Application.java.hbs", path.join(javaDir, "Application.java"), data),
47
+ renderAndWrite("backend/SecurityConfig.java.hbs", path.join(javaDir, "config/SecurityConfig.java"), data),
48
+ renderAndWrite("backend/OpenApiConfig.java.hbs", path.join(javaDir, "config/OpenApiConfig.java"), data),
49
+ renderAndWrite("backend/GlobalExceptionHandler.java.hbs", path.join(javaDir, "shared/exception/GlobalExceptionHandler.java"), data),
50
+ renderAndWrite("backend/ApiError.java.hbs", path.join(javaDir, "shared/exception/ApiError.java"), data),
51
+ renderAndWrite("backend/PageResponse.java.hbs", path.join(javaDir, "shared/dto/PageResponse.java"), data),
52
+ renderAndWrite("backend/application.yml.hbs", path.join(resourcesDir, "application.yml"), data),
53
+ renderAndWrite("backend/application-dev.yml.hbs", path.join(resourcesDir, "application-dev.yml"), data),
54
+ fs.writeFile(path.join(resourcesDir, "db/migration/V1__init.sql"), "-- Initial migration\n"),
55
+ renderAndWrite("backend/ApplicationTests.java.hbs", path.join(testDir, "ApplicationTests.java"), data),
56
+ renderAndWrite("backend/gitignore.hbs", path.join(backendDir, ".gitignore"), data),
57
+ renderAndWrite("backend/maven-wrapper.properties.hbs", path.join(backendDir, ".mvn/wrapper/maven-wrapper.properties"), data),
58
+ renderAndWrite("backend/mvnw.hbs", path.join(backendDir, "mvnw"), data, {
59
+ mode: 0o755,
60
+ }),
61
+ renderAndWrite("backend/mvnw.cmd.hbs", path.join(backendDir, "mvnw.cmd"), data),
62
+ ]);
63
+ }
64
+ }
65
+ export async function generateBackend(projectDir, config, versions) {
66
+ const generator = new BackendGenerator(projectDir, config, versions);
67
+ await generator.generate();
68
+ }
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/generators/backend/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ProjectConfig } from "../types.js";
2
+ export declare abstract class BaseGenerator {
3
+ protected readonly projectDir: string;
4
+ protected readonly config: ProjectConfig;
5
+ constructor(projectDir: string, config: ProjectConfig);
6
+ abstract generate(): Promise<void>;
7
+ protected ensureDirs(dirs: string[]): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=base-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-generator.d.ts","sourceRoot":"","sources":["../../src/generators/base-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,8BAAsB,aAAa;IAE/B,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM;IACrC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa;gBADrB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa;IAG1C,QAAQ,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;cAElB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1D"}
@@ -0,0 +1,13 @@
1
+ import fs from "fs-extra";
2
+ export class BaseGenerator {
3
+ projectDir;
4
+ config;
5
+ constructor(projectDir, config) {
6
+ this.projectDir = projectDir;
7
+ this.config = config;
8
+ }
9
+ async ensureDirs(dirs) {
10
+ await Promise.all(dirs.map((dir) => fs.ensureDir(dir)));
11
+ }
12
+ }
13
+ //# sourceMappingURL=base-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-generator.js","sourceRoot":"","sources":["../../src/generators/base-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAG1B,MAAM,OAAgB,aAAa;IAEZ;IACA;IAFrB,YACqB,UAAkB,EAClB,MAAqB;QADrB,eAAU,GAAV,UAAU,CAAQ;QAClB,WAAM,GAAN,MAAM,CAAe;IACvC,CAAC;IAIM,KAAK,CAAC,UAAU,CAAC,IAAc;QACvC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ import type { ProjectConfig } from "../../types.js";
2
+ export declare function generateCI(projectDir: string, config: ProjectConfig): Promise<void>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/ci/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAcpD,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -0,0 +1,18 @@
1
+ import path from "node:path";
2
+ import { renderAndWrite } from "../../utils/template-engine.js";
3
+ import { BaseGenerator } from "../base-generator.js";
4
+ class CIGenerator extends BaseGenerator {
5
+ async generate() {
6
+ const workflowsDir = path.join(this.projectDir, ".github", "workflows");
7
+ await this.ensureDirs([workflowsDir]);
8
+ await renderAndWrite("ci/ci.yml.hbs", path.join(workflowsDir, "ci.yml"), {
9
+ backend: this.config.backend,
10
+ frontend: this.config.frontend,
11
+ });
12
+ }
13
+ }
14
+ export async function generateCI(projectDir, config) {
15
+ const generator = new CIGenerator(projectDir, config);
16
+ await generator.generate();
17
+ }
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/generators/ci/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,WAAY,SAAQ,aAAa;IACrC,KAAK,CAAC,QAAQ;QACZ,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QACxE,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QAEtC,MAAM,cAAc,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE;YACvE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;SAC/B,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,MAAqB;IAErB,MAAM,SAAS,GAAG,IAAI,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACtD,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ProjectConfig } from "../../types.js";
2
+ import type { ResolvedVersions } from "../../versions.js";
3
+ export declare function generateClaudeCode(projectDir: string, config: ProjectConfig, versions: ResolvedVersions): Promise<void>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/claude-code/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AA+E1D,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -0,0 +1,47 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { renderAndWrite } from "../../utils/template-engine.js";
4
+ import { BaseGenerator } from "../base-generator.js";
5
+ class ClaudeCodeGenerator extends BaseGenerator {
6
+ versions;
7
+ constructor(projectDir, config, versions) {
8
+ super(projectDir, config);
9
+ this.versions = versions;
10
+ }
11
+ async generate() {
12
+ const claudeDir = path.join(this.projectDir, ".claude");
13
+ await fs.ensureDir(claudeDir);
14
+ const allowedCommands = this.buildAllowedCommands();
15
+ const data = {
16
+ name: this.config.name,
17
+ description: this.config.description,
18
+ backend: this.config.backend,
19
+ frontend: this.config.frontend,
20
+ docker: this.config.docker,
21
+ versions: this.versions,
22
+ allowedCommands,
23
+ };
24
+ await Promise.all([
25
+ renderAndWrite("claude-code/CLAUDE.md.hbs", path.join(this.projectDir, "CLAUDE.md"), data),
26
+ renderAndWrite("claude-code/settings.json.hbs", path.join(claudeDir, "settings.json"), data),
27
+ ]);
28
+ }
29
+ buildAllowedCommands() {
30
+ const commands = [];
31
+ if (this.config.backend) {
32
+ commands.push("bash(./mvnw spring-boot:run)", "bash(./mvnw test)", "bash(./mvnw package)", "bash(./mvnw clean)");
33
+ }
34
+ if (this.config.frontend) {
35
+ commands.push("bash(ng serve)", "bash(ng build)", "bash(ng test)", "bash(ng generate)", "bash(npm install)", "bash(npm run)");
36
+ }
37
+ if (this.config.docker) {
38
+ commands.push("bash(docker compose up)", "bash(docker compose down)", "bash(docker compose ps)");
39
+ }
40
+ return commands;
41
+ }
42
+ }
43
+ export async function generateClaudeCode(projectDir, config, versions) {
44
+ const generator = new ClaudeCodeGenerator(projectDir, config, versions);
45
+ await generator.generate();
46
+ }
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/generators/claude-code/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD,MAAM,mBAAoB,SAAQ,aAAa;IAC5B,QAAQ,CAAmB;IAE5C,YACE,UAAkB,EAClB,MAAqB,EACrB,QAA0B;QAE1B,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACxD,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAE9B,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAEpD,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YACpC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,eAAe;SAChB,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,cAAc,CACZ,2BAA2B,EAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACvC,IAAI,CACL;YACD,cAAc,CACZ,+BAA+B,EAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EACrC,IAAI,CACL;SACF,CAAC,CAAC;IACL,CAAC;IAEO,oBAAoB;QAC1B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CACX,8BAA8B,EAC9B,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,CACrB,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CACX,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,CAChB,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CACX,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,CAC1B,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAkB,EAClB,MAAqB,EACrB,QAA0B;IAE1B,MAAM,SAAS,GAAG,IAAI,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxE,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ProjectConfig } from "../../types.js";
2
+ export declare function generateDocker(projectDir: string, config: ProjectConfig): Promise<void>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/docker/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAcpD,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -0,0 +1,14 @@
1
+ import path from "node:path";
2
+ import { renderAndWrite } from "../../utils/template-engine.js";
3
+ import { BaseGenerator } from "../base-generator.js";
4
+ class DockerGenerator extends BaseGenerator {
5
+ async generate() {
6
+ const dbName = this.config.name.toLowerCase().replace(/[^a-z0-9]/g, "_");
7
+ await renderAndWrite("docker/docker-compose.yml.hbs", path.join(this.projectDir, "docker-compose.yml"), { dbName });
8
+ }
9
+ }
10
+ export async function generateDocker(projectDir, config) {
11
+ const generator = new DockerGenerator(projectDir, config);
12
+ await generator.generate();
13
+ }
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/generators/docker/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,eAAgB,SAAQ,aAAa;IACzC,KAAK,CAAC,QAAQ;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAEzE,MAAM,cAAc,CAClB,+BAA+B,EAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,EAChD,EAAE,MAAM,EAAE,CACX,CAAC;IACJ,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAkB,EAClB,MAAqB;IAErB,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ProjectConfig } from "../../types.js";
2
+ import type { ResolvedVersions } from "../../versions.js";
3
+ export declare function generateFrontend(projectDir: string, config: ProjectConfig, versions: ResolvedVersions): Promise<void>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/frontend/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAgJ1D,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,IAAI,CAAC,CAGf"}