@lastbrain/app 0.1.25 → 0.1.27

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 (54) hide show
  1. package/dist/app-shell/(public)/page.d.ts.map +1 -1
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +4 -0
  5. package/dist/layouts/AdminLayoutWithSidebar.d.ts +8 -0
  6. package/dist/layouts/AdminLayoutWithSidebar.d.ts.map +1 -0
  7. package/dist/layouts/AdminLayoutWithSidebar.js +9 -0
  8. package/dist/layouts/AuthLayoutWithSidebar.d.ts +8 -0
  9. package/dist/layouts/AuthLayoutWithSidebar.d.ts.map +1 -0
  10. package/dist/layouts/AuthLayoutWithSidebar.js +9 -0
  11. package/dist/scripts/db-init.js +2 -2
  12. package/dist/scripts/dev-sync.js +23 -12
  13. package/dist/scripts/init-app.d.ts.map +1 -1
  14. package/dist/scripts/init-app.js +114 -12
  15. package/dist/scripts/module-add.d.ts.map +1 -1
  16. package/dist/scripts/module-add.js +19 -6
  17. package/dist/scripts/module-build.d.ts.map +1 -1
  18. package/dist/scripts/module-build.js +288 -30
  19. package/dist/scripts/module-create.d.ts.map +1 -1
  20. package/dist/scripts/module-create.js +25 -15
  21. package/dist/scripts/module-remove.d.ts.map +1 -1
  22. package/dist/scripts/module-remove.js +28 -15
  23. package/dist/scripts/script-runner.js +1 -1
  24. package/dist/styles.css +1 -1
  25. package/dist/templates/DefaultDoc.js +1 -7
  26. package/dist/templates/components/AppAside.d.ts +6 -0
  27. package/dist/templates/components/AppAside.d.ts.map +1 -0
  28. package/dist/templates/components/AppAside.js +9 -0
  29. package/dist/templates/layouts/admin-layout.d.ts +4 -0
  30. package/dist/templates/layouts/admin-layout.d.ts.map +1 -0
  31. package/dist/templates/layouts/admin-layout.js +6 -0
  32. package/dist/templates/layouts/auth-layout.d.ts +4 -0
  33. package/dist/templates/layouts/auth-layout.d.ts.map +1 -0
  34. package/dist/templates/layouts/auth-layout.js +6 -0
  35. package/package.json +2 -1
  36. package/src/app-shell/(public)/page.tsx +6 -2
  37. package/src/auth/useAuthSession.ts +1 -1
  38. package/src/cli.ts +1 -1
  39. package/src/index.ts +6 -0
  40. package/src/layouts/AdminLayoutWithSidebar.tsx +35 -0
  41. package/src/layouts/AppProviders.tsx +1 -1
  42. package/src/layouts/AuthLayoutWithSidebar.tsx +35 -0
  43. package/src/scripts/db-init.ts +13 -8
  44. package/src/scripts/db-migrations-sync.ts +4 -4
  45. package/src/scripts/dev-sync.ts +50 -19
  46. package/src/scripts/init-app.ts +243 -65
  47. package/src/scripts/module-add.ts +54 -22
  48. package/src/scripts/module-build.ts +412 -88
  49. package/src/scripts/module-create.ts +85 -49
  50. package/src/scripts/module-remove.ts +120 -61
  51. package/src/scripts/readme-build.ts +2 -2
  52. package/src/scripts/script-runner.ts +3 -3
  53. package/src/templates/AuthGuidePage.tsx +1 -1
  54. package/src/templates/DefaultDoc.tsx +7 -7
