@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.
- package/dist/__tests__/module-registry.test.d.ts +2 -0
- package/dist/__tests__/module-registry.test.d.ts.map +1 -0
- package/dist/__tests__/module-registry.test.js +64 -0
- package/dist/app-shell/(admin)/layout.d.ts +3 -2
- package/dist/app-shell/(admin)/layout.d.ts.map +1 -1
- package/dist/app-shell/(admin)/layout.js +1 -1
- package/dist/app-shell/(auth)/layout.d.ts +3 -2
- package/dist/app-shell/(auth)/layout.d.ts.map +1 -1
- package/dist/app-shell/(auth)/layout.js +1 -1
- package/dist/app-shell/(public)/page.d.ts.map +1 -1
- package/dist/cli.js +50 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/layouts/AdminLayout.d.ts +3 -2
- package/dist/layouts/AdminLayout.d.ts.map +1 -1
- package/dist/layouts/AdminLayoutWithSidebar.d.ts +8 -0
- package/dist/layouts/AdminLayoutWithSidebar.d.ts.map +1 -0
- package/dist/layouts/AdminLayoutWithSidebar.js +9 -0
- package/dist/layouts/AppProviders.d.ts +3 -2
- package/dist/layouts/AppProviders.d.ts.map +1 -1
- package/dist/layouts/AuthLayout.d.ts +3 -2
- package/dist/layouts/AuthLayout.d.ts.map +1 -1
- package/dist/layouts/AuthLayoutWithSidebar.d.ts +8 -0
- package/dist/layouts/AuthLayoutWithSidebar.d.ts.map +1 -0
- package/dist/layouts/AuthLayoutWithSidebar.js +9 -0
- package/dist/layouts/PublicLayout.d.ts +3 -2
- package/dist/layouts/PublicLayout.d.ts.map +1 -1
- package/dist/layouts/RootLayout.d.ts +3 -2
- package/dist/layouts/RootLayout.d.ts.map +1 -1
- package/dist/scripts/db-init.js +2 -2
- package/dist/scripts/db-migrations-sync.js +5 -5
- package/dist/scripts/dev-sync.js +21 -10
- package/dist/scripts/init-app.d.ts.map +1 -1
- package/dist/scripts/init-app.js +126 -21
- package/dist/scripts/module-add.d.ts.map +1 -1
- package/dist/scripts/module-add.js +20 -7
- package/dist/scripts/module-build.d.ts.map +1 -1
- package/dist/scripts/module-build.js +285 -30
- package/dist/scripts/module-create.d.ts.map +1 -1
- package/dist/scripts/module-create.js +25 -15
- package/dist/scripts/module-remove.d.ts.map +1 -1
- package/dist/scripts/module-remove.js +24 -11
- package/dist/scripts/script-runner.d.ts +5 -0
- package/dist/scripts/script-runner.d.ts.map +1 -0
- package/dist/scripts/script-runner.js +25 -0
- package/dist/styles.css +1 -1
- package/dist/templates/DefaultDoc.js +1 -7
- package/dist/templates/DocPage.d.ts.map +1 -1
- package/dist/templates/DocPage.js +14 -14
- package/dist/templates/components/AppAside.d.ts +6 -0
- package/dist/templates/components/AppAside.d.ts.map +1 -0
- package/dist/templates/components/AppAside.js +9 -0
- package/dist/templates/layouts/admin-layout.d.ts +4 -0
- package/dist/templates/layouts/admin-layout.d.ts.map +1 -0
- package/dist/templates/layouts/admin-layout.js +6 -0
- package/dist/templates/layouts/auth-layout.d.ts +4 -0
- package/dist/templates/layouts/auth-layout.d.ts.map +1 -0
- package/dist/templates/layouts/auth-layout.js +6 -0
- package/package.json +2 -1
- package/src/__tests__/module-registry.test.ts +74 -0
- package/src/app-shell/(admin)/layout.tsx +5 -3
- package/src/app-shell/(auth)/layout.tsx +5 -3
- package/src/app-shell/(public)/page.tsx +6 -2
- package/src/auth/useAuthSession.ts +1 -1
- package/src/cli.ts +51 -1
- package/src/index.ts +6 -0
- package/src/layouts/AdminLayout.tsx +1 -3
- package/src/layouts/AdminLayoutWithSidebar.tsx +35 -0
- package/src/layouts/AppProviders.tsx +3 -5
- package/src/layouts/AuthLayout.tsx +1 -3
- package/src/layouts/AuthLayoutWithSidebar.tsx +35 -0
- package/src/layouts/PublicLayout.tsx +1 -3
- package/src/layouts/RootLayout.tsx +1 -2
- package/src/scripts/db-init.ts +13 -8
- package/src/scripts/db-migrations-sync.ts +4 -4
- package/src/scripts/dev-sync.ts +49 -18
- package/src/scripts/init-app.ts +246 -73
- package/src/scripts/module-add.ts +49 -23
- package/src/scripts/module-build.ts +393 -88
- package/src/scripts/module-create.ts +85 -49
- package/src/scripts/module-remove.ts +116 -57
- package/src/scripts/readme-build.ts +2 -2
- package/src/scripts/script-runner.ts +28 -0
- package/src/templates/AuthGuidePage.tsx +1 -1
- package/src/templates/DefaultDoc.tsx +7 -7
- package/src/templates/DocPage.tsx +74 -46
|
@@ -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): {
|
|
51
|
+
function getLastBrainPackageVersions(rootDir: string): {
|
|
52
|
+
core: string;
|
|
53
|
+
ui: string;
|
|
54
|
+
} {
|
|
52
55
|
try {
|
|
53
56
|
const corePackageJson = JSON.parse(
|
|
54
|
-
fs.readFileSync(
|
|
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(
|
|
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
|
|
65
|
-
console.warn(
|
|
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(
|
|
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 =
|
|
244
|
-
|
|
260
|
+
const menuConfig =
|
|
261
|
+
menuSections.length > 0
|
|
262
|
+
? `,
|
|
245
263
|
menu: {
|
|
246
|
-
${menuSections
|
|
264
|
+
${menuSections
|
|
265
|
+
.map(
|
|
266
|
+
({ section, items }) => ` ${section}: [
|
|
247
267
|
${items.join(",\n")}
|
|
248
|
-
]
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
147
|
-
(typeof m ===
|
|
150
|
+
const moduleEntry = modulesConfig.modules.find(
|
|
151
|
+
(m: any) => (typeof m === "string" ? m : m.package) === module.package,
|
|
148
152
|
);
|
|
149
|
-
|
|
150
|
-
if (
|
|
153
|
+
|
|
154
|
+
if (
|
|
155
|
+
moduleEntry &&
|
|
156
|
+
typeof moduleEntry === "object" &&
|
|
157
|
+
moduleEntry.migrations
|
|
158
|
+
) {
|
|
151
159
|
migrationFiles = moduleEntry.migrations;
|
|
152
|
-
console.log(
|
|
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(
|
|
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(
|
|
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,29 +255,43 @@ 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(
|
|
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(
|
|
247
|
-
|
|
248
|
-
|
|
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(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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(
|
|
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
296
|
} catch (error) {
|
|
265
297
|
console.error(chalk.red(` ❌ Erreur avec ${downFile}`));
|
|
@@ -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);
|
|
@@ -289,15 +321,15 @@ export async function removeModule(moduleName: string, targetDir: string) {
|
|
|
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
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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(
|
|
340
|
-
|
|
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(
|
|
391
|
+
console.log(
|
|
392
|
+
chalk.gray("\n✓ Module marqué comme inactif dans modules.json"),
|
|
393
|
+
);
|
|
347
394
|
} catch (error) {
|
|
348
|
-
console.error(
|
|
395
|
+
console.error(
|
|
396
|
+
chalk.red("❌ Erreur lors de la mise à jour de modules.json"),
|
|
397
|
+
);
|
|
349
398
|
}
|
|
350
399
|
}
|
|
351
400
|
|
|
@@ -359,9 +408,19 @@ export async function removeModule(moduleName: string, targetDir: string) {
|
|
|
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 (error) {
|
|
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
|
}
|
|
@@ -16,13 +16,13 @@ function resolveModuleReadme(moduleName: string) {
|
|
|
16
16
|
projectRoot,
|
|
17
17
|
"packages",
|
|
18
18
|
moduleName.replace("@lastbrain/", ""),
|
|
19
|
-
"README.md"
|
|
19
|
+
"README.md",
|
|
20
20
|
),
|
|
21
21
|
path.join(
|
|
22
22
|
projectRoot,
|
|
23
23
|
"node_modules",
|
|
24
24
|
...moduleName.split("/"),
|
|
25
|
-
"README.md"
|
|
25
|
+
"README.md",
|
|
26
26
|
),
|
|
27
27
|
];
|
|
28
28
|
|