@lastbrain/app 0.1.7 → 0.1.9

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 (40) hide show
  1. package/dist/scripts/init-app.js +3 -3
  2. package/dist/styles.css +2 -0
  3. package/package.json +11 -3
  4. package/src/app-shell/(admin)/layout.tsx +13 -0
  5. package/src/app-shell/(auth)/layout.tsx +13 -0
  6. package/src/app-shell/(public)/page.tsx +11 -0
  7. package/src/app-shell/layout.tsx +5 -0
  8. package/src/app-shell/not-found.tsx +28 -0
  9. package/src/auth/authHelpers.ts +24 -0
  10. package/src/auth/useAuthSession.ts +54 -0
  11. package/src/cli.ts +96 -0
  12. package/src/index.ts +21 -0
  13. package/src/layouts/AdminLayout.tsx +7 -0
  14. package/src/layouts/AppProviders.tsx +61 -0
  15. package/src/layouts/AuthLayout.tsx +7 -0
  16. package/src/layouts/PublicLayout.tsx +7 -0
  17. package/src/layouts/RootLayout.tsx +27 -0
  18. package/src/modules/module-loader.ts +14 -0
  19. package/src/scripts/README.md +262 -0
  20. package/src/scripts/db-init.ts +338 -0
  21. package/src/scripts/db-migrations-sync.ts +86 -0
  22. package/src/scripts/dev-sync.ts +218 -0
  23. package/src/scripts/init-app.ts +1077 -0
  24. package/src/scripts/module-add.ts +242 -0
  25. package/src/scripts/module-build.ts +502 -0
  26. package/src/scripts/module-create.ts +809 -0
  27. package/src/scripts/module-list.ts +37 -0
  28. package/src/scripts/module-remove.ts +367 -0
  29. package/src/scripts/readme-build.ts +60 -0
  30. package/src/styles.css +3 -0
  31. package/src/templates/AuthGuidePage.tsx +68 -0
  32. package/src/templates/DefaultDoc.tsx +462 -0
  33. package/src/templates/DocPage.tsx +381 -0
  34. package/src/templates/DocsPageWithModules.tsx +22 -0
  35. package/src/templates/MigrationsGuidePage.tsx +61 -0
  36. package/src/templates/ModuleGuidePage.tsx +71 -0
  37. package/src/templates/SimpleDocPage.tsx +587 -0
  38. package/src/templates/SimpleHomePage.tsx +385 -0
  39. package/src/templates/env.example/.env.example +6 -0
  40. package/src/templates/migrations/20201010100000_app_base.sql +228 -0
