@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
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/app-shell/(public)/page.tsx"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,UAAU,4CAQjC"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/app-shell/(public)/page.tsx"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,UAAU,4CAYjC"}
package/dist/index.d.ts CHANGED
@@ -4,8 +4,12 @@ export { signOut, signIn } from "./auth/authHelpers.js";
4
4
  export { RootLayout } from "./layouts/RootLayout.js";
5
5
  export { PublicLayout } from "./layouts/PublicLayout.js";
6
6
  export { AuthLayout } from "./layouts/AuthLayout.js";
7
+ export { AuthLayoutWithSidebar } from "./layouts/AuthLayoutWithSidebar.js";
7
8
  export { AdminLayout } from "./layouts/AdminLayout.js";
9
+ export { AdminLayoutWithSidebar } from "./layouts/AdminLayoutWithSidebar.js";
8
10
  export { getModuleConfigs } from "./modules/module-loader.js";
11
+ export { AppAside } from "@lastbrain/ui";
12
+ export type { AppAsideMenuItem, AppAsideMenuConfig } from "@lastbrain/ui";
9
13
  export { SimpleHomePage } from "./templates/SimpleHomePage.js";
10
14
  export { DocPage } from "./templates/DocPage.js";
11
15
  export { SimpleDocPage } from "./templates/SimpleDocPage.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,UAAU,EACV,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,UAAU,EACV,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAG1E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC"}
package/dist/index.js CHANGED
@@ -4,8 +4,12 @@ export { signOut, signIn } from "./auth/authHelpers.js";
4
4
  export { RootLayout } from "./layouts/RootLayout.js";
5
5
  export { PublicLayout } from "./layouts/PublicLayout.js";
6
6
  export { AuthLayout } from "./layouts/AuthLayout.js";
7
+ export { AuthLayoutWithSidebar } from "./layouts/AuthLayoutWithSidebar.js";
7
8
  export { AdminLayout } from "./layouts/AdminLayout.js";
9
+ export { AdminLayoutWithSidebar } from "./layouts/AdminLayoutWithSidebar.js";
8
10
  export { getModuleConfigs } from "./modules/module-loader.js";
11
+ // Components
12
+ export { AppAside } from "@lastbrain/ui";
9
13
  // Templates de pages (starter + docs)
10
14
  export { SimpleHomePage } from "./templates/SimpleHomePage.js";
11
15
  export { DocPage } from "./templates/DocPage.js";