@@ -48,21 +48,34 @@ function parseTablesList(input: string): string[] {
48
48
  /**
49
49
  * Récupère les versions actuelles des packages LastBrain
50
50
  */
51
- function getLastBrainPackageVersions(rootDir: string): { core: string; ui: string } {
51
+ function getLastBrainPackageVersions(rootDir: string): {
52
+ core: string;
53
+ ui: string;
54
+ } {
52
55
  try {
53
56
  const corePackageJson = JSON.parse(
54
- fs.readFileSync(path.join(rootDir, "packages", "core", "package.json"), "utf-8")
57
+ fs.readFileSync(
58
+ path.join(rootDir, "packages", "core", "package.json"),
59
+ "utf-8",
60
+ ),
55
61
  );
56
62
  const uiPackageJson = JSON.parse(
57
- fs.readFileSync(path.join(rootDir, "packages", "ui", "package.json"), "utf-8")
63
+ fs.readFileSync(
64
+ path.join(rootDir, "packages", "ui", "package.json"),
65
+ "utf-8",
66
+ ),
58
67
  );
59
-
68
+
60
69
  return {
61
70
  core: `^${corePackageJson.version}`,
62
71
  ui: `^${uiPackageJson.version}`,
63
72
  };
64
- } catch (error) {
65
- console.warn(chalk.yellow("⚠️ Impossible de lire les versions des packages, utilisation des versions par défaut"));
73
+ } catch {
74
+ console.warn(
75
+ chalk.yellow(
76
+ "⚠️ Impossible de lire les versions des packages, utilisation des versions par défaut",
77
+ ),
78
+ );
66
79
  return {
67
80
  core: "^0.1.0",
68
81
  ui: "^0.1.4",
@@ -73,7 +86,11 @@ function getLastBrainPackageVersions(rootDir: string): { core: string; ui: strin
73
86
  /**
74
87
  * Génère le contenu du package.json
75
88
  */
76
- function generatePackageJson(moduleName: string, slug: string, rootDir: string): string {
89
+ function generatePackageJson(
90
+ moduleName: string,
91
+ slug: string,
92
+ rootDir: string,
93
+ ): string {
77
94
  const versions = getLastBrainPackageVersions(rootDir);
78
95
  const buildConfigExport = `./${slug}.build.config`;
79
96
  return JSON.stringify(
@@ -120,7 +137,7 @@ function generatePackageJson(moduleName: string, slug: string, rootDir: string):
120
137
  sideEffects: false,
121
138
  },
122
139
  null,
123
- 2
140
+ 2,
124
141
  );
125
142
  }
126
143
 
@@ -139,7 +156,7 @@ function generateTsConfig(): string {
139
156
  include: ["src"],
140
157
  },
141
158
  null,
142
- 2
159
+ 2,
143
160
  );
144
161
  }
145
162
 
@@ -181,9 +198,9 @@ function generateBuildConfig(config: ModuleConfig): string {
181
198
 
182
199
  // Générer les menus par section
183
200
  const menuSections: { section: string; items: string[] }[] = [];
184
-
201
+
185
202
  // Menu public
186
- const publicPages = pages.filter(p => p.section === "public");
203
+ const publicPages = pages.filter((p) => p.section === "public");
187
204
  if (publicPages.length > 0) {
188
205
  const publicMenuItems = publicPages.map((page, index) => {
189
206
  const title = page.name
@@ -202,7 +219,7 @@ function generateBuildConfig(config: ModuleConfig): string {
202
219
  }
203
220
 
204
221
  // Menu auth
205
- const authPages = pages.filter(p => p.section === "auth");
222
+ const authPages = pages.filter((p) => p.section === "auth");
206
223
  if (authPages.length > 0) {
207
224
  const authMenuItems = authPages.map((page, index) => {
208
225
  const title = page.name
@@ -221,7 +238,7 @@ function generateBuildConfig(config: ModuleConfig): string {
221
238
  }
222
239
 
223
240
  // Menu admin
224
- const adminPages = pages.filter(p => p.section === "admin");
241
+ const adminPages = pages.filter((p) => p.section === "admin");
225
242
  if (adminPages.length > 0) {
226
243
  const adminMenuItems = adminPages.map((page, index) => {
227
244
  const title = page.name
@@ -240,14 +257,19 @@ function generateBuildConfig(config: ModuleConfig): string {
240
257
  }
241
258
 
242
259
  // Générer la configuration menu
243
- const menuConfig = menuSections.length > 0
244
- ? `,
260
+ const menuConfig =
261
+ menuSections.length > 0
262
+ ? `,
245
263
  menu: {
246
- ${menuSections.map(({ section, items }) => ` ${section}: [
264
+ ${menuSections
265
+ .map(
266
+ ({ section, items }) => ` ${section}: [
247
267
  ${items.join(",\n")}
248
- ]`).join(",\n")}
249
- }`
250
- : "";
268
+ ]`,
269
+ )
270
+ .join(",\n")}
271
+ }`
272
+ : "";
251
273
 
252
274
  return `import type { ModuleBuildConfig } from "@lastbrain/core";
253
275
 
@@ -304,7 +326,7 @@ function generateServerTs(tables: TableConfig[]): string {
304
326
  for (const table of tables) {
305
327
  for (const section of table.sections) {
306
328
  exports.push(
307
- `export { GET, POST, PUT, DELETE } from "./api/${section}/${table.name}.js";`
329
+ `export { GET, POST, PUT, DELETE } from "./api/${section}/${table.name}.js";`,
308
330
  );
309
331
  }
310
332
  }
@@ -368,12 +390,16 @@ const jsonResponse = (payload: unknown, status = 200) => {
368
390
  */
369
391
  export async function GET(request: Request) {
370
392
  const supabase = await getSupabaseServerClient();
371
- ${authRequired ? `
393
+ ${
394
+ authRequired
395
+ ? `
372
396
  const { data: { user }, error: authError } = await supabase.auth.getUser();
373
397
  if (authError || !user) {
374
398
  return jsonResponse({ error: "Non authentifié" }, 401);
375
399
  }
376
- ` : ""}
400
+ `
401
+ : ""
402
+ }
377
403
 
378
404
  const { data, error } = await supabase
379
405
  .from("${tableName}")
@@ -391,12 +417,16 @@ export async function GET(request: Request) {
391
417
  */
392
418
  export async function POST(request: Request) {
393
419
  const supabase = await getSupabaseServerClient();
394
- ${authRequired ? `
420
+ ${
421
+ authRequired
422
+ ? `
395
423
  const { data: { user }, error: authError } = await supabase.auth.getUser();
396
424
  if (authError || !user) {
397
425
  return jsonResponse({ error: "Non authentifié" }, 401);
398
426
  }
399
- ` : ""}
427
+ `
428
+ : ""
429
+ }
400
430
 
401
431
  const body = await request.json();
402
432
 
@@ -418,12 +448,16 @@ export async function POST(request: Request) {
418
448
  */
419
449
  export async function PUT(request: Request) {
420
450
  const supabase = await getSupabaseServerClient();
421
- ${authRequired ? `
451
+ ${
452
+ authRequired
453
+ ? `
422
454
  const { data: { user }, error: authError } = await supabase.auth.getUser();
423
455
  if (authError || !user) {
424
456
  return jsonResponse({ error: "Non authentifié" }, 401);
425
457
  }
426
- ` : ""}
458
+ `
459
+ : ""
460
+ }
427
461
 
428
462
  const body = await request.json();
429
463
  const { id, ...updateData } = body;
@@ -451,12 +485,16 @@ export async function PUT(request: Request) {
451
485
  */
452
486
  export async function DELETE(request: Request) {
453
487
  const supabase = await getSupabaseServerClient();
454
- ${authRequired ? `
488
+ ${
489
+ authRequired
490
+ ? `
455
491
  const { data: { user }, error: authError } = await supabase.auth.getUser();
456
492
  if (authError || !user) {
457
493
  return jsonResponse({ error: "Non authentifié" }, 401);
458
494
  }
459
- ` : ""}
495
+ `
496
+ : ""
497
+ }
460
498
 
461
499
  const { searchParams } = new URL(request.url);
462
500
  const id = searchParams.get("id");
@@ -483,7 +521,7 @@ export async function DELETE(request: Request) {
483
521
  * Génère le contenu d'un fichier de migration SQL
484
522
  */
485
523
  function generateMigration(tables: TableConfig[], slug: string): string {
486
- const timestamp = new Date()
524
+ const _timestamp = new Date()
487
525
  .toISOString()
488
526
  .replace(/[-:]/g, "")
489
527
  .split(".")[0]
@@ -586,36 +624,33 @@ async function createModuleStructure(config: ModuleConfig, rootDir: string) {
586
624
  console.log(chalk.yellow(" 📄 package.json"));
587
625
  await fs.writeFile(
588
626
  path.join(moduleDir, "package.json"),
589
- generatePackageJson(config.moduleName, config.slug, rootDir)
627
+ generatePackageJson(config.moduleName, config.slug, rootDir),
590
628
  );
591
629
 
592
630
  // Créer tsconfig.json
593
631
  console.log(chalk.yellow(" 📄 tsconfig.json"));
594
- await fs.writeFile(
595
- path.join(moduleDir, "tsconfig.json"),
596
- generateTsConfig()
597
- );
632
+ await fs.writeFile(path.join(moduleDir, "tsconfig.json"), generateTsConfig());
598
633
 
599
634
  // Créer {slug}.build.config.ts
600
635
  const buildConfigFileName = `${config.slug}.build.config.ts`;
601
636
  console.log(chalk.yellow(` 📄 src/${buildConfigFileName}`));
602
637
  await fs.writeFile(
603
638
  path.join(moduleDir, "src", buildConfigFileName),
604
- generateBuildConfig(config)
639
+ generateBuildConfig(config),
605
640
  );
606
641
 
607
642
  // Créer index.ts
608
643
  console.log(chalk.yellow(" 📄 src/index.ts"));
609
644
  await fs.writeFile(
610
645
  path.join(moduleDir, "src", "index.ts"),
611
- generateIndexTs(config.pages)
646
+ generateIndexTs(config.pages),
612
647
  );
613
648
 
614
649
  // Créer server.ts
615
650
  console.log(chalk.yellow(" 📄 src/server.ts"));
616
651
  await fs.writeFile(
617
652
  path.join(moduleDir, "src", "server.ts"),
618
- generateServerTs(config.tables)
653
+ generateServerTs(config.tables),
619
654
  );
620
655
 
621
656
  // Créer les pages
@@ -633,7 +668,7 @@ async function createModuleStructure(config: ModuleConfig, rootDir: string) {
633
668
  console.log(chalk.yellow(` 📄 src/web/${page.section}/${fileName}`));
634
669
  await fs.writeFile(
635
670
  path.join(pagePath, fileName),
636
- generatePageComponent(page.name, page.section)
671
+ generatePageComponent(page.name, page.section),
637
672
  );
638
673
  }
639
674
 
@@ -649,7 +684,7 @@ async function createModuleStructure(config: ModuleConfig, rootDir: string) {
649
684
  console.log(chalk.yellow(` 📄 src/api/${section}/${fileName}`));
650
685
  await fs.writeFile(
651
686
  path.join(apiPath, fileName),
652
- generateApiRoute(table.name, section)
687
+ generateApiRoute(table.name, section),
653
688
  );
654
689
  }
655
690
  }
@@ -665,12 +700,10 @@ async function createModuleStructure(config: ModuleConfig, rootDir: string) {
665
700
  .replace("T", "");
666
701
 
667
702
  const migrationFileName = `${timestamp}_${config.slug}_init.sql`;
668
- console.log(
669
- chalk.yellow(` 📄 supabase/migrations/${migrationFileName}`)
670
- );
703
+ console.log(chalk.yellow(` 📄 supabase/migrations/${migrationFileName}`));
671
704
  await fs.writeFile(
672
705
  path.join(moduleDir, "supabase", "migrations", migrationFileName),
673
- generateMigration(config.tables, config.slug)
706
+ generateMigration(config.tables, config.slug),
674
707
  );
675
708
  }
676
709
 
@@ -682,8 +715,8 @@ async function createModuleStructure(config: ModuleConfig, rootDir: string) {
682
715
  console.log(chalk.gray(` 3. pnpm build`));
683
716
  console.log(
684
717
  chalk.gray(
685
- ` 4. Ajouter le module à votre app avec: pnpm lastbrain add ${config.slug.replace("module-", "")}\n`
686
- )
718
+ ` 4. Ajouter le module à votre app avec: pnpm lastbrain add ${config.slug.replace("module-", "")}\n`,
719
+ ),
687
720
  );
688
721
  }
689
722
 
@@ -726,8 +759,7 @@ export async function createModule() {
726
759
  {
727
760
  type: "input",
728
761
  name: "pagesAdmin",
729
- message:
730
- "Pages admin (séparées par des virgules, ex: settings, users):",
762
+ message: "Pages admin (séparées par des virgules, ex: settings, users):",
731
763
  default: "",
732
764
  },
733
765
  {
@@ -807,7 +839,7 @@ export async function createModule() {
807
839
  let rootDir = process.cwd();
808
840
  let attempts = 0;
809
841
  const maxAttempts = 5;
810
-
842
+
811
843
  while (attempts < maxAttempts) {
812
844
  const workspaceFile = path.join(rootDir, "pnpm-workspace.yaml");
813
845
  if (fs.existsSync(workspaceFile)) {
@@ -818,7 +850,11 @@ export async function createModule() {
818
850
  }
819
851
 
820
852
  if (attempts === maxAttempts) {
821
- console.error(chalk.red("❌ Impossible de trouver le répertoire racine du workspace (pnpm-workspace.yaml non trouvé)"));
853
+ console.error(
854
+ chalk.red(
855
+ "❌ Impossible de trouver le répertoire racine du workspace (pnpm-workspace.yaml non trouvé)",
856
+ ),
857
+ );
822
858
  process.exit(1);
823
859
  }
824
860
 
@@ -8,7 +8,7 @@ import { AVAILABLE_MODULES } from "./module-add.js";
8
8
  async function removeGeneratedFiles(
9
9
  moduleName: string,
10
10
  modulePackage: string,
11
- targetDir: string
11
+ targetDir: string,
12
12
  ) {
13
13
  console.log(chalk.yellow("\n🗑️ Suppression des pages générées..."));
14
14
 
@@ -38,7 +38,7 @@ async function removeGeneratedFiles(
38
38
  ) {
39
39
  await fs.remove(fullPath);
40
40
  console.log(
41
- chalk.gray(` ✓ Supprimé ${path.relative(targetDir, fullPath)}`)
41
+ chalk.gray(` ✓ Supprimé ${path.relative(targetDir, fullPath)}`),
42
42
  );
43
43
 
44
44
  // Supprimer le dossier parent si vide
@@ -48,7 +48,7 @@ async function removeGeneratedFiles(
48
48
  await fs.remove(parentDir);
49
49
  }
50
50
  }
51
- } catch (error) {
51
+ } catch {
52
52
  // Ignorer les erreurs de lecture
53
53
  }
54
54
  }
@@ -71,7 +71,7 @@ export async function removeModule(moduleName: string, targetDir: string) {
71
71
  const module = AVAILABLE_MODULES.find((m) => m.name === moduleName);
72
72
  if (!module) {
73
73
  console.error(
74
- chalk.red(`❌ Module "${moduleName}" non trouvé. Modules disponibles:`)
74
+ chalk.red(`❌ Module "${moduleName}" non trouvé. Modules disponibles:`),
75
75
  );
76
76
  AVAILABLE_MODULES.forEach((m) => {
77
77
  console.log(chalk.gray(` - ${m.name}: ${m.description}`));
@@ -102,14 +102,14 @@ export async function removeModule(moduleName: string, targetDir: string) {
102
102
 
103
103
  if (!isInstalledInPackage && !isInstalledInConfig) {
104
104
  console.log(
105
- chalk.yellow(`⚠️ Module ${module.package} n'est pas installé`)
105
+ chalk.yellow(`⚠️ Module ${module.package} n'est pas installé`),
106
106
  );
107
107
  return;
108
108
  }
109
109
 
110
110
  // 2. Retirer la dépendance du package.json
111
111
  console.log(
112
- chalk.yellow(`📦 Suppression de ${module.package} des dépendances...`)
112
+ chalk.yellow(`📦 Suppression de ${module.package} des dépendances...`),
113
113
  );
114
114
  if (pkg.dependencies?.[module.package]) {
115
115
  delete pkg.dependencies[module.package];
@@ -123,7 +123,7 @@ export async function removeModule(moduleName: string, targetDir: string) {
123
123
  if (fs.existsSync(modulesConfigPath)) {
124
124
  const modulesConfig = await fs.readJson(modulesConfigPath);
125
125
  modulesConfig.modules = modulesConfig.modules.filter(
126
- (m: string) => m !== module.package
126
+ (m: string) => m !== module.package,
127
127
  );
128
128
  await fs.writeJson(modulesConfigPath, modulesConfig, { spaces: 2 });
129
129
  }
@@ -138,41 +138,59 @@ export async function removeModule(moduleName: string, targetDir: string) {
138
138
  const projectMigrationsDir = path.join(targetDir, "supabase", "migrations");
139
139
 
140
140
  // Récupérer la liste des migrations depuis modules.json
141
- const modulesConfigPath = path.join(targetDir, ".lastbrain", "modules.json");
141
+ const modulesConfigPath = path.join(
142
+ targetDir,
143
+ ".lastbrain",
144
+ "modules.json",
145
+ );
142
146
  let migrationFiles: string[] = [];
143
-
147
+
144
148
  if (fs.existsSync(modulesConfigPath)) {
145
149
  const modulesConfig = await fs.readJson(modulesConfigPath);
146
- const moduleEntry = modulesConfig.modules.find((m: any) =>
147
- (typeof m === 'string' ? m : m.package) === module.package
150
+ const moduleEntry = modulesConfig.modules.find(
151
+ (m: any) => (typeof m === "string" ? m : m.package) === module.package,
148
152
  );
149
-
150
- if (moduleEntry && typeof moduleEntry === 'object' && moduleEntry.migrations) {
153
+
154
+ if (
155
+ moduleEntry &&
156
+ typeof moduleEntry === "object" &&
157
+ moduleEntry.migrations
158
+ ) {
151
159
  migrationFiles = moduleEntry.migrations;
152
- console.log(chalk.gray(`DEBUG: Migrations from config: ${migrationFiles.join(', ')}`));
160
+ console.log(
161
+ chalk.gray(
162
+ `DEBUG: Migrations from config: ${migrationFiles.join(", ")}`,
163
+ ),
164
+ );
153
165
  }
154
166
  }
155
-
167
+
156
168
  // Fallback: essayer de lire depuis node_modules si disponible
157
169
  if (migrationFiles.length === 0) {
158
170
  const modulePackagePath = path.join(
159
171
  targetDir,
160
172
  "node_modules",
161
- ...module.package.split("/")
173
+ ...module.package.split("/"),
162
174
  );
163
175
 
164
176
  const moduleMigrationsDir = path.join(
165
177
  modulePackagePath,
166
- module.migrationsPath || "supabase/migrations"
178
+ module.migrationsPath || "supabase/migrations",
167
179
  );
168
180
 
169
181
  if (fs.existsSync(moduleMigrationsDir)) {
170
182
  migrationFiles = fs
171
183
  .readdirSync(moduleMigrationsDir)
172
184
  .filter((f) => f.endsWith(".sql"));
173
- console.log(chalk.gray(`DEBUG: Found ${migrationFiles.length} migration files from node_modules: ${migrationFiles.join(', ')}`));
185
+ console.log(
186
+ chalk.gray(
187
+ `DEBUG: Found ${migrationFiles.length} migration files from node_modules: ${migrationFiles.join(", ")}`,
188
+ ),
189
+ );
174
190
  } else {
175
- console.log(chalk.gray(`DEBUG: No migrations found in config or node_modules`));
191
+ console.log(
192
+ chalk.gray(`DEBUG: No migrations found in config or node_modules`),
193
+ );
176
194
  }
177
195
  }
178
196
 
@@ -180,12 +198,12 @@ export async function removeModule(moduleName: string, targetDir: string) {
180
198
  const modulePackagePath = path.join(
181
199
  targetDir,
182
200
  "node_modules",
183
- ...module.package.split("/")
201
+ ...module.package.split("/"),
184
202
  );
185
203
 
186
204
  const moduleMigrationsDownDir = path.join(
187
205
  modulePackagePath,
188
- module.migrationsDownPath || "supabase/migrations-down"
206
+ module.migrationsDownPath || "supabase/migrations-down",
189
207
  );
190
208
 
191
209
  let hasDownMigrations = false;
@@ -237,31 +255,45 @@ export async function removeModule(moduleName: string, targetDir: string) {
237
255
 
238
256
  for (const downFile of downFiles) {
239
257
  const downFilePath = path.join(moduleMigrationsDownDir, downFile);
240
-
258
+
241
259
  // Extraire le timestamp de la migration (14 premiers caractères)
242
- const migrationVersion = downFile.split('_')[0]; // Prend la partie avant le premier underscore
260
+ const migrationVersion = downFile.split("_")[0]; // Prend la partie avant le premier underscore
243
261
 
244
262
  try {
245
263
  console.log(chalk.gray(` Exécution de ${downFile}...`));
246
- execSync(`psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -f "${downFilePath}"`, {
247
- cwd: targetDir,
248
- stdio: "inherit",
249
- });
250
-
264
+ execSync(
265
+ `psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -f "${downFilePath}"`,
266
+ {
267
+ cwd: targetDir,
268
+ stdio: "inherit",
269
+ },
270
+ );
271
+
251
272
  // Supprimer l'entrée de supabase_migrations.schema_migrations
252
273
  try {
253
274
  const deleteQuery = `DELETE FROM supabase_migrations.schema_migrations WHERE version = '${migrationVersion}';`;
254
- const result = execSync(`psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -c "${deleteQuery}"`, {
255
- cwd: targetDir,
256
- encoding: 'utf-8',
257
- });
258
- console.log(chalk.gray(` ✓ Supprimé ${migrationVersion} de schema_migrations (${result.trim()})`));
275
+ const result = execSync(
276
+ `psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -c "${deleteQuery}"`,
277
+ {
278
+ cwd: targetDir,
279
+ encoding: "utf-8",
280
+ },
281
+ );
282
+ console.log(
283
+ chalk.gray(
284
+ ` ✓ Supprimé ${migrationVersion} de schema_migrations (${result.trim()})`,
285
+ ),
286
+ );
259
287
  } catch (error: any) {
260
- console.error(chalk.red(` ❌ Erreur lors de la suppression de ${migrationVersion}: ${error.message}`));
288
+ console.error(
289
+ chalk.red(
290
+ ` ❌ Erreur lors de la suppression de ${migrationVersion}: ${error.message}`,
291
+ ),
292
+ );
261
293
  }
262
-
294
+
263
295
  console.log(chalk.green(` ✓ ${downFile}`));
264
- } catch (error) {
296
+ } catch {
265
297
  console.error(chalk.red(` ❌ Erreur avec ${downFile}`));
266
298
  }
267
299
  }
@@ -270,7 +302,7 @@ export async function removeModule(moduleName: string, targetDir: string) {
270
302
 
271
303
  // D'abord supprimer les fichiers de migration du projet
272
304
  console.log(
273
- chalk.yellow("\n📋 Suppression des fichiers de migration...")
305
+ chalk.yellow("\n📋 Suppression des fichiers de migration..."),
274
306
  );
275
307
  for (const file of migrationFiles) {
276
308
  const filePath = path.join(projectMigrationsDir, file);
@@ -283,21 +315,21 @@ export async function removeModule(moduleName: string, targetDir: string) {
283
315
  try {
284
316
  execSync("supabase db reset", { cwd: targetDir, stdio: "inherit" });
285
317
  console.log(chalk.green("✓ Base de données réinitialisée"));
286
- } catch (error) {
318
+ } catch {
287
319
  console.error(chalk.red("❌ Erreur lors du reset"));
288
320
  }
289
321
  } else {
290
322
  console.log(
291
323
  chalk.gray(
292
- "\n⚠️ Données conservées en base. Nettoyez manuellement si nécessaire.\n"
293
- )
324
+ "\n⚠️ Données conservées en base. Nettoyez manuellement si nécessaire.\n",
325
+ ),
294
326
  );
295
327
  }
296
328
 
297
329
  // Supprimer les fichiers de migration du projet (si pas déjà fait)
298
330
  if (migrationAction !== "reset") {
299
331
  console.log(
300
- chalk.yellow("\n📋 Suppression des fichiers de migration...")
332
+ chalk.yellow("\n📋 Suppression des fichiers de migration..."),
301
333
  );
302
334
  for (const file of migrationFiles) {
303
335
  const filePath = path.join(projectMigrationsDir, file);
@@ -306,24 +338,33 @@ export async function removeModule(moduleName: string, targetDir: string) {
306
338
  console.log(chalk.gray(` ✓ ${file}`));
307
339
  }
308
340
  }
309
-
341
+
310
342
  // Supprimer les entrées de supabase_migrations.schema_migrations
311
343
  if (migrationFiles.length > 0) {
312
344
  console.log(chalk.yellow("\n🗄️ Nettoyage de schema_migrations..."));
313
-
345
+
314
346
  // Extraire uniquement les timestamps (14 premiers caractères) de chaque fichier de migration
315
- const versions = migrationFiles.map(f => {
316
- const timestamp = f.split('_')[0]; // Prend la partie avant le premier underscore
317
- return `'${timestamp}'`;
318
- }).join(', ');
347
+ const versions = migrationFiles
348
+ .map((f) => {
349
+ const timestamp = f.split("_")[0]; // Prend la partie avant le premier underscore
350
+ return `'${timestamp}'`;
351
+ })
352
+ .join(", ");
319
353
  const deleteQuery = `DELETE FROM supabase_migrations.schema_migrations WHERE version IN (${versions});`;
320
-
354
+
321
355
  try {
322
- const result = execSync(`psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -c "${deleteQuery}"`, {
323
- cwd: targetDir,
324
- encoding: 'utf-8',
325
- });
326
- console.log(chalk.gray(` ✓ Supprimé ${migrationFiles.length} entrées de schema_migrations`));
356
+ const result = execSync(
357
+ `psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -c "${deleteQuery}"`,
358
+ {
359
+ cwd: targetDir,
360
+ encoding: "utf-8",
361
+ },
362
+ );
363
+ console.log(
364
+ chalk.gray(
365
+ ` ✓ Supprimé ${migrationFiles.length} entrées de schema_migrations`,
366
+ ),
367
+ );
327
368
  console.log(chalk.gray(` ${result.trim()}`));
328
369
  } catch (error: any) {
329
370
  console.error(chalk.red(` ❌ Erreur: ${error.message}`));
@@ -336,16 +377,24 @@ export async function removeModule(moduleName: string, targetDir: string) {
336
377
  const modulesJsonPath = path.join(targetDir, ".lastbrain", "modules.json");
337
378
  if (fs.existsSync(modulesJsonPath)) {
338
379
  try {
339
- const modulesConfig = JSON.parse(fs.readFileSync(modulesJsonPath, "utf-8"));
340
- const moduleEntry = modulesConfig.modules.find((m: any) => m.package === module.package);
380
+ const modulesConfig = JSON.parse(
381
+ fs.readFileSync(modulesJsonPath, "utf-8"),
382
+ );
383
+ const moduleEntry = modulesConfig.modules.find(
384
+ (m: any) => m.package === module.package,
385
+ );
341
386
  if (moduleEntry) {
342
387
  moduleEntry.active = false;
343
388
  moduleEntry.migrations = [];
344
389
  }
345
390
  fs.writeFileSync(modulesJsonPath, JSON.stringify(modulesConfig, null, 2));
346
- console.log(chalk.gray("\n✓ Module marqué comme inactif dans modules.json"));
347
- } catch (error) {
348
- console.error(chalk.red("❌ Erreur lors de la mise à jour de modules.json"));
391
+ console.log(
392
+ chalk.gray("\n✓ Module marqué comme inactif dans modules.json"),
393
+ );
394
+ } catch {
395
+ console.error(
396
+ chalk.red("❌ Erreur lors de la mise à jour de modules.json"),
397
+ );
349
398
  }
350
399
  }
351
400
 
@@ -353,15 +402,25 @@ export async function removeModule(moduleName: string, targetDir: string) {
353
402
  console.log(chalk.yellow("\n🧹 Nettoyage des dépendances..."));
354
403
  try {
355
404
  execSync("pnpm install", { cwd: targetDir, stdio: "inherit" });
356
- } catch (error) {
405
+ } catch {
357
406
  console.error(chalk.red("❌ Erreur lors du nettoyage"));
358
407
  process.exit(1);
359
408
  }
360
409
 
361
410
  console.log(
362
- chalk.green(`\n✅ Module ${module.displayName} supprimé avec succès!\n`)
411
+ chalk.green(`\n✅ Module ${module.displayName} supprimé avec succès!\n`),
363
412
  );
413
+
414
+ // 7. Rebuilder les modules pour mettre à jour les fichiers générés
415
+ console.log(chalk.yellow("🔧 Mise à jour des modules..."));
416
+ try {
417
+ execSync("pnpm run build:modules", { cwd: targetDir, stdio: "inherit" });
418
+ console.log(chalk.green("✓ Modules mis à jour"));
419
+ } catch {
420
+ console.warn(chalk.yellow("⚠️ Erreur lors de la mise à jour des modules"));
421
+ }
422
+
364
423
  console.log(
365
- chalk.gray("Le serveur de développement redémarrera automatiquement.\n")
424
+ chalk.gray("Le serveur de développement redémarrera automatiquement.\n"),
366
425
  );
367
426
  }