@@ -0,0 +1,242 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ import chalk from "chalk";
4
+ import { execSync } from "child_process";
5
+ import inquirer from "inquirer";
6
+
7
+ interface ModuleDefinition {
8
+ name: string;
9
+ package: string;
10
+ displayName: string;
11
+ description: string;
12
+ hasMigrations: boolean;
13
+ migrationsPath?: string;
14
+ migrationsDownPath?: string;
15
+ }
16
+
17
+ // Registre des modules disponibles
18
+ export const AVAILABLE_MODULES: ModuleDefinition[] = [
19
+ {
20
+ name: "auth",
21
+ package: "@lastbrain/module-auth",
22
+ displayName: "🔐 Authentication",
23
+ description:
24
+ "Système d'authentification complet (signin, signup, sessions)",
25
+ hasMigrations: true,
26
+ migrationsPath: "supabase/migrations",
27
+ migrationsDownPath: "supabase/migrations-down",
28
+ },
29
+ {
30
+ name: "ai",
31
+ package: "@lastbrain/module-ai",
32
+ displayName: "🤖 AI Generation",
33
+ description:
34
+ "Génération de texte et d'images avec gestion de tokens",
35
+ hasMigrations: true,
36
+ migrationsPath: "supabase/migrations",
37
+ migrationsDownPath: "supabase/migrations-down",
38
+ },
39
+ // Ajouter d'autres modules ici au fur et à mesure
40
+ ];
41
+
42
+ export async function addModule(moduleName: string, targetDir: string) {
43
+ console.log(chalk.blue(`\n🔧 Ajout du module: ${moduleName}\n`));
44
+
45
+ const module = AVAILABLE_MODULES.find((m) => m.name === moduleName);
46
+ if (!module) {
47
+ console.error(
48
+ chalk.red(`❌ Module "${moduleName}" non trouvé. Modules disponibles:`)
49
+ );
50
+ AVAILABLE_MODULES.forEach((m) => {
51
+ console.log(chalk.gray(` - ${m.name}: ${m.description}`));
52
+ });
53
+ process.exit(1);
54
+ }
55
+
56
+ // 1. Vérifier qu'on est dans un projet LastBrain
57
+ const pkgPath = path.join(targetDir, "package.json");
58
+ if (!fs.existsSync(pkgPath)) {
59
+ console.error(chalk.red("❌ package.json non trouvé"));
60
+ process.exit(1);
61
+ }
62
+
63
+ const pkg = await fs.readJson(pkgPath);
64
+
65
+ // Vérifier si le module n'est pas déjà installé
66
+ if (
67
+ pkg.dependencies?.[module.package] ||
68
+ pkg.devDependencies?.[module.package]
69
+ ) {
70
+ console.log(chalk.yellow(`⚠️ Module ${module.package} déjà installé`));
71
+ return;
72
+ }
73
+
74
+ // 2. Ajouter la dépendance au package.json
75
+ console.log(chalk.yellow(`📦 Ajout de ${module.package} aux dépendances...`));
76
+ pkg.dependencies = pkg.dependencies || {};
77
+ pkg.dependencies[module.package] = "workspace:*";
78
+ await fs.writeJson(pkgPath, pkg, { spaces: 2 });
79
+
80
+ // 3. Installer les dépendances
81
+ console.log(chalk.yellow("📥 Installation des dépendances..."));
82
+ try {
83
+ execSync("pnpm install", { cwd: targetDir, stdio: "inherit" });
84
+ } catch (error) {
85
+ console.error(chalk.red("❌ Erreur lors de l'installation"));
86
+ process.exit(1);
87
+ }
88
+
89
+ // 5. Copier les migrations du module
90
+ let copiedMigrationFiles: string[] = [];
91
+
92
+ if (module.hasMigrations) {
93
+ console.log(chalk.yellow("\n📋 Copie des migrations du module..."));
94
+
95
+ // Trouver le chemin du module installé
96
+ const modulePackagePath = path.join(
97
+ targetDir,
98
+ "node_modules",
99
+ ...module.package.split("/")
100
+ );
101
+
102
+ const moduleMigrationsDir = path.join(
103
+ modulePackagePath,
104
+ module.migrationsPath || "supabase/migrations"
105
+ );
106
+
107
+ const projectMigrationsDir = path.join(targetDir, "supabase", "migrations");
108
+ await fs.ensureDir(projectMigrationsDir);
109
+
110
+ if (fs.existsSync(moduleMigrationsDir)) {
111
+ const migrationFiles = fs.readdirSync(moduleMigrationsDir);
112
+
113
+ for (const file of migrationFiles) {
114
+ if (file.endsWith(".sql")) {
115
+ const sourcePath = path.join(moduleMigrationsDir, file);
116
+ const destPath = path.join(projectMigrationsDir, file);
117
+
118
+ await fs.copyFile(sourcePath, destPath);
119
+ copiedMigrationFiles.push(file);
120
+ console.log(chalk.green(` ✓ ${file}`));
121
+ }
122
+ }
123
+
124
+ // 6. Demander comment appliquer les migrations
125
+ console.log(
126
+ chalk.yellow("\n🗄️ Application des migrations à la base de données\n")
127
+ );
128
+
129
+ console.log("Choisissez une option:");
130
+ console.log(chalk.cyan(" 1) 🔄 Reset complet (supabase db reset) - Recommandé en dev"));
131
+ console.log(chalk.cyan(" 2) ⬆️ Push uniquement les nouvelles migrations (supabase migration up)"));
132
+ console.log(chalk.cyan(" 3) ⏭️ Ignorer pour l'instant"));
133
+ console.log("");
134
+
135
+ const { migrationAction } = await inquirer.prompt([
136
+ {
137
+ type: "rawlist",
138
+ name: "migrationAction",
139
+ message: "Comment voulez-vous appliquer les migrations ?",
140
+ choices: [
141
+ {
142
+ name: "🔄 Reset complet (supabase db reset) - Recommandé en dev",
143
+ value: "reset",
144
+ },
145
+ {
146
+ name: "⬆️ Push uniquement les nouvelles migrations (supabase migration up)",
147
+ value: "push",
148
+ },
149
+ {
150
+ name: "⏭️ Ignorer pour l'instant",
151
+ value: "skip",
152
+ },
153
+ ],
154
+ },
155
+ ]);
156
+
157
+ if (migrationAction === "reset") {
158
+ console.log(chalk.yellow("\n🔄 Reset de la base de données..."));
159
+ try {
160
+ execSync("supabase db reset", { cwd: targetDir, stdio: "inherit" });
161
+ console.log(chalk.green("✓ Base de données réinitialisée"));
162
+ } catch (error) {
163
+ console.error(chalk.red("❌ Erreur lors du reset"));
164
+ }
165
+ } else if (migrationAction === "push") {
166
+ console.log(chalk.yellow("\n⬆️ Application des nouvelles migrations..."));
167
+ try {
168
+ execSync("supabase migration up", { cwd: targetDir, stdio: "inherit" });
169
+ console.log(chalk.green("✓ Migrations appliquées"));
170
+ } catch (error) {
171
+ console.error(chalk.red("❌ Erreur lors de l'application des migrations"));
172
+ }
173
+ } else {
174
+ console.log(
175
+ chalk.gray(
176
+ "\n⚠️ N'oubliez pas d'appliquer les migrations avec:\n supabase db reset ou supabase migration up\n"
177
+ )
178
+ );
179
+ }
180
+ } else {
181
+ console.log(chalk.gray(" Aucune migration trouvée pour ce module"));
182
+ }
183
+ }
184
+
185
+ // 4. Enregistrer le module dans la configuration
186
+ const modulesConfigPath = path.join(targetDir, ".lastbrain", "modules.json");
187
+ await fs.ensureDir(path.dirname(modulesConfigPath));
188
+
189
+ interface ModuleConfig {
190
+ modules: Array<{
191
+ package: string;
192
+ active: boolean;
193
+ migrations?: string[];
194
+ }>;
195
+ }
196
+
197
+ let modulesConfig: ModuleConfig = { modules: [] };
198
+ if (fs.existsSync(modulesConfigPath)) {
199
+ modulesConfig = await fs.readJson(modulesConfigPath);
200
+ }
201
+
202
+ // Initialiser tous les modules disponibles s'ils n'existent pas
203
+ for (const availableModule of AVAILABLE_MODULES) {
204
+ const exists = modulesConfig.modules.find(m => m.package === availableModule.package);
205
+ if (!exists) {
206
+ modulesConfig.modules.push({
207
+ package: availableModule.package,
208
+ active: false,
209
+ migrations: [],
210
+ });
211
+ }
212
+ }
213
+
214
+ const existingModuleIndex = modulesConfig.modules.findIndex(
215
+ (m) => m.package === module.package
216
+ );
217
+
218
+ const migrationsList = copiedMigrationFiles;
219
+
220
+ if (existingModuleIndex >= 0) {
221
+ modulesConfig.modules[existingModuleIndex] = {
222
+ package: module.package,
223
+ active: true,
224
+ migrations: migrationsList,
225
+ };
226
+ } else {
227
+ modulesConfig.modules.push({
228
+ package: module.package,
229
+ active: true,
230
+ migrations: migrationsList,
231
+ });
232
+ }
233
+
234
+ await fs.writeJson(modulesConfigPath, modulesConfig, { spaces: 2 });
235
+
236
+ console.log(
237
+ chalk.green(`\n✅ Module ${module.displayName} ajouté avec succès!\n`)
238
+ );
239
+ console.log(
240
+ chalk.gray("Le serveur de développement redémarrera automatiquement.\n")
241
+ );
242
+ }