@lastbrain/app 0.1.24 → 0.1.26

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 (87) hide show
  1. package/dist/__tests__/module-registry.test.d.ts +2 -0
  2. package/dist/__tests__/module-registry.test.d.ts.map +1 -0
  3. package/dist/__tests__/module-registry.test.js +64 -0
  4. package/dist/app-shell/(admin)/layout.d.ts +3 -2
  5. package/dist/app-shell/(admin)/layout.d.ts.map +1 -1
  6. package/dist/app-shell/(admin)/layout.js +1 -1
  7. package/dist/app-shell/(auth)/layout.d.ts +3 -2
  8. package/dist/app-shell/(auth)/layout.d.ts.map +1 -1
  9. package/dist/app-shell/(auth)/layout.js +1 -1
  10. package/dist/app-shell/(public)/page.d.ts.map +1 -1
  11. package/dist/cli.js +50 -0
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -0
  15. package/dist/layouts/AdminLayout.d.ts +3 -2
  16. package/dist/layouts/AdminLayout.d.ts.map +1 -1
  17. package/dist/layouts/AdminLayoutWithSidebar.d.ts +8 -0
  18. package/dist/layouts/AdminLayoutWithSidebar.d.ts.map +1 -0
  19. package/dist/layouts/AdminLayoutWithSidebar.js +9 -0
  20. package/dist/layouts/AppProviders.d.ts +3 -2
  21. package/dist/layouts/AppProviders.d.ts.map +1 -1
  22. package/dist/layouts/AuthLayout.d.ts +3 -2
  23. package/dist/layouts/AuthLayout.d.ts.map +1 -1
  24. package/dist/layouts/AuthLayoutWithSidebar.d.ts +8 -0
  25. package/dist/layouts/AuthLayoutWithSidebar.d.ts.map +1 -0
  26. package/dist/layouts/AuthLayoutWithSidebar.js +9 -0
  27. package/dist/layouts/PublicLayout.d.ts +3 -2
  28. package/dist/layouts/PublicLayout.d.ts.map +1 -1
  29. package/dist/layouts/RootLayout.d.ts +3 -2
  30. package/dist/layouts/RootLayout.d.ts.map +1 -1
  31. package/dist/scripts/db-init.js +2 -2
  32. package/dist/scripts/db-migrations-sync.js +5 -5
  33. package/dist/scripts/dev-sync.js +21 -10
  34. package/dist/scripts/init-app.d.ts.map +1 -1
  35. package/dist/scripts/init-app.js +126 -21
  36. package/dist/scripts/module-add.d.ts.map +1 -1
  37. package/dist/scripts/module-add.js +20 -7
  38. package/dist/scripts/module-build.d.ts.map +1 -1
  39. package/dist/scripts/module-build.js +285 -30
  40. package/dist/scripts/module-create.d.ts.map +1 -1
  41. package/dist/scripts/module-create.js +25 -15
  42. package/dist/scripts/module-remove.d.ts.map +1 -1
  43. package/dist/scripts/module-remove.js +24 -11
  44. package/dist/scripts/script-runner.d.ts +5 -0
  45. package/dist/scripts/script-runner.d.ts.map +1 -0
  46. package/dist/scripts/script-runner.js +25 -0
  47. package/dist/styles.css +1 -1
  48. package/dist/templates/DefaultDoc.js +1 -7
  49. package/dist/templates/DocPage.d.ts.map +1 -1
  50. package/dist/templates/DocPage.js +14 -14
  51. package/dist/templates/components/AppAside.d.ts +6 -0
  52. package/dist/templates/components/AppAside.d.ts.map +1 -0
  53. package/dist/templates/components/AppAside.js +9 -0
  54. package/dist/templates/layouts/admin-layout.d.ts +4 -0
  55. package/dist/templates/layouts/admin-layout.d.ts.map +1 -0
  56. package/dist/templates/layouts/admin-layout.js +6 -0
  57. package/dist/templates/layouts/auth-layout.d.ts +4 -0
  58. package/dist/templates/layouts/auth-layout.d.ts.map +1 -0
  59. package/dist/templates/layouts/auth-layout.js +6 -0
  60. package/package.json +2 -1
  61. package/src/__tests__/module-registry.test.ts +74 -0
  62. package/src/app-shell/(admin)/layout.tsx +5 -3
  63. package/src/app-shell/(auth)/layout.tsx +5 -3
  64. package/src/app-shell/(public)/page.tsx +6 -2
  65. package/src/auth/useAuthSession.ts +1 -1
  66. package/src/cli.ts +51 -1
  67. package/src/index.ts +6 -0
  68. package/src/layouts/AdminLayout.tsx +1 -3
  69. package/src/layouts/AdminLayoutWithSidebar.tsx +35 -0
  70. package/src/layouts/AppProviders.tsx +3 -5
  71. package/src/layouts/AuthLayout.tsx +1 -3
  72. package/src/layouts/AuthLayoutWithSidebar.tsx +35 -0
  73. package/src/layouts/PublicLayout.tsx +1 -3
  74. package/src/layouts/RootLayout.tsx +1 -2
  75. package/src/scripts/db-init.ts +13 -8
  76. package/src/scripts/db-migrations-sync.ts +4 -4
  77. package/src/scripts/dev-sync.ts +49 -18
  78. package/src/scripts/init-app.ts +246 -73
  79. package/src/scripts/module-add.ts +49 -23
  80. package/src/scripts/module-build.ts +393 -88
  81. package/src/scripts/module-create.ts +85 -49
  82. package/src/scripts/module-remove.ts +116 -57
  83. package/src/scripts/readme-build.ts +2 -2
  84. package/src/scripts/script-runner.ts +28 -0
  85. package/src/templates/AuthGuidePage.tsx +1 -1
  86. package/src/templates/DefaultDoc.tsx +7 -7
  87. package/src/templates/DocPage.tsx +74 -46