@@ -0,0 +1,8 @@
1
+ interface AdminLayoutWithSidebarProps {
2
+ children: React.ReactNode;
3
+ menuConfig?: any;
4
+ className?: string;
5
+ }
6
+ export declare function AdminLayoutWithSidebar({ children, menuConfig, className, }: AdminLayoutWithSidebarProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=AdminLayoutWithSidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminLayoutWithSidebar.d.ts","sourceRoot":"","sources":["../../src/layouts/AdminLayoutWithSidebar.tsx"],"names":[],"mappings":"AAMA,UAAU,2BAA2B;IACnC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,UAAU,EACV,SAAc,GACf,EAAE,2BAA2B,2CAkB7B"}
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { AdminLayout } from "./AdminLayout.js";
4
+ import { AppAside } from "@lastbrain/ui";
5
+ import { useAuthSession } from "../auth/useAuthSession.js";
6
+ export function AdminLayoutWithSidebar({ children, menuConfig, className = "", }) {
7
+ const { isSuperAdmin } = useAuthSession();
8
+ return (_jsxs("div", { className: "flex min-h-screen", children: [menuConfig && (_jsx(AppAside, { menuConfig: menuConfig, isSuperAdmin: isSuperAdmin, className: className })), _jsx("div", { className: `flex-1 ${menuConfig ? "lg:ml-72" : ""}`, children: _jsx(AdminLayout, { children: children }) })] }));
9
+ }
@@ -0,0 +1,8 @@
1
+ interface AuthLayoutWithSidebarProps {
2
+ children: React.ReactNode;
3
+ menuConfig?: any;
4
+ className?: string;
5
+ }
6
+ export declare function AuthLayoutWithSidebar({ children, menuConfig, className, }: AuthLayoutWithSidebarProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=AuthLayoutWithSidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthLayoutWithSidebar.d.ts","sourceRoot":"","sources":["../../src/layouts/AuthLayoutWithSidebar.tsx"],"names":[],"mappings":"AAMA,UAAU,0BAA0B;IAClC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,UAAU,EACV,SAAc,GACf,EAAE,0BAA0B,2CAkB5B"}
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { AuthLayout } from "./AuthLayout.js";
4
+ import { AppAside } from "@lastbrain/ui";
5
+ import { useAuthSession } from "../auth/useAuthSession.js";
6
+ export function AuthLayoutWithSidebar({ children, menuConfig, className = "", }) {
7
+ const { isSuperAdmin } = useAuthSession();
8
+ return (_jsxs("div", { className: "flex min-h-screen", children: [menuConfig && (_jsx(AppAside, { menuConfig: menuConfig, isSuperAdmin: isSuperAdmin, className: className })), _jsx("div", { className: `flex-1 ${menuConfig ? "lg:ml-72" : ""}`, children: _jsx(AuthLayout, { children: children }) })] }));
9
+ }
@@ -1,4 +1,4 @@
1
- import { spawn, spawnSync } from "node:child_process";
1
+ import { spawn, spawnSync, } from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
@@ -229,7 +229,7 @@ async function main() {
229
229
  try {
230
230
  runSupabase("start");
231
231
  }
232
- catch (_error) {
232
+ catch {
233
233
  console.warn("⚠️ Supabase start had issues, continuing...");
234
234
  }
235
235
  console.log("🔄 Resetting database...");
@@ -14,12 +14,12 @@ const scriptsToEnsure = {
14
14
  "build:modules": "pnpm --filter @lastbrain/app module:build",
15
15
  "db:migrations:sync": "pnpm --filter @lastbrain/app db:migrations:sync",
16
16
  "db:init": "pnpm --filter @lastbrain/app db:init",
17
- "readme:create": "pnpm --filter @lastbrain/app readme:create"
17
+ "readme:create": "pnpm --filter @lastbrain/app readme:create",
18
18
  };
19
19
  const dependenciesToEnsure = {
20
20
  "@lastbrain/app": "workspace:*",
21
21
  "@lastbrain/core": "workspace:*",
22
- "@lastbrain/ui": "workspace:*"
22
+ "@lastbrain/ui": "workspace:*",
23
23
  };
24
24
  const gitignoreTemplate = path.join(projectRoot, "packages/app/src/templates/gitignore/.gitignore");
25
25
  const consumerGitignore = path.join(projectRoot, "apps/web/.gitignore");
@@ -30,7 +30,9 @@ function ensureDirectory(dir) {
30
30
  fs.mkdirSync(dir, { recursive: true });
31
31
  }
32
32
  function normalizeContent(data) {
33
- const trimmed = data.startsWith(GENERATED_HEADER) ? data.slice(GENERATED_HEADER.length) : data;
33
+ const trimmed = data.startsWith(GENERATED_HEADER)
34
+ ? data.slice(GENERATED_HEADER.length)
35
+ : data;
34
36
  const sanitized = trimmed.trimStart();
35
37
  return `${GENERATED_HEADER}\n${sanitized}`;
36
38
  }
@@ -48,13 +50,13 @@ function syncFile(src, dest) {
48
50
  fs.writeFileSync(dest, content);
49
51
  return dest;
50
52
  }
51
- function copyDirectory(srcDir, destDir) {
53
+ function _copyDirectory(srcDir, destDir) {
52
54
  const stats = fs.statSync(srcDir);
53
55
  if (stats.isDirectory()) {
54
56
  ensureDirectory(destDir);
55
57
  const entries = fs.readdirSync(srcDir, { withFileTypes: true });
56
58
  for (const entry of entries) {
57
- copyDirectory(path.join(srcDir, entry.name), path.join(destDir, entry.name));
59
+ _copyDirectory(path.join(srcDir, entry.name), path.join(destDir, entry.name));
58
60
  }
59
61
  }
60
62
  else if (stats.isFile()) {
@@ -86,7 +88,7 @@ function syncAppShell() {
86
88
  function cleanupStaleGroupFiles() {
87
89
  const staleFiles = [
88
90
  path.join(destAppShell, "(auth)", "page.tsx"),
89
- path.join(destAppShell, "(admin)", "page.tsx")
91
+ path.join(destAppShell, "(admin)", "page.tsx"),
90
92
  ];
91
93
  staleFiles.forEach((file) => {
92
94
  if (fs.existsSync(file)) {
@@ -95,7 +97,7 @@ function cleanupStaleGroupFiles() {
95
97
  });
96
98
  const staleDirs = [
97
99
  path.join(destAppShell, "(auth)", "dashboard"),
98
- path.join(destAppShell, "(admin)", "dashboard")
100
+ path.join(destAppShell, "(admin)", "dashboard"),
99
101
  ];
100
102
  staleDirs.forEach((dir) => {
101
103
  if (fs.existsSync(dir)) {
@@ -112,20 +114,27 @@ function syncPackageJson() {
112
114
  name: "web",
113
115
  private: true,
114
116
  version: "0.1.0",
115
- type: "module"
117
+ type: "module",
116
118
  };
117
- const pkg = fs.existsSync(webPackage) ? JSON.parse(fs.readFileSync(webPackage, "utf-8")) : defaultPkg;
119
+ const pkg = fs.existsSync(webPackage)
120
+ ? JSON.parse(fs.readFileSync(webPackage, "utf-8"))
121
+ : defaultPkg;
118
122
  pkg.scripts = mergeScripts(pkg.scripts ?? {}, scriptsToEnsure);
119
123
  pkg.dependencies = { ...(pkg.dependencies ?? {}), ...dependenciesToEnsure };
120
124
  fs.writeFileSync(webPackage, JSON.stringify(pkg, null, 2) + "\n");
121
- return { scripts: Object.keys(scriptsToEnsure), dependencies: Object.keys(dependenciesToEnsure) };
125
+ return {
126
+ scripts: Object.keys(scriptsToEnsure),
127
+ dependencies: Object.keys(dependenciesToEnsure),
128
+ };
122
129
  }
123
130
  function syncEnvExample() {
124
131
  if (!fs.existsSync(envTemplate)) {
125
132
  return null;
126
133
  }
127
134
  const shouldOverwrite = !fs.existsSync(consumerEnvExample) ||
128
- fs.readFileSync(consumerEnvExample, "utf-8").includes("GENERATED BY LASTBRAIN");
135
+ fs
136
+ .readFileSync(consumerEnvExample, "utf-8")
137
+ .includes("GENERATED BY LASTBRAIN");
129
138
  if (!shouldOverwrite) {
130
139
  return null;
131
140
  }
@@ -147,7 +156,9 @@ function syncGitignore() {
147
156
  return null;
148
157
  }
149
158
  const shouldOverwrite = !fs.existsSync(consumerGitignore) ||
150
- fs.readFileSync(consumerGitignore, "utf-8").includes("GENERATED BY LASTBRAIN");
159
+ fs
160
+ .readFileSync(consumerGitignore, "utf-8")
161
+ .includes("GENERATED BY LASTBRAIN");
151
162
  if (!shouldOverwrite) {
152
163
  return null;
153
164
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init-app.d.ts","sourceRoot":"","sources":["../../src/scripts/init-app.ts"],"names":[],"mappings":"AAWA,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBAwJpD"}
1
+ {"version":3,"file":"init-app.d.ts","sourceRoot":"","sources":["../../src/scripts/init-app.ts"],"names":[],"mappings":"AAWA,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBAwMpD"}
@@ -38,6 +38,12 @@ export async function initApp(options) {
38
38
  withAuth = selectedModules.includes("auth");
39
39
  console.log();
40
40
  }
41
+ else if (!interactive) {
42
+ // En mode non-interactif, installer auth et ai par défaut
43
+ selectedModules.push("auth", "ai");
44
+ withAuth = true;
45
+ console.log(chalk.blue("📦 Modules installés par défaut : Authentication, AI Generation\n"));
46
+ }
41
47
  // Créer le dossier s'il n'existe pas
42
48
  await fs.ensureDir(targetDir);
43
49
  // 1. Vérifier/créer package.json
@@ -58,7 +64,10 @@ export async function initApp(options) {
58
64
  // 8. Ajouter les scripts NPM
59
65
  await addScriptsToPackageJson(targetDir);
60
66
  // 9. Enregistrer les modules sélectionnés
61
- if (withAuth || selectedModules.length > 0) {
67
+ if (withAuth && !selectedModules.includes("auth")) {
68
+ selectedModules.push("auth");
69
+ }
70
+ if (selectedModules.length > 0) {
62
71
  await saveModulesConfig(targetDir, selectedModules, withAuth);
63
72
  }
64
73
  console.log(chalk.green("\n✅ Application LastBrain initialisée avec succès!\n"));
@@ -80,6 +89,14 @@ export async function initApp(options) {
80
89
  console.log(chalk.yellow("🔧 Génération des routes des modules...\n"));
81
90
  execSync("pnpm build:modules", { cwd: targetDir, stdio: "inherit" });
82
91
  console.log(chalk.green("\n✓ Routes des modules générées\n"));
92
+ console.log(chalk.yellow("🗄️ Initialisation de la base de données...\n"));
93
+ try {
94
+ execSync("pnpm db:init", { cwd: targetDir, stdio: "inherit" });
95
+ console.log(chalk.green("\n✓ Base de données initialisée\n"));
96
+ }
97
+ catch {
98
+ console.log(chalk.yellow("\n⚠️ Erreur d'initialisation de la DB (normal si Supabase pas configuré)\n"));
99
+ }
83
100
  // Détecter le port (par défaut 3000 pour Next.js)
84
101
  const port = 3000;
85
102
  const url = `http://127.0.0.1:${port}`;
@@ -92,24 +109,29 @@ export async function initApp(options) {
92
109
  console.log(chalk.white(" 4. Exécutez : pnpm db:init"));
93
110
  console.log(chalk.white(" 5. Rechargez la page\n"));
94
111
  // Ouvrir le navigateur
95
- const openCommand = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
112
+ const openCommand = process.platform === "darwin"
113
+ ? "open"
114
+ : process.platform === "win32"
115
+ ? "start"
116
+ : "xdg-open";
96
117
  setTimeout(() => {
97
118
  try {
98
119
  execSync(`${openCommand} ${url}`, { stdio: "ignore" });
99
120
  }
100
- catch (error) {
121
+ catch {
101
122
  // Ignorer les erreurs d'ouverture du navigateur
102
123
  }
103
124
  }, 2000);
104
125
  // Lancer pnpm dev
105
126
  execSync("pnpm dev", { cwd: targetDir, stdio: "inherit" });
106
127
  }
107
- catch (error) {
128
+ catch {
108
129
  console.error(chalk.red("\n❌ Erreur lors du lancement\n"));
109
130
  console.log(chalk.cyan("\nVous pouvez lancer manuellement avec :"));
110
131
  console.log(chalk.white(` cd ${relativePath}`));
111
132
  console.log(chalk.white(" pnpm install"));
112
133
  console.log(chalk.white(" pnpm build:modules"));
134
+ console.log(chalk.white(" pnpm db:init"));
113
135
  console.log(chalk.white(" pnpm dev\n"));
114
136
  }
115
137
  }
@@ -118,6 +140,8 @@ export async function initApp(options) {
118
140
  console.log(chalk.white(" 1. cd " + relativePath));
119
141
  console.log(chalk.white(" 2. pnpm install (installer les dépendances)"));
120
142
  console.log(chalk.white(" 3. pnpm build:modules (générer les routes des modules)"));
143
+ console.log(chalk.white(" 4. pnpm db:init (initialiser la base de données)"));
144
+ console.log(chalk.white(" 5. pnpm dev (lancer le serveur)"));
121
145
  console.log(chalk.white(" 4. pnpm db:init (initialiser Supabase)"));
122
146
  console.log(chalk.white(" 5. pnpm dev (démarrer le serveur)\n"));
123
147
  console.log(chalk.gray("Prérequis pour Supabase :"));
@@ -182,7 +206,7 @@ function getLastBrainVersions(targetDir) {
182
206
  };
183
207
  }
184
208
  }
185
- catch (error) {
209
+ catch {
186
210
  console.warn(chalk.yellow("⚠️ Impossible de lire les versions locales, utilisation de 'latest'"));
187
211
  }
188
212
  // Fallback: utiliser "latest"
@@ -214,7 +238,7 @@ async function addDependencies(targetDir, useHeroUI, withAuth, selectedModules =
214
238
  }
215
239
  // Ajouter les autres modules sélectionnés
216
240
  for (const moduleName of selectedModules) {
217
- const moduleInfo = AVAILABLE_MODULES.find(m => m.name === moduleName);
241
+ const moduleInfo = AVAILABLE_MODULES.find((m) => m.name === moduleName);
218
242
  if (moduleInfo && moduleInfo.package !== "@lastbrain/module-auth") {
219
243
  // Pour les autres modules, utiliser "latest" ou la version depuis le package
220
244
  requiredDeps[moduleInfo.package] = versions.app; // Utiliser la même version que app
@@ -435,9 +459,12 @@ export default function NotFound() {
435
459
  }
436
460
  // Créer les routes avec leurs layouts
437
461
  await createRoute(appDir, "admin", "admin", force);
462
+ await createRoute(appDir, "auth", "auth", force);
438
463
  await createRoute(appDir, "docs", "public", force);
439
464
  // Créer le composant AppHeader
440
465
  await createAppHeader(targetDir, force);
466
+ // Créer le composant AppAside
467
+ await createAppAside(targetDir, force);
441
468
  }
442
469
  async function createRoute(appDir, routeName, layoutType, force) {
443
470
  const routeDir = path.join(appDir, routeName);
@@ -445,11 +472,48 @@ async function createRoute(appDir, routeName, layoutType, force) {
445
472
  // Layout pour la route
446
473
  const layoutPath = path.join(routeDir, "layout.tsx");
447
474
  if (!fs.existsSync(layoutPath) || force) {
448
- const layoutComponent = layoutType.charAt(0).toUpperCase() + layoutType.slice(1) + "Layout";
449
- const layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
475
+ let layoutContent = "";
476
+ if (routeName === "admin") {
477
+ // Layout admin avec sidebar
478
+ layoutContent = `import { AdminLayoutWithSidebar } from "@lastbrain/app";
479
+ import { menuConfig } from "../../config/menu";
480
+
481
+ export default function AdminLayout({
482
+ children,
483
+ }: {
484
+ children: React.ReactNode;
485
+ }) {
486
+ return (
487
+ <AdminLayoutWithSidebar menuConfig={menuConfig}>
488
+ {children}
489
+ </AdminLayoutWithSidebar>
490
+ );
491
+ }`;
492
+ }
493
+ else if (routeName === "auth") {
494
+ // Layout auth avec sidebar
495
+ layoutContent = `import { AuthLayoutWithSidebar } from "@lastbrain/app";
496
+ import { menuConfig } from "../../config/menu";
497
+
498
+ export default function AuthLayout({
499
+ children,
500
+ }: {
501
+ children: React.ReactNode;
502
+ }) {
503
+ return (
504
+ <AuthLayoutWithSidebar menuConfig={menuConfig}>
505
+ {children}
506
+ </AuthLayoutWithSidebar>
507
+ );
508
+ }`;
509
+ }
510
+ else {
511
+ // Layout standard pour les autres routes
512
+ const layoutComponent = layoutType.charAt(0).toUpperCase() + layoutType.slice(1) + "Layout";
513
+ layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
450
514
 
451
- export default ${layoutComponent};
452
- `;
515
+ export default ${layoutComponent};`;
516
+ }
453
517
  await fs.writeFile(layoutPath, layoutContent);
454
518
  console.log(chalk.green(`✓ app/${routeName}/layout.tsx créé`));
455
519
  }
@@ -544,6 +608,41 @@ export function AppHeader() {
544
608
  console.log(chalk.gray(" components/AppHeader.tsx existe déjà (utilisez --force pour écraser)"));
545
609
  }
546
610
  }
611
+ async function createAppAside(targetDir, force) {
612
+ const componentsDir = path.join(targetDir, "components");
613
+ await fs.ensureDir(componentsDir);
614
+ const asidePath = path.join(componentsDir, "AppAside.tsx");
615
+ if (!fs.existsSync(asidePath) || force) {
616
+ const asideContent = `"use client";
617
+
618
+ import { AppAside as UIAppAside } from "@lastbrain/app";
619
+ import { useAuthSession } from "@lastbrain/app";
620
+ import { menuConfig } from "../config/menu";
621
+
622
+ interface AppAsideProps {
623
+ className?: string;
624
+ isVisible?: boolean;
625
+ }
626
+
627
+ export function AppAside({ className = "", isVisible = true }: AppAsideProps) {
628
+ const { isSuperAdmin } = useAuthSession();
629
+
630
+ return (
631
+ <UIAppAside
632
+ className={className}
633
+ menuConfig={menuConfig}
634
+ isSuperAdmin={isSuperAdmin}
635
+ isVisible={isVisible}
636
+ />
637
+ );
638
+ }`;
639
+ await fs.writeFile(asidePath, asideContent);
640
+ console.log(chalk.green("✓ components/AppAside.tsx créé"));
641
+ }
642
+ else {
643
+ console.log(chalk.gray(" components/AppAside.tsx existe déjà (utilisez --force pour écraser)"));
644
+ }
645
+ }
547
646
  async function createConfigFiles(targetDir, force, useHeroUI) {
548
647
  console.log(chalk.yellow("\n⚙️ Création des fichiers de configuration..."));
549
648
  // middleware.ts - Protection des routes /auth/* et /admin/*
@@ -916,7 +1015,9 @@ async function addScriptsToPackageJson(targetDir) {
916
1015
  build: "next build",
917
1016
  start: "next start",
918
1017
  lint: "next lint",
919
- lastbrain: targetIsInMonorepo ? "lastbrain" : "node node_modules/@lastbrain/app/dist/cli.js",
1018
+ lastbrain: targetIsInMonorepo
1019
+ ? "lastbrain"
1020
+ : "node node_modules/@lastbrain/app/dist/cli.js",
920
1021
  "build:modules": `${scriptsPrefix} module:build`,
921
1022
  "db:migrations:sync": `${scriptsPrefix} db:migrations:sync`,
922
1023
  "db:init": `${scriptsPrefix} db:init`,
@@ -932,7 +1033,8 @@ async function saveModulesConfig(targetDir, selectedModules, withAuth) {
932
1033
  const modules = [];
933
1034
  // Ajouter TOUS les modules disponibles
934
1035
  for (const availableModule of AVAILABLE_MODULES) {
935
- const isSelected = selectedModules.includes(availableModule.name) || (withAuth && availableModule.name === 'auth');
1036
+ const isSelected = selectedModules.includes(availableModule.name) ||
1037
+ (withAuth && availableModule.name === "auth");
936
1038
  // Vérifier si le module a des migrations
937
1039
  const modulePath = path.join(targetDir, "node_modules", ...availableModule.package.split("/"));
938
1040
  const migrationsDir = path.join(modulePath, "supabase", "migrations");
@@ -1 +1 @@
1
- {"version":3,"file":"module-add.d.ts","sourceRoot":"","sources":["../../src/scripts/module-add.ts"],"names":[],"mappings":"AAMA,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAGD,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,EAsB/C,CAAC;AAEF,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAsMpE"}
1
+ {"version":3,"file":"module-add.d.ts","sourceRoot":"","sources":["../../src/scripts/module-add.ts"],"names":[],"mappings":"AAMA,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAGD,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,EAqB/C,CAAC;AAEF,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAuOpE"}
@@ -58,7 +58,7 @@ export async function addModule(moduleName, targetDir) {
58
58
  try {
59
59
  execSync("pnpm install", { cwd: targetDir, stdio: "inherit" });
60
60
  }
61
- catch (error) {
61
+ catch {
62
62
  console.error(chalk.red("❌ Erreur lors de l'installation"));
63
63
  process.exit(1);
64
64
  }
@@ -116,17 +116,20 @@ export async function addModule(moduleName, targetDir) {
116
116
  execSync("supabase db reset", { cwd: targetDir, stdio: "inherit" });
117
117
  console.log(chalk.green("✓ Base de données réinitialisée"));
118
118
  }
119
- catch (error) {
119
+ catch {
120
120
  console.error(chalk.red("❌ Erreur lors du reset"));
121
121
  }
122
122
  }
123
123
  else if (migrationAction === "push") {
124
124
  console.log(chalk.yellow("\n⬆️ Application des nouvelles migrations..."));
125
125
  try {
126
- execSync("supabase migration up", { cwd: targetDir, stdio: "inherit" });
126
+ execSync("supabase migration up", {
127
+ cwd: targetDir,
128
+ stdio: "inherit",
129
+ });
127
130
  console.log(chalk.green("✓ Migrations appliquées"));
128
131
  }
129
- catch (error) {
132
+ catch {
130
133
  console.error(chalk.red("❌ Erreur lors de l'application des migrations"));
131
134
  }
132
135
  }
@@ -147,7 +150,7 @@ export async function addModule(moduleName, targetDir) {
147
150
  }
148
151
  // Initialiser tous les modules disponibles s'ils n'existent pas
149
152
  for (const availableModule of AVAILABLE_MODULES) {
150
- const exists = modulesConfig.modules.find(m => m.package === availableModule.package);
153
+ const exists = modulesConfig.modules.find((m) => m.package === availableModule.package);
151
154
  if (!exists) {
152
155
  modulesConfig.modules.push({
153
156
  package: availableModule.package,
@@ -174,5 +177,15 @@ export async function addModule(moduleName, targetDir) {
174
177
  }
175
178
  await fs.writeJson(modulesConfigPath, modulesConfig, { spaces: 2 });
176
179
  console.log(chalk.green(`\n✅ Module ${module.displayName} ajouté avec succès!\n`));
177
- console.log(chalk.gray("Le serveur de développement redémarrera automatiquement.\n"));
180
+ // 7. Générer automatiquement les routes du module
181
+ console.log(chalk.yellow("🔧 Génération des routes du module..."));
182
+ try {
183
+ execSync("pnpm build:modules", { cwd: targetDir, stdio: "inherit" });
184
+ console.log(chalk.green("✓ Routes du module générées"));
185
+ }
186
+ catch {
187
+ console.error(chalk.red("❌ Erreur lors de la génération des routes"));
188
+ console.error(chalk.gray("Vous pouvez les générer manuellement avec: pnpm build:modules"));
189
+ }
190
+ console.log(chalk.gray("\nLe serveur de développement redémarrera automatiquement.\n"));
178
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"AAseA,wBAAsB,cAAc,kBAanC"}
1
+ {"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"AA6wBA,wBAAsB,cAAc,kBA4CnC"}