@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.
- package/dist/scripts/init-app.js +3 -3
- package/dist/styles.css +2 -0
- package/package.json +11 -3
- package/src/app-shell/(admin)/layout.tsx +13 -0
- package/src/app-shell/(auth)/layout.tsx +13 -0
- package/src/app-shell/(public)/page.tsx +11 -0
- package/src/app-shell/layout.tsx +5 -0
- package/src/app-shell/not-found.tsx +28 -0
- package/src/auth/authHelpers.ts +24 -0
- package/src/auth/useAuthSession.ts +54 -0
- package/src/cli.ts +96 -0
- package/src/index.ts +21 -0
- package/src/layouts/AdminLayout.tsx +7 -0
- package/src/layouts/AppProviders.tsx +61 -0
- package/src/layouts/AuthLayout.tsx +7 -0
- package/src/layouts/PublicLayout.tsx +7 -0
- package/src/layouts/RootLayout.tsx +27 -0
- package/src/modules/module-loader.ts +14 -0
- package/src/scripts/README.md +262 -0
- package/src/scripts/db-init.ts +338 -0
- package/src/scripts/db-migrations-sync.ts +86 -0
- package/src/scripts/dev-sync.ts +218 -0
- package/src/scripts/init-app.ts +1077 -0
- package/src/scripts/module-add.ts +242 -0
- package/src/scripts/module-build.ts +502 -0
- package/src/scripts/module-create.ts +809 -0
- package/src/scripts/module-list.ts +37 -0
- package/src/scripts/module-remove.ts +367 -0
- package/src/scripts/readme-build.ts +60 -0
- package/src/styles.css +3 -0
- package/src/templates/AuthGuidePage.tsx +68 -0
- package/src/templates/DefaultDoc.tsx +462 -0
- package/src/templates/DocPage.tsx +381 -0
- package/src/templates/DocsPageWithModules.tsx +22 -0
- package/src/templates/MigrationsGuidePage.tsx +61 -0
- package/src/templates/ModuleGuidePage.tsx +71 -0
- package/src/templates/SimpleDocPage.tsx +587 -0
- package/src/templates/SimpleHomePage.tsx +385 -0
- package/src/templates/env.example/.env.example +6 -0
- 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
|
+
}
|