package/src/cli.ts CHANGED
@@ -23,7 +23,7 @@ program
23
23
  .option("--with-auth", "Inclure le module d'authentification")
24
24
  .option(
25
25
  "--no-interactive",
26
- "Mode non-interactif (skip la sélection des modules)"
26
+ "Mode non-interactif (skip la sélection des modules)",
27
27
  )
28
28
  .action(async (directory: string | undefined, options) => {
29
29
  try {
@@ -93,4 +93,54 @@ program
93
93
  }
94
94
  });
95
95
 
96
+ // Commandes de build et maintenance
97
+ program
98
+ .command("module:build")
99
+ .description("Build les configurations de modules")
100
+ .action(async () => {
101
+ try {
102
+ const { runModuleBuild } = await import("./scripts/module-build.js");
103
+ await runModuleBuild();
104
+ } catch (error) {
105
+ console.error("❌ Erreur lors du build des modules:", error);
106
+ process.exit(1);
107
+ }
108
+ });
109
+
110
+ program
111
+ .command("db:init")
112
+ .description("Initialise la base de données Supabase")
113
+ .action(async () => {
114
+ try {
115
+ await import("./scripts/db-init.js");
116
+ } catch (error) {
117
+ console.error("❌ Erreur lors de l'initialisation de la DB:", error);
118
+ process.exit(1);
119
+ }
120
+ });
121
+
122
+ program
123
+ .command("db:migrations:sync")
124
+ .description("Synchronise les migrations de modules")
125
+ .action(async () => {
126
+ try {
127
+ await import("./scripts/db-migrations-sync.js");
128
+ } catch (error) {
129
+ console.error("❌ Erreur lors de la sync des migrations:", error);
130
+ process.exit(1);
131
+ }
132
+ });
133
+
134
+ program
135
+ .command("readme:create")
136
+ .description("Génère le fichier README")
137
+ .action(async () => {
138
+ try {
139
+ await import("./scripts/readme-build.js");
140
+ } catch (error) {
141
+ console.error("❌ Erreur lors de la création du README:", error);
142
+ process.exit(1);
143
+ }
144
+ });
145
+
96
146
  program.parse();
