@lastbrain/app 0.1.34 → 0.1.37
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/README.md +23 -5
- package/dist/__tests__/module-registry.test.js +5 -16
- package/dist/scripts/init-app.d.ts.map +1 -1
- package/dist/scripts/init-app.js +2 -2
- package/dist/scripts/module-add.d.ts +0 -11
- package/dist/scripts/module-add.d.ts.map +1 -1
- package/dist/scripts/module-add.js +45 -22
- package/dist/scripts/module-build.d.ts.map +1 -1
- package/dist/scripts/module-build.js +90 -1
- package/dist/scripts/module-create.d.ts +23 -0
- package/dist/scripts/module-create.d.ts.map +1 -1
- package/dist/scripts/module-create.js +737 -52
- package/dist/scripts/module-delete.d.ts +6 -0
- package/dist/scripts/module-delete.d.ts.map +1 -0
- package/dist/scripts/module-delete.js +143 -0
- package/dist/scripts/module-list.d.ts.map +1 -1
- package/dist/scripts/module-list.js +2 -2
- package/dist/scripts/module-remove.d.ts.map +1 -1
- package/dist/scripts/module-remove.js +20 -4
- package/dist/styles.css +1 -1
- package/dist/templates/DefaultDoc.d.ts.map +1 -1
- package/dist/templates/DefaultDoc.js +170 -30
- package/dist/templates/DocPage.d.ts.map +1 -1
- package/dist/templates/DocPage.js +25 -8
- package/dist/templates/migrations/20201010100000_app_base.sql +23 -24
- package/package.json +4 -4
- package/src/__tests__/module-registry.test.ts +5 -17
- package/src/scripts/db-init.ts +2 -2
- package/src/scripts/init-app.ts +5 -2
- package/src/scripts/module-add.ts +55 -23
- package/src/scripts/module-build.ts +109 -1
- package/src/scripts/module-create.ts +885 -63
- package/src/scripts/module-delete.ts +202 -0
- package/src/scripts/module-list.ts +9 -2
- package/src/scripts/module-remove.ts +36 -4
- package/src/templates/DefaultDoc.tsx +1163 -753
- package/src/templates/DocPage.tsx +28 -11
- package/src/templates/migrations/20201010100000_app_base.sql +23 -24
package/README.md
CHANGED
|
@@ -11,18 +11,36 @@ Package principal pour créer et gérer des applications Next.js LastBrain.
|
|
|
11
11
|
- 🔧 **Scripts utilitaires** - Gestion modules, migrations DB, génération docs
|
|
12
12
|
- 🎨 **Intégration Tailwind v4** - Configuration optimale out-of-the-box
|
|
13
13
|
|
|
14
|
-
## 📦 Installation
|
|
14
|
+
## 📦 Installation & Démarrage rapide
|
|
15
|
+
|
|
16
|
+
> **Recommandé :** Utilisez directement le CLI pour créer une nouvelle application
|
|
15
17
|
|
|
16
18
|
```bash
|
|
17
|
-
|
|
19
|
+
# Créer une nouvelle application LastBrain
|
|
20
|
+
pnpx @lastbrain/app@latest init mon-app
|
|
21
|
+
|
|
22
|
+
# Accéder au dossier
|
|
23
|
+
cd mon-app
|
|
24
|
+
|
|
25
|
+
# Initialiser Supabase (optionnel)
|
|
26
|
+
pnpm db:init
|
|
27
|
+
|
|
28
|
+
# Démarrer le serveur
|
|
29
|
+
pnpm dev
|
|
18
30
|
```
|
|
19
31
|
|
|
20
|
-
|
|
32
|
+
### Installation manuelle
|
|
33
|
+
|
|
34
|
+
Si vous souhaitez intégrer LastBrain dans un projet existant :
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add @lastbrain/app @lastbrain/core @lastbrain/ui
|
|
38
|
+
```
|
|
21
39
|
|
|
22
|
-
|
|
40
|
+
## 🚀 Ce que fait la commande init
|
|
23
41
|
|
|
24
42
|
```bash
|
|
25
|
-
|
|
43
|
+
pnpx @lastbrain/app@latest init mon-app
|
|
26
44
|
```
|
|
27
45
|
|
|
28
46
|
Cette commande génère une application Next.js complète avec :
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { AVAILABLE_MODULES } from "
|
|
2
|
+
import { AVAILABLE_MODULES } from "@lastbrain/core/config/modules";
|
|
3
3
|
describe("Module Registry", () => {
|
|
4
4
|
describe("AVAILABLE_MODULES", () => {
|
|
5
5
|
it("should have at least one module defined", () => {
|
|
@@ -9,29 +9,18 @@ describe("Module Registry", () => {
|
|
|
9
9
|
const authModule = AVAILABLE_MODULES.find((m) => m.name === "auth");
|
|
10
10
|
expect(authModule).toBeDefined();
|
|
11
11
|
expect(authModule?.package).toBe("@lastbrain/module-auth");
|
|
12
|
-
expect(authModule?.hasMigrations).toBe(true);
|
|
13
12
|
});
|
|
14
13
|
it("should have ai module defined", () => {
|
|
15
14
|
const aiModule = AVAILABLE_MODULES.find((m) => m.name === "ai");
|
|
16
15
|
expect(aiModule).toBeDefined();
|
|
17
16
|
expect(aiModule?.package).toBe("@lastbrain/module-ai");
|
|
18
|
-
expect(aiModule?.hasMigrations).toBe(true);
|
|
19
17
|
});
|
|
20
18
|
it("should have all required properties for each module", () => {
|
|
21
19
|
AVAILABLE_MODULES.forEach((module) => {
|
|
22
20
|
expect(module.name).toBeDefined();
|
|
23
21
|
expect(module.package).toBeDefined();
|
|
24
|
-
expect(module.
|
|
22
|
+
expect(module.emoji).toBeDefined();
|
|
25
23
|
expect(module.description).toBeDefined();
|
|
26
|
-
expect(typeof module.hasMigrations).toBe("boolean");
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
it("should have migrations paths when hasMigrations is true", () => {
|
|
30
|
-
AVAILABLE_MODULES.forEach((module) => {
|
|
31
|
-
if (module.hasMigrations) {
|
|
32
|
-
expect(module.migrationsPath).toBeDefined();
|
|
33
|
-
expect(module.migrationsDownPath).toBeDefined();
|
|
34
|
-
}
|
|
35
24
|
});
|
|
36
25
|
});
|
|
37
26
|
it("should have unique module names", () => {
|
|
@@ -44,10 +33,10 @@ describe("Module Registry", () => {
|
|
|
44
33
|
const uniquePackages = new Set(packages);
|
|
45
34
|
expect(packages.length).toBe(uniquePackages.size);
|
|
46
35
|
});
|
|
47
|
-
it("should have
|
|
36
|
+
it("should have emoji", () => {
|
|
48
37
|
AVAILABLE_MODULES.forEach((module) => {
|
|
49
|
-
// Check if
|
|
50
|
-
expect(module.
|
|
38
|
+
// Check if emoji contains at least one emoji (basic check)
|
|
39
|
+
expect(module.emoji).toMatch(/[\u{1F300}-\u{1F9FF}]/u);
|
|
51
40
|
});
|
|
52
41
|
});
|
|
53
42
|
it("should have non-empty descriptions", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-app.d.ts","sourceRoot":"","sources":["../../src/scripts/init-app.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init-app.d.ts","sourceRoot":"","sources":["../../src/scripts/init-app.ts"],"names":[],"mappings":"AAcA,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,iBAyMpD"}
|
package/dist/scripts/init-app.js
CHANGED
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "url";
|
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
|
-
import { AVAILABLE_MODULES } from "
|
|
7
|
+
import { AVAILABLE_MODULES, } from "@lastbrain/core/config/modules";
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = path.dirname(__filename);
|
|
10
10
|
export async function initApp(options) {
|
|
@@ -28,7 +28,7 @@ export async function initApp(options) {
|
|
|
28
28
|
name: "modules",
|
|
29
29
|
message: "Quels modules voulez-vous installer ?",
|
|
30
30
|
choices: AVAILABLE_MODULES.map((module) => ({
|
|
31
|
-
name: `${module.
|
|
31
|
+
name: `${module.emoji} ${module.name.charAt(0).toUpperCase() + module.name.slice(1)} - ${module.description}`,
|
|
32
32
|
value: module.name,
|
|
33
33
|
checked: false,
|
|
34
34
|
})),
|
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
interface ModuleDefinition {
|
|
2
|
-
name: string;
|
|
3
|
-
package: string;
|
|
4
|
-
displayName: string;
|
|
5
|
-
description: string;
|
|
6
|
-
hasMigrations: boolean;
|
|
7
|
-
migrationsPath?: string;
|
|
8
|
-
migrationsDownPath?: string;
|
|
9
|
-
}
|
|
10
|
-
export declare const AVAILABLE_MODULES: ModuleDefinition[];
|
|
11
1
|
export declare function addModule(moduleName: string, targetDir: string): Promise<void>;
|
|
12
|
-
export {};
|
|
13
2
|
//# sourceMappingURL=module-add.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-add.d.ts","sourceRoot":"","sources":["../../src/scripts/module-add.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module-add.d.ts","sourceRoot":"","sources":["../../src/scripts/module-add.ts"],"names":[],"mappings":"AAiCA,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBA8QpE"}
|
|
@@ -3,38 +3,30 @@ import path from "path";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
import { AVAILABLE_MODULES, } from "@lastbrain/core/config/modules";
|
|
7
|
+
// Convert core module metadata to local module definition
|
|
8
|
+
function toModuleDefinition(meta) {
|
|
9
|
+
return {
|
|
10
|
+
name: meta.name,
|
|
11
|
+
package: meta.package,
|
|
12
|
+
displayName: `${meta.emoji} ${meta.name.charAt(0).toUpperCase() + meta.name.slice(1)}`,
|
|
13
|
+
description: meta.description,
|
|
13
14
|
hasMigrations: true,
|
|
14
15
|
migrationsPath: "supabase/migrations",
|
|
15
16
|
migrationsDownPath: "supabase/migrations-down",
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
name: "ai",
|
|
19
|
-
package: "@lastbrain/module-ai",
|
|
20
|
-
displayName: "🤖 AI Generation",
|
|
21
|
-
description: "Génération de texte et d'images avec gestion de tokens",
|
|
22
|
-
hasMigrations: true,
|
|
23
|
-
migrationsPath: "supabase/migrations",
|
|
24
|
-
migrationsDownPath: "supabase/migrations-down",
|
|
25
|
-
},
|
|
26
|
-
// Ajouter d'autres modules ici au fur et à mesure
|
|
27
|
-
];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
28
19
|
export async function addModule(moduleName, targetDir) {
|
|
29
20
|
console.log(chalk.blue(`\n🔧 Ajout du module: ${moduleName}\n`));
|
|
30
|
-
const
|
|
31
|
-
if (!
|
|
21
|
+
const moduleMeta = AVAILABLE_MODULES.find((m) => m.name === moduleName);
|
|
22
|
+
if (!moduleMeta) {
|
|
32
23
|
console.error(chalk.red(`❌ Module "${moduleName}" non trouvé. Modules disponibles:`));
|
|
33
24
|
AVAILABLE_MODULES.forEach((m) => {
|
|
34
|
-
console.log(chalk.gray(` - ${m.name}: ${m.description}`));
|
|
25
|
+
console.log(chalk.gray(` - ${m.emoji} ${m.name}: ${m.description}`));
|
|
35
26
|
});
|
|
36
27
|
process.exit(1);
|
|
37
28
|
}
|
|
29
|
+
const module = toModuleDefinition(moduleMeta);
|
|
38
30
|
// 1. Vérifier qu'on est dans un projet LastBrain
|
|
39
31
|
const pkgPath = path.join(targetDir, "package.json");
|
|
40
32
|
if (!fs.existsSync(pkgPath)) {
|
|
@@ -62,6 +54,37 @@ export async function addModule(moduleName, targetDir) {
|
|
|
62
54
|
console.error(chalk.red("❌ Erreur lors de l'installation"));
|
|
63
55
|
process.exit(1);
|
|
64
56
|
}
|
|
57
|
+
// 3.1 Build du module ajouté (pour générer dist/ et éviter les erreurs d'import)
|
|
58
|
+
console.log(chalk.yellow(`\n🏗️ Build du module ${module.package}...`));
|
|
59
|
+
try {
|
|
60
|
+
// Trouver la racine du monorepo (chercher pnpm-workspace.yaml en remontant)
|
|
61
|
+
let workspaceRoot = targetDir;
|
|
62
|
+
let attempts = 0;
|
|
63
|
+
const maxAttempts = 6;
|
|
64
|
+
while (attempts < maxAttempts) {
|
|
65
|
+
if (fs.existsSync(path.join(workspaceRoot, "pnpm-workspace.yaml"))) {
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
const parent = path.resolve(workspaceRoot, "..");
|
|
69
|
+
if (parent === workspaceRoot)
|
|
70
|
+
break;
|
|
71
|
+
workspaceRoot = parent;
|
|
72
|
+
attempts++;
|
|
73
|
+
}
|
|
74
|
+
if (!fs.existsSync(path.join(workspaceRoot, "pnpm-workspace.yaml"))) {
|
|
75
|
+
console.log(chalk.gray(" ℹ️ Impossible de localiser la racine du monorepo, build ignoré"));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
execSync(`pnpm --filter ${module.package} build`, {
|
|
79
|
+
cwd: workspaceRoot,
|
|
80
|
+
stdio: "inherit",
|
|
81
|
+
});
|
|
82
|
+
console.log(chalk.green(" ✓ Module compilé"));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
console.log(chalk.yellow(" ⚠️ Build du module échoué, essayez: pnpm --filter"), module.package, "build");
|
|
87
|
+
}
|
|
65
88
|
// 5. Copier les migrations du module
|
|
66
89
|
const copiedMigrationFiles = [];
|
|
67
90
|
if (module.hasMigrations) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"AAg7BA,wBAAsB,cAAc,kBAoDnC"}
|
|
@@ -3,6 +3,10 @@ import path from "node:path";
|
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
// Utiliser PROJECT_ROOT si défini (pour pnpm --filter), sinon process.cwd()
|
|
5
5
|
const projectRoot = process.env.PROJECT_ROOT || process.cwd();
|
|
6
|
+
// Si on est dans une app, monter jusqu'à la racine du monorepo
|
|
7
|
+
const monorepoRoot = projectRoot.includes("/apps/")
|
|
8
|
+
? path.resolve(projectRoot, "..", "..")
|
|
9
|
+
: projectRoot;
|
|
6
10
|
const appDirectory = path.join(projectRoot, "app");
|
|
7
11
|
// Créer un require dans le contexte de l'application pour résoudre les modules installés dans l'app
|
|
8
12
|
const projectRequire = createRequire(path.join(projectRoot, "package.json"));
|
|
@@ -154,8 +158,38 @@ function buildPage(moduleConfig, page) {
|
|
|
154
158
|
(page.path.includes("signin") ||
|
|
155
159
|
page.path.includes("signup") ||
|
|
156
160
|
page.path.includes("reset-password"));
|
|
161
|
+
// Détecter si c'est la page de détail utilisateur qui a besoin des user tabs
|
|
162
|
+
const isUserDetailPage = page.section === "admin" &&
|
|
163
|
+
page.path.includes("users/[id]") &&
|
|
164
|
+
page.componentExport === "UserPage";
|
|
157
165
|
let content;
|
|
158
|
-
if (
|
|
166
|
+
if (isUserDetailPage) {
|
|
167
|
+
// Page spéciale SSR avec injection des user tabs
|
|
168
|
+
// On importe directement depuis app/config au lieu de passer via props
|
|
169
|
+
content = `// GENERATED BY LASTBRAIN MODULE BUILD
|
|
170
|
+
import { UserDetailPage } from "${moduleConfig.moduleName}";
|
|
171
|
+
|
|
172
|
+
interface UserPageProps { params: Promise<{ id: string }> }
|
|
173
|
+
|
|
174
|
+
async function getModuleUserTabs() {
|
|
175
|
+
try {
|
|
176
|
+
// Depuis /app/admin/auth/users/[id]/ vers /apps/test-01/config/user-tabs
|
|
177
|
+
const { moduleUserTabs } = await import("../../../../../config/user-tabs");
|
|
178
|
+
return moduleUserTabs || [];
|
|
179
|
+
} catch (e) {
|
|
180
|
+
console.warn("[user-detail-wrapper] erreur chargement user-tabs", e);
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export default async function ${wrapperName}(props: UserPageProps) {
|
|
186
|
+
const { id } = await props.params;
|
|
187
|
+
const moduleUserTabs = await getModuleUserTabs();
|
|
188
|
+
return <UserDetailPage userId={id} moduleUserTabs={moduleUserTabs} />;
|
|
189
|
+
}
|
|
190
|
+
`;
|
|
191
|
+
}
|
|
192
|
+
else if (isPublicAuthPage) {
|
|
159
193
|
content = `// GENERATED BY LASTBRAIN MODULE BUILD
|
|
160
194
|
"use client";
|
|
161
195
|
|
|
@@ -252,6 +286,8 @@ export interface MenuItem {
|
|
|
252
286
|
icon?: string;
|
|
253
287
|
path: string;
|
|
254
288
|
order?: number;
|
|
289
|
+
shortcut?: string;
|
|
290
|
+
shortcutDisplay?: string;
|
|
255
291
|
}
|
|
256
292
|
|
|
257
293
|
export interface MenuConfig {
|
|
@@ -685,6 +721,56 @@ export default realtimeConfig;
|
|
|
685
721
|
console.error("❌ Error generating realtime configuration:", error);
|
|
686
722
|
}
|
|
687
723
|
}
|
|
724
|
+
async function generateUserTabsConfig(moduleConfigs) {
|
|
725
|
+
try {
|
|
726
|
+
// Extraire les configurations user tabs des modules
|
|
727
|
+
const userTabsConfigs = moduleConfigs
|
|
728
|
+
.filter((config) => config.userTabs && config.userTabs.length > 0)
|
|
729
|
+
.flatMap((config) => config.userTabs.map((tab) => ({
|
|
730
|
+
...tab,
|
|
731
|
+
moduleName: config.moduleName,
|
|
732
|
+
})))
|
|
733
|
+
.sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
734
|
+
if (userTabsConfigs.length === 0) {
|
|
735
|
+
console.log("⏭️ No user tabs configuration found in modules");
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
// Générer les imports statiques (Next/dynamic pour chaque composant)
|
|
739
|
+
const importsForApp = userTabsConfigs
|
|
740
|
+
.map((tab) => `const ${tab.componentExport} = dynamic(() => import("${tab.moduleName}").then(mod => ({ default: mod.${tab.componentExport} })), { ssr: true });`)
|
|
741
|
+
.join("\n");
|
|
742
|
+
// Générer le tableau des tabs
|
|
743
|
+
const tabsArray = userTabsConfigs
|
|
744
|
+
.map((tab) => ` {
|
|
745
|
+
key: "${tab.key}",
|
|
746
|
+
title: "${tab.title}",
|
|
747
|
+
icon: "${tab.icon || ""}",
|
|
748
|
+
component: ${tab.componentExport},
|
|
749
|
+
}`)
|
|
750
|
+
.join(",\n");
|
|
751
|
+
const timestamp = new Date().toISOString();
|
|
752
|
+
const appContent = `// GENERATED FILE - DO NOT EDIT MANUALLY\n// User tabs configuration\n// Generated at: ${timestamp}\n\n"use client";\n\nimport dynamic from "next/dynamic";\nimport type React from "react";\n\n${importsForApp}\n\nexport interface ModuleUserTab {\n key: string;\n title: string;\n icon?: string;\n component: React.ComponentType<{ userId: string }>;\n}\n\nexport const moduleUserTabs: ModuleUserTab[] = [\n${tabsArray}\n];\n\nexport default moduleUserTabs;\n`;
|
|
753
|
+
// Créer le fichier de configuration (uniquement dans /config)
|
|
754
|
+
const outputPath = path.join(projectRoot, "config", "user-tabs.ts");
|
|
755
|
+
const configDir = path.dirname(outputPath);
|
|
756
|
+
// Créer le dossier config s'il n'existe pas
|
|
757
|
+
if (!fs.existsSync(configDir)) {
|
|
758
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
759
|
+
}
|
|
760
|
+
// Écrire le fichier TypeScript
|
|
761
|
+
fs.writeFileSync(outputPath, appContent);
|
|
762
|
+
console.log(`✅ Generated user tabs configuration: ${outputPath}`);
|
|
763
|
+
console.log(`📊 User tabs count: ${userTabsConfigs.length}`);
|
|
764
|
+
// Afficher un résumé
|
|
765
|
+
userTabsConfigs.forEach((tab) => {
|
|
766
|
+
console.log(` - ${tab.title} (${tab.moduleName})`);
|
|
767
|
+
});
|
|
768
|
+
// Plus de copie vers app/config ni stub core
|
|
769
|
+
}
|
|
770
|
+
catch (error) {
|
|
771
|
+
console.error("❌ Error generating user tabs configuration:", error);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
688
774
|
export async function runModuleBuild() {
|
|
689
775
|
ensureDirectory(appDirectory);
|
|
690
776
|
// Nettoyer les fichiers générés précédemment
|
|
@@ -720,4 +806,7 @@ export async function runModuleBuild() {
|
|
|
720
806
|
// Générer la configuration realtime
|
|
721
807
|
console.log("🔄 Generating realtime configuration...");
|
|
722
808
|
await generateRealtimeConfig(moduleConfigs);
|
|
809
|
+
// Générer la configuration des user tabs
|
|
810
|
+
console.log("📑 Generating user tabs configuration...");
|
|
811
|
+
await generateUserTabsConfig(moduleConfigs);
|
|
723
812
|
}
|
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
export interface PageConfig {
|
|
2
|
+
section: "public" | "auth" | "admin";
|
|
3
|
+
path: string;
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
export interface TableConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
sections: ("public" | "auth" | "admin")[];
|
|
9
|
+
}
|
|
10
|
+
export interface ModuleConfig {
|
|
11
|
+
slug: string;
|
|
12
|
+
moduleName: string;
|
|
13
|
+
pages: PageConfig[];
|
|
14
|
+
tables: TableConfig[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Trouve le répertoire racine du workspace (avec pnpm-workspace.yaml)
|
|
18
|
+
*/
|
|
19
|
+
export declare function findWorkspaceRoot(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Crée la structure du module
|
|
22
|
+
*/
|
|
23
|
+
export declare function createModuleStructure(config: ModuleConfig, rootDir: string): Promise<void>;
|
|
1
24
|
/**
|
|
2
25
|
* Point d'entrée du script
|
|
3
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-create.d.ts","sourceRoot":"","sources":["../../src/scripts/module-create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module-create.d.ts","sourceRoot":"","sources":["../../src/scripts/module-create.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AA+vCD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAiB1C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,iBAoLhB;AAED;;GAEG;AACH,wBAAsB,YAAY,kBAwKjC"}
|