@lastbrain/app 0.1.44 → 0.1.46
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.d.ts +1 -0
- package/dist/scripts/init-app.d.ts.map +1 -1
- package/dist/scripts/init-app.js +61 -15
- package/dist/scripts/module-build.js +3 -1
- package/dist/scripts/module-create.d.ts.map +1 -1
- package/dist/templates/DefaultDoc.d.ts.map +1 -1
- package/dist/templates/DefaultDoc.js +1 -1
- package/package.json +1 -1
- package/src/auth/useAuthSession.ts +1 -1
- package/src/cli.ts +1 -1
- package/src/hooks/useNotifications.ts +7 -7
- package/src/layouts/AdminLayoutWithSidebar.tsx +3 -3
- package/src/layouts/AppProviders.tsx +1 -1
- package/src/layouts/AuthLayoutWithSidebar.tsx +3 -3
- package/src/layouts/PublicLayoutWithSidebar.tsx +3 -3
- package/src/scripts/db-init.ts +7 -7
- package/src/scripts/db-migrations-sync.ts +2 -2
- package/src/scripts/dev-sync.ts +8 -8
- package/src/scripts/init-app.ts +137 -71
- package/src/scripts/module-add.ts +26 -26
- package/src/scripts/module-build.ts +31 -31
- package/src/scripts/module-create.ts +52 -54
- package/src/scripts/module-delete.ts +13 -13
- package/src/scripts/module-list.ts +5 -5
- package/src/scripts/module-remove.ts +36 -36
- package/src/scripts/readme-build.ts +2 -2
- package/src/templates/DefaultDoc.tsx +28 -0
package/src/scripts/init-app.ts
CHANGED
|
@@ -19,6 +19,7 @@ interface InitAppOptions {
|
|
|
19
19
|
useHeroUI: boolean;
|
|
20
20
|
withAuth?: boolean;
|
|
21
21
|
interactive?: boolean;
|
|
22
|
+
isMonorepoProject?: boolean;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export async function initApp(options: InitAppOptions) {
|
|
@@ -29,7 +30,7 @@ export async function initApp(options: InitAppOptions) {
|
|
|
29
30
|
useHeroUI,
|
|
30
31
|
interactive = true,
|
|
31
32
|
} = options;
|
|
32
|
-
let { withAuth = false } = options;
|
|
33
|
+
let { withAuth = false, isMonorepoProject = false } = options;
|
|
33
34
|
|
|
34
35
|
console.log(chalk.blue("\n🚀 LastBrain App Init\n"));
|
|
35
36
|
console.log(chalk.gray(`📁 Dossier cible: ${targetDir}`));
|
|
@@ -55,20 +56,56 @@ export async function initApp(options: InitAppOptions) {
|
|
|
55
56
|
checked: false,
|
|
56
57
|
})),
|
|
57
58
|
},
|
|
59
|
+
{
|
|
60
|
+
type: "rawlist",
|
|
61
|
+
name: "projectType",
|
|
62
|
+
message: "Type de projet ?",
|
|
63
|
+
choices: [
|
|
64
|
+
{
|
|
65
|
+
name: "📦 Indépendant (créer une nouvelle BDD Supabase)",
|
|
66
|
+
value: "independent",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "🏢 Monorepo (utiliser la BDD existante)",
|
|
70
|
+
value: "monorepo",
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
default: "independent",
|
|
74
|
+
},
|
|
58
75
|
]);
|
|
59
76
|
|
|
60
77
|
selectedModules.push(...answers.modules);
|
|
61
78
|
withAuth = selectedModules.includes("auth");
|
|
79
|
+
isMonorepoProject = answers.projectType === "monorepo";
|
|
80
|
+
|
|
81
|
+
if (isMonorepoProject) {
|
|
82
|
+
console.log(
|
|
83
|
+
chalk.cyan("\n💡 Mode monorepo activé:"),
|
|
84
|
+
chalk.gray(
|
|
85
|
+
"Votre app utilisera la base de données centralisée du monorepo."
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
console.log(
|
|
89
|
+
chalk.gray(" Aucune configuration Supabase locale ne sera créée.\n")
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
console.log(
|
|
93
|
+
chalk.cyan("\n💡 Mode projet indépendant activé:"),
|
|
94
|
+
chalk.gray("Votre app aura sa propre instance Supabase locale.")
|
|
95
|
+
);
|
|
96
|
+
console.log(chalk.gray(" Configuration complète sera créée.\n"));
|
|
97
|
+
}
|
|
62
98
|
|
|
63
99
|
console.log();
|
|
64
100
|
} else if (!interactive) {
|
|
65
101
|
// En mode non-interactif, installer auth et ai par défaut
|
|
66
102
|
selectedModules.push("auth", "ai");
|
|
67
103
|
withAuth = true;
|
|
104
|
+
isMonorepoProject = false;
|
|
68
105
|
console.log(
|
|
69
106
|
chalk.blue(
|
|
70
|
-
"📦 Modules installés par défaut : Authentication, AI Generation\n"
|
|
71
|
-
)
|
|
107
|
+
"📦 Modules installés par défaut : Authentication, AI Generation\n"
|
|
108
|
+
)
|
|
72
109
|
);
|
|
73
110
|
}
|
|
74
111
|
|
|
@@ -93,10 +130,21 @@ export async function initApp(options: InitAppOptions) {
|
|
|
93
130
|
// 6. Créer .gitignore et .env.local.example
|
|
94
131
|
await createGitIgnore(targetDir, force);
|
|
95
132
|
await createEnvExample(targetDir, force);
|
|
96
|
-
await createEnvLocal(targetDir, force);
|
|
133
|
+
await createEnvLocal(targetDir, force, isMonorepoProject);
|
|
97
134
|
|
|
98
|
-
// 7. Créer la structure Supabase avec migrations
|
|
99
|
-
|
|
135
|
+
// 7. Créer la structure Supabase avec migrations (seulement pour projets indépendants)
|
|
136
|
+
if (!isMonorepoProject) {
|
|
137
|
+
console.log(
|
|
138
|
+
chalk.blue("🗄️ Création de la structure Supabase locale...\n")
|
|
139
|
+
);
|
|
140
|
+
await createSupabaseStructure(targetDir, force);
|
|
141
|
+
} else {
|
|
142
|
+
console.log(
|
|
143
|
+
chalk.yellow(
|
|
144
|
+
"⏭️ Projet monorepo détecté - pas de configuration Supabase locale requise\n"
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
100
148
|
|
|
101
149
|
// 8. Ajouter les scripts NPM
|
|
102
150
|
await addScriptsToPackageJson(targetDir);
|
|
@@ -111,7 +159,7 @@ export async function initApp(options: InitAppOptions) {
|
|
|
111
159
|
}
|
|
112
160
|
|
|
113
161
|
console.log(
|
|
114
|
-
chalk.green("\n✅ Application LastBrain initialisée avec succès!\n")
|
|
162
|
+
chalk.green("\n✅ Application LastBrain initialisée avec succès!\n")
|
|
115
163
|
);
|
|
116
164
|
|
|
117
165
|
const relativePath = path.relative(process.cwd(), targetDir);
|
|
@@ -139,7 +187,7 @@ export async function initApp(options: InitAppOptions) {
|
|
|
139
187
|
console.log(chalk.green("\n✓ Routes des modules générées\n"));
|
|
140
188
|
|
|
141
189
|
console.log(
|
|
142
|
-
chalk.yellow("📜 Synchronisation des migrations des modules...\n")
|
|
190
|
+
chalk.yellow("📜 Synchronisation des migrations des modules...\n")
|
|
143
191
|
);
|
|
144
192
|
try {
|
|
145
193
|
execSync("pnpm db:migrations:sync", {
|
|
@@ -149,7 +197,7 @@ export async function initApp(options: InitAppOptions) {
|
|
|
149
197
|
console.log(chalk.green("\n✓ Migrations synchronisées\n"));
|
|
150
198
|
} catch (error) {
|
|
151
199
|
console.log(
|
|
152
|
-
chalk.yellow("\n⚠️ Erreur de synchronisation des migrations\n")
|
|
200
|
+
chalk.yellow("\n⚠️ Erreur de synchronisation des migrations\n")
|
|
153
201
|
);
|
|
154
202
|
}
|
|
155
203
|
|
|
@@ -160,8 +208,8 @@ export async function initApp(options: InitAppOptions) {
|
|
|
160
208
|
} catch {
|
|
161
209
|
console.log(
|
|
162
210
|
chalk.yellow(
|
|
163
|
-
"\n⚠️ Erreur d'initialisation de la DB (normal si Supabase pas configuré)\n"
|
|
164
|
-
)
|
|
211
|
+
"\n⚠️ Erreur d'initialisation de la DB (normal si Supabase pas configuré)\n"
|
|
212
|
+
)
|
|
165
213
|
);
|
|
166
214
|
}
|
|
167
215
|
|
|
@@ -170,19 +218,19 @@ export async function initApp(options: InitAppOptions) {
|
|
|
170
218
|
const url = `http://127.0.0.1:${port}`;
|
|
171
219
|
|
|
172
220
|
console.log(
|
|
173
|
-
chalk.yellow("🚀 Lancement du serveur de développement...\n")
|
|
221
|
+
chalk.yellow("🚀 Lancement du serveur de développement...\n")
|
|
174
222
|
);
|
|
175
223
|
console.log(chalk.cyan(`📱 Ouvrez votre navigateur sur : ${url}\n`));
|
|
176
224
|
|
|
177
225
|
console.log(chalk.blue("\n📋 Prochaines étapes après le démarrage :"));
|
|
178
226
|
console.log(
|
|
179
|
-
chalk.white(" 1. Cliquez sur 'Get Started' sur la page d'accueil")
|
|
227
|
+
chalk.white(" 1. Cliquez sur 'Get Started' sur la page d'accueil")
|
|
180
228
|
);
|
|
181
229
|
console.log(chalk.white(" 2. Lancez Docker Desktop"));
|
|
182
230
|
console.log(
|
|
183
231
|
chalk.white(
|
|
184
|
-
" 3. Installez Supabase CLI si nécessaire : brew install supabase/tap/supabase"
|
|
185
|
-
)
|
|
232
|
+
" 3. Installez Supabase CLI si nécessaire : brew install supabase/tap/supabase"
|
|
233
|
+
)
|
|
186
234
|
);
|
|
187
235
|
console.log(chalk.white(" 4. Exécutez : pnpm db:init"));
|
|
188
236
|
console.log(chalk.white(" 5. Rechargez la page\n"));
|
|
@@ -219,20 +267,20 @@ export async function initApp(options: InitAppOptions) {
|
|
|
219
267
|
console.log(chalk.white(" 1. cd " + relativePath));
|
|
220
268
|
console.log(chalk.white(" 2. pnpm install (installer les dépendances)"));
|
|
221
269
|
console.log(
|
|
222
|
-
chalk.white(" 3. pnpm build:modules (générer les routes des modules)")
|
|
270
|
+
chalk.white(" 3. pnpm build:modules (générer les routes des modules)")
|
|
223
271
|
);
|
|
224
272
|
console.log(
|
|
225
|
-
chalk.white(" 4. pnpm db:migrations:sync (synchroniser les migrations)")
|
|
273
|
+
chalk.white(" 4. pnpm db:migrations:sync (synchroniser les migrations)")
|
|
226
274
|
);
|
|
227
275
|
console.log(
|
|
228
|
-
chalk.white(" 5. pnpm db:init (initialiser la base de données)")
|
|
276
|
+
chalk.white(" 5. pnpm db:init (initialiser la base de données)")
|
|
229
277
|
);
|
|
230
278
|
console.log(chalk.white(" 6. pnpm dev (lancer le serveur)\n"));
|
|
231
279
|
|
|
232
280
|
console.log(chalk.gray("Prérequis pour Supabase :"));
|
|
233
281
|
console.log(chalk.white(" - Docker Desktop installé et lancé"));
|
|
234
282
|
console.log(
|
|
235
|
-
chalk.white(" - Supabase CLI : brew install supabase/tap/supabase\n")
|
|
283
|
+
chalk.white(" - Supabase CLI : brew install supabase/tap/supabase\n")
|
|
236
284
|
);
|
|
237
285
|
|
|
238
286
|
// Afficher la commande cd pour faciliter la copie
|
|
@@ -276,7 +324,7 @@ function getLastBrainVersions(targetDir: string): {
|
|
|
276
324
|
} {
|
|
277
325
|
const targetIsInMonorepo =
|
|
278
326
|
fs.existsSync(
|
|
279
|
-
path.join(targetDir, "../../../packages/core/package.json")
|
|
327
|
+
path.join(targetDir, "../../../packages/core/package.json")
|
|
280
328
|
) ||
|
|
281
329
|
fs.existsSync(path.join(targetDir, "../../packages/core/package.json"));
|
|
282
330
|
|
|
@@ -304,11 +352,11 @@ function getLastBrainVersions(targetDir: string): {
|
|
|
304
352
|
const monorepoRoot = path.join(__dirname, "../../../../");
|
|
305
353
|
const moduleAuthPkgPath = path.join(
|
|
306
354
|
monorepoRoot,
|
|
307
|
-
"packages/module-auth/package.json"
|
|
355
|
+
"packages/module-auth/package.json"
|
|
308
356
|
);
|
|
309
357
|
const moduleAiPkgPath = path.join(
|
|
310
358
|
monorepoRoot,
|
|
311
|
-
"packages/module-ai/package.json"
|
|
359
|
+
"packages/module-ai/package.json"
|
|
312
360
|
);
|
|
313
361
|
const corePkgPath = path.join(monorepoRoot, "packages/core/package.json");
|
|
314
362
|
const uiPkgPath = path.join(monorepoRoot, "packages/ui/package.json");
|
|
@@ -321,7 +369,7 @@ function getLastBrainVersions(targetDir: string): {
|
|
|
321
369
|
// Lire les vraies versions depuis les package.json du monorepo
|
|
322
370
|
if (fs.existsSync(moduleAuthPkgPath)) {
|
|
323
371
|
const moduleAuthPkg = JSON.parse(
|
|
324
|
-
fs.readFileSync(moduleAuthPkgPath, "utf-8")
|
|
372
|
+
fs.readFileSync(moduleAuthPkgPath, "utf-8")
|
|
325
373
|
);
|
|
326
374
|
moduleAuthVersion = `^${moduleAuthPkg.version}`;
|
|
327
375
|
} else {
|
|
@@ -331,7 +379,7 @@ function getLastBrainVersions(targetDir: string): {
|
|
|
331
379
|
|
|
332
380
|
if (fs.existsSync(moduleAiPkgPath)) {
|
|
333
381
|
const moduleAiPkg = JSON.parse(
|
|
334
|
-
fs.readFileSync(moduleAiPkgPath, "utf-8")
|
|
382
|
+
fs.readFileSync(moduleAiPkgPath, "utf-8")
|
|
335
383
|
);
|
|
336
384
|
moduleAiVersion = `^${moduleAiPkg.version}`;
|
|
337
385
|
} else {
|
|
@@ -360,8 +408,8 @@ function getLastBrainVersions(targetDir: string): {
|
|
|
360
408
|
} catch (error) {
|
|
361
409
|
console.warn(
|
|
362
410
|
chalk.yellow(
|
|
363
|
-
`⚠️ Impossible de lire les versions locales (${error}), utilisation de 'latest'
|
|
364
|
-
)
|
|
411
|
+
`⚠️ Impossible de lire les versions locales (${error}), utilisation de 'latest'`
|
|
412
|
+
)
|
|
365
413
|
);
|
|
366
414
|
}
|
|
367
415
|
|
|
@@ -379,7 +427,7 @@ async function addDependencies(
|
|
|
379
427
|
targetDir: string,
|
|
380
428
|
useHeroUI: boolean,
|
|
381
429
|
withAuth: boolean,
|
|
382
|
-
selectedModules: string[] = []
|
|
430
|
+
selectedModules: string[] = []
|
|
383
431
|
) {
|
|
384
432
|
const pkgPath = path.join(targetDir, "package.json");
|
|
385
433
|
const pkg = await fs.readJson(pkgPath);
|
|
@@ -490,7 +538,7 @@ async function createNextStructure(
|
|
|
490
538
|
targetDir: string,
|
|
491
539
|
force: boolean,
|
|
492
540
|
useHeroUI: boolean,
|
|
493
|
-
withAuth: boolean
|
|
541
|
+
withAuth: boolean
|
|
494
542
|
) {
|
|
495
543
|
console.log(chalk.yellow("\n📁 Création de la structure Next.js..."));
|
|
496
544
|
|
|
@@ -550,9 +598,7 @@ export default function RootLayout({ children }: PropsWithChildren<{}>) {
|
|
|
550
598
|
console.log(chalk.green("✓ app/layout.tsx créé"));
|
|
551
599
|
} else {
|
|
552
600
|
console.log(
|
|
553
|
-
chalk.gray(
|
|
554
|
-
" app/layout.tsx existe déjà (utilisez --force pour écraser)",
|
|
555
|
-
),
|
|
601
|
+
chalk.gray(" app/layout.tsx existe déjà (utilisez --force pour écraser)")
|
|
556
602
|
);
|
|
557
603
|
}
|
|
558
604
|
|
|
@@ -646,7 +692,7 @@ export default function NotFound() {
|
|
|
646
692
|
async function createClientLayout(
|
|
647
693
|
targetDir: string,
|
|
648
694
|
force: boolean,
|
|
649
|
-
useHeroUI: boolean
|
|
695
|
+
useHeroUI: boolean
|
|
650
696
|
) {
|
|
651
697
|
const componentsDir = path.join(targetDir, "components");
|
|
652
698
|
await fs.ensureDir(componentsDir);
|
|
@@ -723,8 +769,8 @@ export function ClientLayout({ children }: { children: ReactNode }) {
|
|
|
723
769
|
} else {
|
|
724
770
|
console.log(
|
|
725
771
|
chalk.gray(
|
|
726
|
-
" components/ClientLayout.tsx existe déjà (utilisez --force pour écraser)"
|
|
727
|
-
)
|
|
772
|
+
" components/ClientLayout.tsx existe déjà (utilisez --force pour écraser)"
|
|
773
|
+
)
|
|
728
774
|
);
|
|
729
775
|
}
|
|
730
776
|
}
|
|
@@ -733,7 +779,7 @@ async function createRoute(
|
|
|
733
779
|
appDir: string,
|
|
734
780
|
routeName: string,
|
|
735
781
|
layoutType: string,
|
|
736
|
-
force: boolean
|
|
782
|
+
force: boolean
|
|
737
783
|
) {
|
|
738
784
|
const routeDir = path.join(appDir, routeName);
|
|
739
785
|
await fs.ensureDir(routeDir);
|
|
@@ -780,9 +826,8 @@ export default function AuthLayout({
|
|
|
780
826
|
const layoutComponent =
|
|
781
827
|
layoutType.charAt(0).toUpperCase() + layoutType.slice(1) + "Layout";
|
|
782
828
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
|
|
829
|
+
// Layout docs avec footer
|
|
830
|
+
layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
|
|
786
831
|
import { footerConfig } from "../../config/footer";
|
|
787
832
|
|
|
788
833
|
export default function DocsLayout({
|
|
@@ -792,11 +837,6 @@ export default function DocsLayout({
|
|
|
792
837
|
}) {
|
|
793
838
|
return <${layoutComponent} footerConfig={footerConfig}>{children}</${layoutComponent}>;
|
|
794
839
|
}`;
|
|
795
|
-
} else {
|
|
796
|
-
layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
|
|
797
|
-
|
|
798
|
-
export default ${layoutComponent};`;
|
|
799
|
-
}
|
|
800
840
|
}
|
|
801
841
|
|
|
802
842
|
await fs.writeFile(layoutPath, layoutContent);
|
|
@@ -893,6 +933,7 @@ export function AppHeader() {
|
|
|
893
933
|
user={user}
|
|
894
934
|
onLogout={handleLogout}
|
|
895
935
|
menuConfig={menuConfig}
|
|
936
|
+
accountMenu={menuConfig.account}
|
|
896
937
|
brandName="LastBrain App"
|
|
897
938
|
brandHref="/"
|
|
898
939
|
isSuperAdmin={isSuperAdmin}
|
|
@@ -911,8 +952,8 @@ export function AppHeader() {
|
|
|
911
952
|
} else {
|
|
912
953
|
console.log(
|
|
913
954
|
chalk.gray(
|
|
914
|
-
" components/AppHeader.tsx existe déjà (utilisez --force pour écraser)"
|
|
915
|
-
)
|
|
955
|
+
" components/AppHeader.tsx existe déjà (utilisez --force pour écraser)"
|
|
956
|
+
)
|
|
916
957
|
);
|
|
917
958
|
}
|
|
918
959
|
}
|
|
@@ -951,8 +992,8 @@ export function AppAside({ className = "", isVisible = true }: AppAsideProps) {
|
|
|
951
992
|
} else {
|
|
952
993
|
console.log(
|
|
953
994
|
chalk.gray(
|
|
954
|
-
" components/AppAside.tsx existe déjà (utilisez --force pour écraser)"
|
|
955
|
-
)
|
|
995
|
+
" components/AppAside.tsx existe déjà (utilisez --force pour écraser)"
|
|
996
|
+
)
|
|
956
997
|
);
|
|
957
998
|
}
|
|
958
999
|
}
|
|
@@ -981,8 +1022,8 @@ export function AppProviders({ children }: { children: ReactNode }) {
|
|
|
981
1022
|
} else {
|
|
982
1023
|
console.log(
|
|
983
1024
|
chalk.gray(
|
|
984
|
-
" components/AppProviders.tsx existe déjà (utilisez --force pour écraser)"
|
|
985
|
-
)
|
|
1025
|
+
" components/AppProviders.tsx existe déjà (utilisez --force pour écraser)"
|
|
1026
|
+
)
|
|
986
1027
|
);
|
|
987
1028
|
}
|
|
988
1029
|
}
|
|
@@ -991,7 +1032,7 @@ async function createConfigFiles(
|
|
|
991
1032
|
targetDir: string,
|
|
992
1033
|
force: boolean,
|
|
993
1034
|
useHeroUI: boolean,
|
|
994
|
-
projectName?: string
|
|
1035
|
+
projectName?: string
|
|
995
1036
|
) {
|
|
996
1037
|
console.log(chalk.yellow("\n⚙️ Création des fichiers de configuration..."));
|
|
997
1038
|
|
|
@@ -1014,6 +1055,11 @@ export async function middleware(request: NextRequest) {
|
|
|
1014
1055
|
"/callback",
|
|
1015
1056
|
];
|
|
1016
1057
|
|
|
1058
|
+
if(process.env.MAINTENANCE_MODE === "true" && !pathname.startsWith("/maintenance")) {
|
|
1059
|
+
const redirectUrl = new URL("/maintenance", request.url);
|
|
1060
|
+
return NextResponse.redirect(redirectUrl);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1017
1063
|
const isPublicAuthPage = publicAuthPages.some((page) =>
|
|
1018
1064
|
pathname.startsWith(page)
|
|
1019
1065
|
);
|
|
@@ -1131,8 +1177,8 @@ export const config = {
|
|
|
1131
1177
|
await fs.writeFile(middlewarePath, middleware);
|
|
1132
1178
|
console.log(
|
|
1133
1179
|
chalk.green(
|
|
1134
|
-
"✓ middleware.ts créé (protection /auth/*, /admin/* et /api/admin/*)"
|
|
1135
|
-
)
|
|
1180
|
+
"✓ middleware.ts créé (protection /auth/*, /admin/* et /api/admin/*)"
|
|
1181
|
+
)
|
|
1136
1182
|
);
|
|
1137
1183
|
}
|
|
1138
1184
|
|
|
@@ -1418,7 +1464,7 @@ async function createGitIgnore(targetDir: string, force: boolean) {
|
|
|
1418
1464
|
// Copier le fichier .gitignore depuis le template
|
|
1419
1465
|
const templateGitignorePath = path.join(
|
|
1420
1466
|
__dirname,
|
|
1421
|
-
"../templates/gitignore/.gitignore"
|
|
1467
|
+
"../templates/gitignore/.gitignore"
|
|
1422
1468
|
);
|
|
1423
1469
|
|
|
1424
1470
|
if (fs.existsSync(templateGitignorePath)) {
|
|
@@ -1516,13 +1562,31 @@ SUPABASE_SERVICE_ROLE_KEY=YOUR_LOCAL_SERVICE_ROLE_KEY
|
|
|
1516
1562
|
}
|
|
1517
1563
|
}
|
|
1518
1564
|
|
|
1519
|
-
async function createEnvLocal(
|
|
1565
|
+
async function createEnvLocal(
|
|
1566
|
+
targetDir: string,
|
|
1567
|
+
force: boolean,
|
|
1568
|
+
isMonorepoProject: boolean = false
|
|
1569
|
+
) {
|
|
1520
1570
|
const envLocalPath = path.join(targetDir, ".env.local");
|
|
1521
1571
|
|
|
1522
1572
|
if (!fs.existsSync(envLocalPath) || force) {
|
|
1523
1573
|
console.log(chalk.yellow("\n🔐 Création de .env.local..."));
|
|
1524
1574
|
|
|
1525
|
-
|
|
1575
|
+
let envContent: string;
|
|
1576
|
+
|
|
1577
|
+
if (isMonorepoProject) {
|
|
1578
|
+
// Pour les projets monorepo, utiliser les variables du monorepo
|
|
1579
|
+
envContent = `# Supabase Configuration (Monorepo - Centralisé)
|
|
1580
|
+
# Les variables Supabase sont gérées au niveau du monorepo
|
|
1581
|
+
|
|
1582
|
+
# OpenAI Configuration (clé factice pour éviter les erreurs de build)
|
|
1583
|
+
OPENAI_API_KEY=sk-fake-openai-key-for-development-replace-with-real-key
|
|
1584
|
+
|
|
1585
|
+
# Note: Les variables Supabase sont fournies par le monorepo parent
|
|
1586
|
+
`;
|
|
1587
|
+
} else {
|
|
1588
|
+
// Pour les projets indépendants
|
|
1589
|
+
envContent = `# Supabase Configuration
|
|
1526
1590
|
# Valeurs par défaut pour le développement local
|
|
1527
1591
|
|
|
1528
1592
|
# Supabase Local (par défaut)
|
|
@@ -1533,6 +1597,8 @@ SUPABASE_SERVICE_ROLE_KEY=eyJhbGc...
|
|
|
1533
1597
|
# OpenAI Configuration (clé factice pour éviter les erreurs de build)
|
|
1534
1598
|
OPENAI_API_KEY=sk-fake-openai-key-for-development-replace-with-real-key
|
|
1535
1599
|
`;
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1536
1602
|
await fs.writeFile(envLocalPath, envContent);
|
|
1537
1603
|
console.log(chalk.green("✓ .env.local créé"));
|
|
1538
1604
|
}
|
|
@@ -1548,11 +1614,11 @@ async function createSupabaseStructure(targetDir: string, force: boolean) {
|
|
|
1548
1614
|
// Copier le fichier de migration initial depuis le template
|
|
1549
1615
|
const templateMigrationPath = path.join(
|
|
1550
1616
|
__dirname,
|
|
1551
|
-
"../templates/migrations/20201010100000_app_base.sql"
|
|
1617
|
+
"../templates/migrations/20201010100000_app_base.sql"
|
|
1552
1618
|
);
|
|
1553
1619
|
const migrationDestPath = path.join(
|
|
1554
1620
|
migrationsDir,
|
|
1555
|
-
"20201010100000_app_base.sql"
|
|
1621
|
+
"20201010100000_app_base.sql"
|
|
1556
1622
|
);
|
|
1557
1623
|
|
|
1558
1624
|
if (!fs.existsSync(migrationDestPath) || force) {
|
|
@@ -1560,35 +1626,35 @@ async function createSupabaseStructure(targetDir: string, force: boolean) {
|
|
|
1560
1626
|
if (fs.existsSync(templateMigrationPath)) {
|
|
1561
1627
|
await fs.copy(templateMigrationPath, migrationDestPath);
|
|
1562
1628
|
console.log(
|
|
1563
|
-
chalk.green("✓ supabase/migrations/20201010100000_app_base.sql créé")
|
|
1629
|
+
chalk.green("✓ supabase/migrations/20201010100000_app_base.sql créé")
|
|
1564
1630
|
);
|
|
1565
1631
|
} else {
|
|
1566
1632
|
console.log(
|
|
1567
1633
|
chalk.yellow(
|
|
1568
|
-
"⚠ Template de migration introuvable, création d'un fichier vide"
|
|
1569
|
-
)
|
|
1634
|
+
"⚠ Template de migration introuvable, création d'un fichier vide"
|
|
1635
|
+
)
|
|
1570
1636
|
);
|
|
1571
1637
|
await fs.writeFile(
|
|
1572
1638
|
migrationDestPath,
|
|
1573
|
-
"-- Initial migration\n-- Add your database schema here\n"
|
|
1639
|
+
"-- Initial migration\n-- Add your database schema here\n"
|
|
1574
1640
|
);
|
|
1575
1641
|
console.log(
|
|
1576
1642
|
chalk.green(
|
|
1577
|
-
"✓ supabase/migrations/20201010100000_app_base.sql créé (vide)"
|
|
1578
|
-
)
|
|
1643
|
+
"✓ supabase/migrations/20201010100000_app_base.sql créé (vide)"
|
|
1644
|
+
)
|
|
1579
1645
|
);
|
|
1580
1646
|
}
|
|
1581
1647
|
} catch (error) {
|
|
1582
1648
|
console.error(
|
|
1583
1649
|
chalk.red("✗ Erreur lors de la création de la migration:"),
|
|
1584
|
-
error
|
|
1650
|
+
error
|
|
1585
1651
|
);
|
|
1586
1652
|
}
|
|
1587
1653
|
} else {
|
|
1588
1654
|
console.log(
|
|
1589
1655
|
chalk.gray(
|
|
1590
|
-
" supabase/migrations/20201010100000_app_base.sql existe déjà"
|
|
1591
|
-
)
|
|
1656
|
+
" supabase/migrations/20201010100000_app_base.sql existe déjà"
|
|
1657
|
+
)
|
|
1592
1658
|
);
|
|
1593
1659
|
}
|
|
1594
1660
|
}
|
|
@@ -1602,7 +1668,7 @@ async function addScriptsToPackageJson(targetDir: string) {
|
|
|
1602
1668
|
// Détecter si le projet cible est dans un workspace
|
|
1603
1669
|
const targetIsInMonorepo =
|
|
1604
1670
|
fs.existsSync(
|
|
1605
|
-
path.join(targetDir, "../../../packages/core/package.json")
|
|
1671
|
+
path.join(targetDir, "../../../packages/core/package.json")
|
|
1606
1672
|
) ||
|
|
1607
1673
|
fs.existsSync(path.join(targetDir, "../../packages/core/package.json"));
|
|
1608
1674
|
|
|
@@ -1639,7 +1705,7 @@ async function addScriptsToPackageJson(targetDir: string) {
|
|
|
1639
1705
|
async function saveModulesConfig(
|
|
1640
1706
|
targetDir: string,
|
|
1641
1707
|
selectedModules: string[],
|
|
1642
|
-
withAuth: boolean
|
|
1708
|
+
withAuth: boolean
|
|
1643
1709
|
) {
|
|
1644
1710
|
const modulesConfigPath = path.join(targetDir, ".lastbrain", "modules.json");
|
|
1645
1711
|
await fs.ensureDir(path.dirname(modulesConfigPath));
|
|
@@ -1660,7 +1726,7 @@ async function saveModulesConfig(
|
|
|
1660
1726
|
const modulePath = path.join(
|
|
1661
1727
|
targetDir,
|
|
1662
1728
|
"node_modules",
|
|
1663
|
-
...availableModule.package.split("/")
|
|
1729
|
+
...availableModule.package.split("/")
|
|
1664
1730
|
);
|
|
1665
1731
|
const migrationsDir = path.join(modulePath, "supabase", "migrations");
|
|
1666
1732
|
|
|
@@ -1918,7 +1984,7 @@ export function isPrivateBucket(bucket: string): boolean {
|
|
|
1918
1984
|
"api",
|
|
1919
1985
|
"storage",
|
|
1920
1986
|
"[bucket]",
|
|
1921
|
-
"[...path]"
|
|
1987
|
+
"[...path]"
|
|
1922
1988
|
);
|
|
1923
1989
|
await fs.ensureDir(apiStorageDir);
|
|
1924
1990
|
|
|
@@ -2045,7 +2111,7 @@ export async function GET(
|
|
|
2045
2111
|
|
|
2046
2112
|
await fs.writeFile(routePath, routeContent);
|
|
2047
2113
|
console.log(
|
|
2048
|
-
chalk.green("✓ app/api/storage/[bucket]/[...path]/route.ts créé")
|
|
2114
|
+
chalk.green("✓ app/api/storage/[bucket]/[...path]/route.ts créé")
|
|
2049
2115
|
);
|
|
2050
2116
|
}
|
|
2051
2117
|
|