package/src/index.ts CHANGED
@@ -9,8 +9,14 @@ export { signOut, signIn } from "./auth/authHelpers.js";
9
9
  export { RootLayout } from "./layouts/RootLayout.js";
10
10
  export { PublicLayout } from "./layouts/PublicLayout.js";
11
11
  export { AuthLayout } from "./layouts/AuthLayout.js";
12
+ export { AuthLayoutWithSidebar } from "./layouts/AuthLayoutWithSidebar.js";
12
13
  export { AdminLayout } from "./layouts/AdminLayout.js";
14
+ export { AdminLayoutWithSidebar } from "./layouts/AdminLayoutWithSidebar.js";
13
15
  export { getModuleConfigs } from "./modules/module-loader.js";
16
+
17
+ // Components
18
+ export { AppAside } from "@lastbrain/ui";
19
+ export type { AppAsideMenuItem, AppAsideMenuConfig } from "@lastbrain/ui";
14
20
  // Templates de pages (starter + docs)
15
21
 
16
22
  export { SimpleHomePage } from "./templates/SimpleHomePage.js";
@@ -1,7 +1,5 @@
1
1
  "use client";
2
2
 
3
- import type { PropsWithChildren } from "react";
4
-
5
- export function AdminLayout({ children }: PropsWithChildren<{}>) {
3
+ export function AdminLayout({ children }: { children: React.ReactNode }) {
6
4
  return <div className="pt-18 px-2 md:px-5">{children}</div>;
7
5
  }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import { AdminLayout } from "./AdminLayout.js";
4
+ import { AppAside } from "@lastbrain/ui";
5
+ import { useAuthSession } from "../auth/useAuthSession.js";
6
+
7
+ interface AdminLayoutWithSidebarProps {
8
+ children: React.ReactNode;
9
+ menuConfig?: any;
10
+ className?: string;
11
+ }
12
+
13
+ export function AdminLayoutWithSidebar({
14
+ children,
15
+ menuConfig,
16
+ className = "",
17
+ }: AdminLayoutWithSidebarProps) {
18
+ const { isSuperAdmin } = useAuthSession();
19
+
20
+ return (
21
+ <div className="flex min-h-screen">
22
+ {menuConfig && (
23
+ <AppAside
24
+ menuConfig={menuConfig}
25
+ isSuperAdmin={isSuperAdmin}
26
+ className={className}
27
+ />
28
+ )}
29
+ {/* Contenu principal avec marge pour la sidebar */}
30
+ <div className={`flex-1 ${menuConfig ? "lg:ml-72" : ""}`}>
31
+ <AdminLayout>{children}</AdminLayout>
32
+ </div>
33
+ </div>
34
+ );
35
+ }
@@ -1,12 +1,10 @@
1
1
  "use client";
2
2
 
3
- import type { PropsWithChildren } from "react";
4
3
  import { createContext, useContext, useMemo } from "react";
5
4
  import { getModuleConfigs } from "../modules/module-loader.js";
6
- import { Header, ToastProvider } from "@lastbrain/ui";
5
+ import { ToastProvider } from "@lastbrain/ui";
7
6
  import { useAuthSession } from "../auth/useAuthSession.js";
8
7
  import type { User } from "@supabase/supabase-js";
9
- import { useRouter } from "next/navigation.js";
10
8
 
11
9
  const ModuleContext = createContext(getModuleConfigs());
12
10
  const NotificationContext = createContext({ messages: [] as string[] });
@@ -32,14 +30,14 @@ export function useAuth() {
32
30
  return useContext(AuthContext);
33
31
  }
34
32
 
35
- export function AppProviders({ children }: PropsWithChildren<{}>) {
33
+ export function AppProviders({ children }: { children: React.ReactNode }) {
36
34
  const modules = useMemo(() => getModuleConfigs(), []);
37
35
  const notifications = useMemo(() => ({ messages: [] as string[] }), []);
38
36
  const { user, loading, isSuperAdmin } = useAuthSession();
39
37
  // const router = useRouter();
40
38
  const authValue = useMemo(
41
39
  () => ({ user, loading, isSuperAdmin }),
42
- [user, loading, isSuperAdmin]
40
+ [user, loading, isSuperAdmin],
43
41
  );
44
42
 
45
43
  // const handleLogout = async () => {
@@ -1,7 +1,5 @@
1
1
  "use client";
2
2
 
3
- import type { PropsWithChildren } from "react";
4
-
5
- export function AuthLayout({ children }: PropsWithChildren<{}>) {
3
+ export function AuthLayout({ children }: { children: React.ReactNode }) {
6
4
  return <div className="pt-18 px-2 md:px-5 ">{children}</div>;
7
5
  }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import { AuthLayout } from "./AuthLayout.js";
4
+ import { AppAside } from "@lastbrain/ui";
5
+ import { useAuthSession } from "../auth/useAuthSession.js";
6
+
7
+ interface AuthLayoutWithSidebarProps {
8
+ children: React.ReactNode;
9
+ menuConfig?: any;
10
+ className?: string;
11
+ }
12
+
13
+ export function AuthLayoutWithSidebar({
14
+ children,
15
+ menuConfig,
16
+ className = "",
17
+ }: AuthLayoutWithSidebarProps) {
18
+ const { isSuperAdmin } = useAuthSession();
19
+
20
+ return (
21
+ <div className="flex min-h-screen">
22
+ {menuConfig && (
23
+ <AppAside
24
+ menuConfig={menuConfig}
25
+ isSuperAdmin={isSuperAdmin}
26
+ className={className}
27
+ />
28
+ )}
29
+ {/* Contenu principal avec marge pour la sidebar */}
30
+ <div className={`flex-1 ${menuConfig ? "lg:ml-72" : ""}`}>
31
+ <AuthLayout>{children}</AuthLayout>
32
+ </div>
33
+ </div>
34
+ );
35
+ }
@@ -1,7 +1,5 @@
1
1
  "use client";
2
2
 
3
- import type { PropsWithChildren } from "react";
4
-
5
- export function PublicLayout({ children }: PropsWithChildren<{}>) {
3
+ export function PublicLayout({ children }: { children: React.ReactNode }) {
6
4
  return <section className=" px-4 ">{children}</section>;
7
5
  }
@@ -1,11 +1,10 @@
1
1
  "use client";
2
2
 
3
- import type { PropsWithChildren } from "react";
4
3
  import { ThemeProvider } from "next-themes";
5
4
  import { AppProviders } from "./AppProviders.js";
6
5
 
7
6
  // Note: L'app Next.js doit importer son propre globals.css dans son layout
8
- export function RootLayout({ children }: PropsWithChildren<{}>) {
7
+ export function RootLayout({ children }: { children: React.ReactNode }) {
9
8
  return (
10
9
  <html lang="fr" suppressHydrationWarning>
11
10
  <body className="min-h-screen">
@@ -1,4 +1,9 @@
1
- import { spawn, spawnSync, execSync, execFileSync } from "node:child_process";
1
+ import {
2
+ spawn,
3
+ spawnSync,
4
+ execSync as _execSync,
5
+ execFileSync as _execFileSync,
6
+ } from "node:child_process";
2
7
  import fs from "node:fs";
3
8
  import path from "node:path";
4
9
  import { fileURLToPath } from "node:url";
@@ -15,7 +20,7 @@ const packageAppDir = path
15
20
  .replace(/dist\/scripts$/, "src");
16
21
  const envExampleTemplate = path.join(
17
22
  packageAppDir,
18
- "templates/env.example/.env.example"
23
+ "templates/env.example/.env.example",
19
24
  );
20
25
 
21
26
  function ensureDirectory(dir: string) {
@@ -73,7 +78,7 @@ function runSupabase(...args: any[]): Buffer | null {
73
78
  // Si le processus s'est terminé avec un code de sortie non nul, propager l'erreur
74
79
  if (result.status !== 0) {
75
80
  const error: any = new Error(
76
- `Command failed with exit code ${result.status}`
81
+ `Command failed with exit code ${result.status}`,
77
82
  );
78
83
  error.status = result.status;
79
84
  throw error;
@@ -84,7 +89,7 @@ function runSupabase(...args: any[]): Buffer | null {
84
89
  }
85
90
 
86
91
  throw new Error(
87
- "Unable to locate Supabase CLI (install it globally or via pnpm)."
92
+ "Unable to locate Supabase CLI (install it globally or via pnpm).",
88
93
  );
89
94
  }
90
95
 
@@ -105,7 +110,7 @@ function parseEnvFile(filePath: string) {
105
110
  .map((line) => {
106
111
  const [key, ...value] = line.split("=");
107
112
  return [key, value.join("=")];
108
- })
113
+ }),
109
114
  ) as Record<string, string>;
110
115
  }
111
116
 
@@ -272,7 +277,7 @@ async function main() {
272
277
  stdio: "inherit",
273
278
  env: { ...process.env, PATH: enhancedPath },
274
279
  shell: true,
275
- }
280
+ },
276
281
  );
277
282
 
278
283
  if (migrationResult.error || migrationResult.status !== 0) {
@@ -282,7 +287,7 @@ async function main() {
282
287
  console.log("⚙️ Starting Supabase...");
283
288
  try {
284
289
  runSupabase("start");
285
- } catch (error) {
290
+ } catch (_error) {
286
291
  console.warn("⚠️ Supabase start had issues, continuing...");
287
292
  }
288
293
 
@@ -310,7 +315,7 @@ async function main() {
310
315
  console.log("ℹ️ Copied .env.example into .env.local as fallback.");
311
316
  }
312
317
  console.warn(
313
- "⚠️ Impossible de récupérer automatiquement les accès Supabase."
318
+ "⚠️ Impossible de récupérer automatiquement les accès Supabase.",
314
319
  );
315
320
  }
316
321
 
@@ -13,7 +13,7 @@ function ensureDirectory(dir: string) {
13
13
  fs.mkdirSync(dir, { recursive: true });
14
14
  }
15
15
 
16
- enum CopyStrategy {
16
+ enum _CopyStrategy {
17
17
  overwrite,
18
18
  skip,
19
19
  }
@@ -32,7 +32,7 @@ function copyMigration(
32
32
  moduleConfig: ModuleBuildConfig,
33
33
  migration: ModuleMigrationEntry,
34
34
  file: string,
35
- index: number
35
+ index: number,
36
36
  ) {
37
37
  const moduleDir = getModulePackageDir(moduleConfig.moduleName);
38
38
  const migrationsPath = migration.path ?? "supabase/migrations";
@@ -48,7 +48,7 @@ function copyMigration(
48
48
  const moduleSlug = moduleConfig.moduleName.replace("@lastbrain/", "module-");
49
49
  const prefix = String((migration.priority ?? 0) * 10 + index + 1).padStart(
50
50
  3,
51
- "0"
51
+ "0",
52
52
  );
53
53
  const fileName = `${prefix}_${moduleSlug}_${file}`;
54
54
  const targetFile = path.join(migrationsDir, fileName);
@@ -67,7 +67,7 @@ function syncModuleMigrations() {
67
67
 
68
68
  const moduleMigrationPath = path.join(
69
69
  getModulePackageDir(moduleConfig.moduleName),
70
- migrationBlock.path ?? "supabase/migrations"
70
+ migrationBlock.path ?? "supabase/migrations",
71
71
  );
72
72
  let files = migrationBlock.files;
73
73
  if (!files?.length && fs.existsSync(moduleMigrationPath)) {
@@ -17,18 +17,24 @@ const scriptsToEnsure = {
17
17
  "build:modules": "pnpm --filter @lastbrain/app module:build",
18
18
  "db:migrations:sync": "pnpm --filter @lastbrain/app db:migrations:sync",
19
19
  "db:init": "pnpm --filter @lastbrain/app db:init",
20
- "readme:create": "pnpm --filter @lastbrain/app readme:create"
20
+ "readme:create": "pnpm --filter @lastbrain/app readme:create",
21
21
  };
22
22
 
23
23
  const dependenciesToEnsure = {
24
24
  "@lastbrain/app": "workspace:*",
25
25
  "@lastbrain/core": "workspace:*",
26
- "@lastbrain/ui": "workspace:*"
26
+ "@lastbrain/ui": "workspace:*",
27
27
  };
28
28
 
29
- const gitignoreTemplate = path.join(projectRoot, "packages/app/src/templates/gitignore/.gitignore");
29
+ const gitignoreTemplate = path.join(
30
+ projectRoot,
31
+ "packages/app/src/templates/gitignore/.gitignore",
32
+ );
30
33
  const consumerGitignore = path.join(projectRoot, "apps/web/.gitignore");
31
- const envTemplate = path.join(projectRoot, "packages/app/src/templates/env.example/.env.example");
34
+ const envTemplate = path.join(
35
+ projectRoot,
36
+ "packages/app/src/templates/env.example/.env.example",
37
+ );
32
38
  const consumerEnvExample = path.join(projectRoot, "apps/web/.env.example");
33
39
  const consumerEnvLocal = path.join(projectRoot, "apps/web/.env.local");
34
40
 
@@ -37,7 +43,9 @@ function ensureDirectory(dir: string) {
37
43
  }
38
44
 
39
45
  function normalizeContent(data: string) {
40
- const trimmed = data.startsWith(GENERATED_HEADER) ? data.slice(GENERATED_HEADER.length) : data;
46
+ const trimmed = data.startsWith(GENERATED_HEADER)
47
+ ? data.slice(GENERATED_HEADER.length)
48
+ : data;
41
49
  const sanitized = trimmed.trimStart();
42
50
  return `${GENERATED_HEADER}\n${sanitized}`;
43
51
  }
@@ -64,7 +72,10 @@ function copyDirectory(srcDir: string, destDir: string) {
64
72
  ensureDirectory(destDir);
65
73
  const entries = fs.readdirSync(srcDir, { withFileTypes: true });
66
74
  for (const entry of entries) {
67
- copyDirectory(path.join(srcDir, entry.name), path.join(destDir, entry.name));
75
+ copyDirectory(
76
+ path.join(srcDir, entry.name),
77
+ path.join(destDir, entry.name),
78
+ );
68
79
  }
69
80
  } else if (stats.isFile()) {
70
81
  syncFile(srcDir, destDir);
@@ -98,7 +109,7 @@ function syncAppShell() {
98
109
  function cleanupStaleGroupFiles() {
99
110
  const staleFiles = [
100
111
  path.join(destAppShell, "(auth)", "page.tsx"),
101
- path.join(destAppShell, "(admin)", "page.tsx")
112
+ path.join(destAppShell, "(admin)", "page.tsx"),
102
113
  ];
103
114
 
104
115
  staleFiles.forEach((file) => {
@@ -109,7 +120,7 @@ function cleanupStaleGroupFiles() {
109
120
 
110
121
  const staleDirs = [
111
122
  path.join(destAppShell, "(auth)", "dashboard"),
112
- path.join(destAppShell, "(admin)", "dashboard")
123
+ path.join(destAppShell, "(admin)", "dashboard"),
113
124
  ];
114
125
 
115
126
  staleDirs.forEach((dir) => {
@@ -119,7 +130,10 @@ function cleanupStaleGroupFiles() {
119
130
  });
120
131
  }
121
132
 
122
- function mergeScripts(base: Record<string, string>, additions: Record<string, string>) {
133
+ function mergeScripts(
134
+ base: Record<string, string>,
135
+ additions: Record<string, string>,
136
+ ) {
123
137
  return { ...base, ...additions };
124
138
  }
125
139
 
@@ -129,15 +143,20 @@ function syncPackageJson() {
129
143
  name: "web",
130
144
  private: true,
131
145
  version: "0.1.0",
132
- type: "module"
146
+ type: "module",
133
147
  };
134
148
 
135
- const pkg = fs.existsSync(webPackage) ? JSON.parse(fs.readFileSync(webPackage, "utf-8")) : defaultPkg;
149
+ const pkg = fs.existsSync(webPackage)
150
+ ? JSON.parse(fs.readFileSync(webPackage, "utf-8"))
151
+ : defaultPkg;
136
152
  pkg.scripts = mergeScripts(pkg.scripts ?? {}, scriptsToEnsure);
137
153
  pkg.dependencies = { ...(pkg.dependencies ?? {}), ...dependenciesToEnsure };
138
154
 
139
155
  fs.writeFileSync(webPackage, JSON.stringify(pkg, null, 2) + "\n");
140
- return { scripts: Object.keys(scriptsToEnsure), dependencies: Object.keys(dependenciesToEnsure) };
156
+ return {
157
+ scripts: Object.keys(scriptsToEnsure),
158
+ dependencies: Object.keys(dependenciesToEnsure),
159
+ };
141
160
  }
142
161
 
143
162
  function syncEnvExample() {
@@ -147,7 +166,9 @@ function syncEnvExample() {
147
166
 
148
167
  const shouldOverwrite =
149
168
  !fs.existsSync(consumerEnvExample) ||
150
- fs.readFileSync(consumerEnvExample, "utf-8").includes("GENERATED BY LASTBRAIN");
169
+ fs
170
+ .readFileSync(consumerEnvExample, "utf-8")
171
+ .includes("GENERATED BY LASTBRAIN");
151
172
 
152
173
  if (!shouldOverwrite) {
153
174
  return null;
@@ -177,7 +198,9 @@ function syncGitignore() {
177
198
 
178
199
  const shouldOverwrite =
179
200
  !fs.existsSync(consumerGitignore) ||
180
- fs.readFileSync(consumerGitignore, "utf-8").includes("GENERATED BY LASTBRAIN");
201
+ fs
202
+ .readFileSync(consumerGitignore, "utf-8")
203
+ .includes("GENERATED BY LASTBRAIN");
181
204
 
182
205
  if (!shouldOverwrite) {
183
206
  return null;
@@ -199,19 +222,27 @@ function main() {
199
222
 
200
223
  console.log("✅ apps/web synced with @lastbrain/app");
201
224
  console.log(`Copied or updated files (${copiedFiles.length}):`);
202
- copiedFiles.forEach((file) => console.log(` • ${path.relative(projectRoot, file)}`));
225
+ copiedFiles.forEach((file) =>
226
+ console.log(` • ${path.relative(projectRoot, file)}`),
227
+ );
203
228
  console.log("Scripts ensured in apps/web/package.json:");
204
229
  changes.scripts.forEach((script) => console.log(` • ${script}`));
205
230
  console.log("Dependencies ensured in apps/web/package.json:");
206
231
  changes.dependencies.forEach((dep) => console.log(` • ${dep}`));
207
232
  if (gitignoreSynced) {
208
- console.log(`.gitignore ensured at ${path.relative(projectRoot, gitignoreSynced)}`);
233
+ console.log(
234
+ `.gitignore ensured at ${path.relative(projectRoot, gitignoreSynced)}`,
235
+ );
209
236
  }
210
237
  if (envExampleSynced) {
211
- console.log(`.env.example ensured at ${path.relative(projectRoot, envExampleSynced)}`);
238
+ console.log(
239
+ `.env.example ensured at ${path.relative(projectRoot, envExampleSynced)}`,
240
+ );
212
241
  }
213
242
  if (envLocalCreated) {
214
- console.log(`.env.local ensured at ${path.relative(projectRoot, envLocalCreated)}`);
243
+ console.log(
244
+ `.env.local ensured at ${path.relative(projectRoot, envLocalCreated)}`,
245
+ );
215
246
  }
216
247
  }
217
248