@lastbrain/app 0.1.39 → 0.1.42

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/cli.js CHANGED
@@ -89,8 +89,13 @@ program
89
89
  program
90
90
  .command("module:build")
91
91
  .description("Build les configurations de modules")
92
- .action(async () => {
92
+ .option("--debug", "Affiche tous les logs détaillés")
93
+ .action(async (options) => {
93
94
  try {
95
+ // Passer le flag debug via process.argv pour que module-build puisse le lire
96
+ if (options.debug && !process.argv.includes("--debug")) {
97
+ process.argv.push("--debug");
98
+ }
94
99
  const { runModuleBuild } = await import("./scripts/module-build.js");
95
100
  await runModuleBuild();
96
101
  }
@@ -3,6 +3,7 @@ export interface UserNotification {
3
3
  id: string;
4
4
  owner_id: string;
5
5
  title: string;
6
+ message: string;
6
7
  body?: string;
7
8
  type: string;
8
9
  read: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useNotifications.d.ts","sourceRoot":"","sources":["../../src/hooks/useNotifications.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI;;;;;iCAwExB,MAAM;;yCAiEN,MAAM;;;;;EAwDhC"}
1
+ {"version":3,"file":"useNotifications.d.ts","sourceRoot":"","sources":["../../src/hooks/useNotifications.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI;;;;;iCAwExB,MAAM;;yCAiEN,MAAM;;;;;EAwDhC"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  export function PublicLayout({ children }) {
4
- return _jsx("section", { className: "pt-16 px-2 md:px-0 ", children: children });
4
+ return _jsx("section", { className: "pt-16 ", children: children });
5
5
  }
@@ -723,7 +723,7 @@ export function AppProviders({ children }: { children: ReactNode }) {
723
723
  }
724
724
  async function createConfigFiles(targetDir, force, useHeroUI) {
725
725
  console.log(chalk.yellow("\n⚙️ Création des fichiers de configuration..."));
726
- // middleware.ts - Protection des routes /auth/* et /admin/*
726
+ // middleware.ts - Protection des routes /auth/*, /admin/* et /api/admin/*
727
727
  const middlewarePath = path.join(targetDir, "middleware.ts");
728
728
  if (!fs.existsSync(middlewarePath) || force) {
729
729
  const middleware = `import { type NextRequest, NextResponse } from "next/server";
@@ -731,6 +731,7 @@ import { createMiddlewareClient } from "@lastbrain/core/server";
731
731
 
732
732
  export async function middleware(request: NextRequest) {
733
733
  const { pathname } = request.nextUrl;
734
+ const isApi = pathname.startsWith("/api/");
734
735
 
735
736
  // Protéger les routes /auth/* (espace membre)
736
737
  if (pathname.startsWith("/auth")) {
@@ -740,33 +741,56 @@ export async function middleware(request: NextRequest) {
740
741
  data: { session },
741
742
  } = await supabase.auth.getSession();
742
743
 
743
- // Pas de session → redirection vers /signin
744
+ // Pas de session → nettoyage des cookies + redirection vers /auth/signin
744
745
  if (!session) {
745
- const redirectUrl = new URL("/signin", request.url);
746
+ const redirectUrl = new URL("/auth/signin", request.url);
746
747
  redirectUrl.searchParams.set("redirect", pathname);
747
- return NextResponse.redirect(redirectUrl);
748
+ const res = NextResponse.redirect(redirectUrl);
749
+ res.cookies.delete("sb-access-token");
750
+ res.cookies.delete("sb-refresh-token");
751
+ res.cookies.delete("sb:token");
752
+ res.cookies.delete("sb:refresh-token");
753
+ return res;
748
754
  }
749
755
 
750
756
  return response;
751
757
  } catch (error) {
752
758
  console.error("Middleware auth error:", error);
753
- return NextResponse.redirect(new URL("/signin", request.url));
759
+ const res = NextResponse.redirect(new URL("/auth/signin", request.url));
760
+ res.cookies.delete("sb-access-token");
761
+ res.cookies.delete("sb-refresh-token");
762
+ res.cookies.delete("sb:token");
763
+ res.cookies.delete("sb:refresh-token");
764
+ return res;
754
765
  }
755
766
  }
756
767
 
757
- // Protéger les routes /admin/* (superadmin uniquement)
758
- if (pathname.startsWith("/admin")) {
768
+ // Protéger les routes /admin/* et /api/admin/* (superadmin uniquement)
769
+ if (pathname.startsWith("/admin") || pathname.startsWith("/api/admin")) {
759
770
  try {
760
771
  const { supabase, response } = createMiddlewareClient(request);
761
772
  const {
762
773
  data: { session },
763
774
  } = await supabase.auth.getSession();
764
775
 
765
- // Pas de session → redirection vers /signin
776
+ // Pas de session → 401 JSON pour API, sinon redirection vers /auth/signin avec nettoyage cookies
766
777
  if (!session) {
767
- const redirectUrl = new URL("/signin", request.url);
778
+ if (isApi) {
779
+ const res = NextResponse.json({ error: "Non authentifié" }, { status: 401 });
780
+ res.cookies.delete("sb-access-token");
781
+ res.cookies.delete("sb-refresh-token");
782
+ res.cookies.delete("sb:token");
783
+ res.cookies.delete("sb:refresh-token");
784
+ return res;
785
+ }
786
+ const redirectUrl = new URL("/auth/signin", request.url);
768
787
  redirectUrl.searchParams.set("redirect", pathname);
769
- return NextResponse.redirect(redirectUrl);
788
+ const res = NextResponse.redirect(redirectUrl);
789
+ res.cookies.delete("sb-access-token");
790
+ res.cookies.delete("sb-refresh-token");
791
+ res.cookies.delete("sb:token");
792
+ res.cookies.delete("sb:refresh-token");
793
+ return res;
770
794
  }
771
795
 
772
796
  // Vérifier si l'utilisateur est superadmin
@@ -777,13 +801,24 @@ export async function middleware(request: NextRequest) {
777
801
 
778
802
  if (error || !isSuperAdmin) {
779
803
  console.error("Access denied: not a superadmin", error);
804
+ if (isApi) {
805
+ return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
806
+ }
780
807
  return NextResponse.redirect(new URL("/", request.url));
781
808
  }
782
809
 
783
810
  return response;
784
811
  } catch (error) {
785
812
  console.error("Middleware admin error:", error);
786
- return NextResponse.redirect(new URL("/", request.url));
813
+ if (isApi) {
814
+ return NextResponse.json({ error: "Erreur middleware" }, { status: 500 });
815
+ }
816
+ const res = NextResponse.redirect(new URL("/", request.url));
817
+ res.cookies.delete("sb-access-token");
818
+ res.cookies.delete("sb-refresh-token");
819
+ res.cookies.delete("sb:token");
820
+ res.cookies.delete("sb:refresh-token");
821
+ return res;
787
822
  }
788
823
  }
789
824
 
@@ -804,7 +839,7 @@ export const config = {
804
839
  };
805
840
  `;
806
841
  await fs.writeFile(middlewarePath, middleware);
807
- console.log(chalk.green("✓ middleware.ts créé (protection /auth/* et /admin/*)"));
842
+ console.log(chalk.green("✓ middleware.ts créé (protection /auth/*, /admin/* et /api/admin/*)"));
808
843
  }
809
844
  // next.config.mjs
810
845
  const nextConfigPath = path.join(targetDir, "next.config.mjs");
@@ -1290,6 +1325,13 @@ export const BUCKET_CONFIGS: Record<string, BucketConfig> = {
1290
1325
  return filePath.startsWith(\`\${userId}/\`);
1291
1326
  },
1292
1327
  },
1328
+ recipes: {
1329
+ name: "recipes",
1330
+ isPublic: true,
1331
+ description: "Public recipe images accessible by slug",
1332
+ allowedFileTypes: ["image/jpeg", "image/png", "image/webp", "image/gif"],
1333
+ maxFileSize: 50 * 1024 * 1024, // 50MB
1334
+ },
1293
1335
  // Example for future buckets:
1294
1336
  // public: {
1295
1337
  // name: "public",
@@ -1 +1 @@
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"}
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,iBA+SpE"}
@@ -145,15 +145,33 @@ export async function addModule(moduleName, targetDir) {
145
145
  }
146
146
  else if (migrationAction === "push") {
147
147
  console.log(chalk.yellow("\n⬆️ Application des nouvelles migrations..."));
148
- try {
149
- execSync("supabase migration up", {
150
- cwd: targetDir,
151
- stdio: "inherit",
152
- });
153
- console.log(chalk.green("✓ Migrations appliquées"));
148
+ // Appliquer directement avec psql au lieu de supabase migration up
149
+ const migrationsDir = path.join(targetDir, "supabase", "migrations");
150
+ const migrationFiles = fs
151
+ .readdirSync(migrationsDir)
152
+ .filter((f) => f.endsWith(".sql"))
153
+ .filter((f) => copiedMigrationFiles.includes(f))
154
+ .sort();
155
+ if (migrationFiles.length === 0) {
156
+ console.log(chalk.yellow("⚠️ Aucune nouvelle migration à appliquer"));
154
157
  }
155
- catch {
156
- console.error(chalk.red("❌ Erreur lors de l'application des migrations"));
158
+ else {
159
+ try {
160
+ const dbUrl = "postgresql://postgres:postgres@127.0.0.1:54322/postgres";
161
+ for (const file of migrationFiles) {
162
+ const filePath = path.join(migrationsDir, file);
163
+ console.log(chalk.gray(` Exécution de ${file}...`));
164
+ execSync(`psql "${dbUrl}" -f "${filePath}"`, {
165
+ cwd: targetDir,
166
+ stdio: "pipe",
167
+ });
168
+ }
169
+ console.log(chalk.green(`✓ ${migrationFiles.length} migration(s) appliquée(s)`));
170
+ }
171
+ catch (error) {
172
+ console.error(chalk.red("❌ Erreur lors de l'application des migrations"));
173
+ console.log(chalk.gray("\nVous pouvez essayer manuellement:\n supabase db reset\n"));
174
+ }
157
175
  }
158
176
  }
159
177
  else {
@@ -203,12 +221,12 @@ export async function addModule(moduleName, targetDir) {
203
221
  // 7. Générer automatiquement les routes du module
204
222
  console.log(chalk.yellow("🔧 Génération des routes du module..."));
205
223
  try {
206
- execSync("pnpm build:modules", { cwd: targetDir, stdio: "inherit" });
224
+ execSync("pnpm run build:modules", { cwd: targetDir, stdio: "inherit" });
207
225
  console.log(chalk.green("✓ Routes du module générées"));
208
226
  }
209
227
  catch {
210
228
  console.error(chalk.red("❌ Erreur lors de la génération des routes"));
211
- console.error(chalk.gray("Vous pouvez les générer manuellement avec: pnpm build:modules"));
229
+ console.error(chalk.gray("Vous pouvez les générer manuellement avec: cd apps/<votre-app> && pnpm run build:modules"));
212
230
  }
213
231
  console.log(chalk.gray("\nLe serveur de développement redémarrera automatiquement.\n"));
214
232
  }
@@ -1 +1 @@
1
- {"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"AAg7BA,wBAAsB,cAAc,kBAoDnC"}
1
+ {"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"AAw0CA,wBAAsB,cAAc,kBAyFnC"}