@lastbrain/app 0.1.0

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 (159) hide show
  1. package/README.md +256 -0
  2. package/dist/app-shell/(admin)/dashboard/page.d.ts +2 -0
  3. package/dist/app-shell/(admin)/dashboard/page.d.ts.map +1 -0
  4. package/dist/app-shell/(admin)/dashboard/page.js +5 -0
  5. package/dist/app-shell/(admin)/layout.d.ts +3 -0
  6. package/dist/app-shell/(admin)/layout.d.ts.map +1 -0
  7. package/dist/app-shell/(admin)/layout.js +5 -0
  8. package/dist/app-shell/(admin)/page.d.ts +2 -0
  9. package/dist/app-shell/(admin)/page.d.ts.map +1 -0
  10. package/dist/app-shell/(admin)/page.js +5 -0
  11. package/dist/app-shell/(auth)/dashboard/page.d.ts +2 -0
  12. package/dist/app-shell/(auth)/dashboard/page.d.ts.map +1 -0
  13. package/dist/app-shell/(auth)/dashboard/page.js +5 -0
  14. package/dist/app-shell/(auth)/layout.d.ts +3 -0
  15. package/dist/app-shell/(auth)/layout.d.ts.map +1 -0
  16. package/dist/app-shell/(auth)/layout.js +5 -0
  17. package/dist/app-shell/(auth)/page.d.ts +2 -0
  18. package/dist/app-shell/(auth)/page.d.ts.map +1 -0
  19. package/dist/app-shell/(auth)/page.js +5 -0
  20. package/dist/app-shell/(public)/page.d.ts +2 -0
  21. package/dist/app-shell/(public)/page.d.ts.map +1 -0
  22. package/dist/app-shell/(public)/page.js +5 -0
  23. package/dist/app-shell/layout.d.ts +3 -0
  24. package/dist/app-shell/layout.d.ts.map +1 -0
  25. package/dist/app-shell/layout.js +3 -0
  26. package/dist/app-shell/not-found.d.ts +2 -0
  27. package/dist/app-shell/not-found.d.ts.map +1 -0
  28. package/dist/app-shell/not-found.js +10 -0
  29. package/dist/auth/authHelpers.d.ts +7 -0
  30. package/dist/auth/authHelpers.d.ts.map +1 -0
  31. package/dist/auth/authHelpers.js +19 -0
  32. package/dist/auth/useAuthSession.d.ts +7 -0
  33. package/dist/auth/useAuthSession.d.ts.map +1 -0
  34. package/dist/auth/useAuthSession.js +43 -0
  35. package/dist/cli.d.ts +3 -0
  36. package/dist/cli.d.ts.map +1 -0
  37. package/dist/cli.js +88 -0
  38. package/dist/components/TableStructure.d.ts +8 -0
  39. package/dist/components/TableStructure.d.ts.map +1 -0
  40. package/dist/components/TableStructure.js +37 -0
  41. package/dist/index.d.ts +15 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +15 -0
  44. package/dist/layouts/AdminLayout.d.ts +3 -0
  45. package/dist/layouts/AdminLayout.d.ts.map +1 -0
  46. package/dist/layouts/AdminLayout.js +5 -0
  47. package/dist/layouts/AppProviders.d.ts +13 -0
  48. package/dist/layouts/AppProviders.d.ts.map +1 -0
  49. package/dist/layouts/AppProviders.js +35 -0
  50. package/dist/layouts/AuthLayout.d.ts +3 -0
  51. package/dist/layouts/AuthLayout.d.ts.map +1 -0
  52. package/dist/layouts/AuthLayout.js +5 -0
  53. package/dist/layouts/PublicLayout.d.ts +3 -0
  54. package/dist/layouts/PublicLayout.d.ts.map +1 -0
  55. package/dist/layouts/PublicLayout.js +5 -0
  56. package/dist/layouts/RootLayout.d.ts +3 -0
  57. package/dist/layouts/RootLayout.d.ts.map +1 -0
  58. package/dist/layouts/RootLayout.js +8 -0
  59. package/dist/module-build.d.ts +2 -0
  60. package/dist/module-build.d.ts.map +1 -0
  61. package/dist/module-build.js +50 -0
  62. package/dist/modules/index.d.ts +3 -0
  63. package/dist/modules/index.d.ts.map +1 -0
  64. package/dist/modules/index.js +2 -0
  65. package/dist/modules/module-loader.d.ts +5 -0
  66. package/dist/modules/module-loader.d.ts.map +1 -0
  67. package/dist/modules/module-loader.js +10 -0
  68. package/dist/scripts/db-init.d.ts +2 -0
  69. package/dist/scripts/db-init.d.ts.map +1 -0
  70. package/dist/scripts/db-init.js +281 -0
  71. package/dist/scripts/db-migrations-sync.d.ts +2 -0
  72. package/dist/scripts/db-migrations-sync.d.ts.map +1 -0
  73. package/dist/scripts/db-migrations-sync.js +55 -0
  74. package/dist/scripts/dev-sync.d.ts +2 -0
  75. package/dist/scripts/dev-sync.d.ts.map +1 -0
  76. package/dist/scripts/dev-sync.js +182 -0
  77. package/dist/scripts/init-app.d.ts +11 -0
  78. package/dist/scripts/init-app.d.ts.map +1 -0
  79. package/dist/scripts/init-app.js +846 -0
  80. package/dist/scripts/module-add.d.ts +13 -0
  81. package/dist/scripts/module-add.d.ts.map +1 -0
  82. package/dist/scripts/module-add.js +178 -0
  83. package/dist/scripts/module-build.d.ts +2 -0
  84. package/dist/scripts/module-build.d.ts.map +1 -0
  85. package/dist/scripts/module-build.js +413 -0
  86. package/dist/scripts/module-create.d.ts +5 -0
  87. package/dist/scripts/module-create.d.ts.map +1 -0
  88. package/dist/scripts/module-create.js +694 -0
  89. package/dist/scripts/module-list.d.ts +2 -0
  90. package/dist/scripts/module-list.d.ts.map +1 -0
  91. package/dist/scripts/module-list.js +31 -0
  92. package/dist/scripts/module-remove.d.ts +2 -0
  93. package/dist/scripts/module-remove.d.ts.map +1 -0
  94. package/dist/scripts/module-remove.js +282 -0
  95. package/dist/scripts/readme-build.d.ts +2 -0
  96. package/dist/scripts/readme-build.d.ts.map +1 -0
  97. package/dist/scripts/readme-build.js +39 -0
  98. package/dist/templates/AuthGuidePage.d.ts +2 -0
  99. package/dist/templates/AuthGuidePage.d.ts.map +1 -0
  100. package/dist/templates/AuthGuidePage.js +9 -0
  101. package/dist/templates/DefaultDoc.d.ts +2 -0
  102. package/dist/templates/DefaultDoc.d.ts.map +1 -0
  103. package/dist/templates/DefaultDoc.js +29 -0
  104. package/dist/templates/DocPage.d.ts +17 -0
  105. package/dist/templates/DocPage.d.ts.map +1 -0
  106. package/dist/templates/DocPage.js +165 -0
  107. package/dist/templates/DocsPageWithModules.d.ts +2 -0
  108. package/dist/templates/DocsPageWithModules.d.ts.map +1 -0
  109. package/dist/templates/DocsPageWithModules.js +8 -0
  110. package/dist/templates/HomePage.d.ts +6 -0
  111. package/dist/templates/HomePage.d.ts.map +1 -0
  112. package/dist/templates/HomePage.js +6 -0
  113. package/dist/templates/MigrationsGuidePage.d.ts +2 -0
  114. package/dist/templates/MigrationsGuidePage.d.ts.map +1 -0
  115. package/dist/templates/MigrationsGuidePage.js +11 -0
  116. package/dist/templates/ModuleGuidePage.d.ts +2 -0
  117. package/dist/templates/ModuleGuidePage.d.ts.map +1 -0
  118. package/dist/templates/ModuleGuidePage.js +14 -0
  119. package/dist/templates/SimpleDocPage.d.ts +2 -0
  120. package/dist/templates/SimpleDocPage.d.ts.map +1 -0
  121. package/dist/templates/SimpleDocPage.js +28 -0
  122. package/dist/templates/SimpleHomePage.d.ts +6 -0
  123. package/dist/templates/SimpleHomePage.d.ts.map +1 -0
  124. package/dist/templates/SimpleHomePage.js +7 -0
  125. package/dist/templates/env.example/.env.example +6 -0
  126. package/dist/templates/migrations/20201010100000_app_base.sql +228 -0
  127. package/dist/templates/migrations/20201010100000_init.sql +123 -0
  128. package/package.json +75 -0
  129. package/src/app-shell/(admin)/layout.tsx +13 -0
  130. package/src/app-shell/(auth)/layout.tsx +13 -0
  131. package/src/app-shell/(public)/page.tsx +11 -0
  132. package/src/app-shell/layout.tsx +5 -0
  133. package/src/app-shell/not-found.tsx +28 -0
  134. package/src/layouts/AdminLayout.tsx +7 -0
  135. package/src/layouts/AppProviders.tsx +61 -0
  136. package/src/layouts/AuthLayout.tsx +7 -0
  137. package/src/layouts/PublicLayout.tsx +7 -0
  138. package/src/layouts/RootLayout.tsx +27 -0
  139. package/src/scripts/README.md +262 -0
  140. package/src/scripts/db-init.ts +338 -0
  141. package/src/scripts/db-migrations-sync.ts +86 -0
  142. package/src/scripts/dev-sync.ts +218 -0
  143. package/src/scripts/init-app.ts +1011 -0
  144. package/src/scripts/module-add.ts +242 -0
  145. package/src/scripts/module-build.ts +502 -0
  146. package/src/scripts/module-create.ts +809 -0
  147. package/src/scripts/module-list.ts +37 -0
  148. package/src/scripts/module-remove.ts +367 -0
  149. package/src/scripts/readme-build.ts +60 -0
  150. package/src/templates/AuthGuidePage.tsx +68 -0
  151. package/src/templates/DefaultDoc.tsx +462 -0
  152. package/src/templates/DocPage.tsx +381 -0
  153. package/src/templates/DocsPageWithModules.tsx +22 -0
  154. package/src/templates/MigrationsGuidePage.tsx +61 -0
  155. package/src/templates/ModuleGuidePage.tsx +71 -0
  156. package/src/templates/SimpleDocPage.tsx +587 -0
  157. package/src/templates/SimpleHomePage.tsx +385 -0
  158. package/src/templates/env.example/.env.example +6 -0
  159. package/src/templates/migrations/20201010100000_app_base.sql +228 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,UAAU,EACV,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ export { AppProviders, useAuth, useModules, useNotifications, } from "./layouts/AppProviders.js";
2
+ export { useAuthSession } from "./auth/useAuthSession.js";
3
+ export { signOut, signIn } from "./auth/authHelpers.js";
4
+ export { RootLayout } from "./layouts/RootLayout.js";
5
+ export { PublicLayout } from "./layouts/PublicLayout.js";
6
+ export { AuthLayout } from "./layouts/AuthLayout.js";
7
+ export { AdminLayout } from "./layouts/AdminLayout.js";
8
+ export { getModuleConfigs } from "./modules/module-loader.js";
9
+ // Templates de pages (starter + docs)
10
+ export { SimpleHomePage } from "./templates/SimpleHomePage.js";
11
+ export { DocPage } from "./templates/DocPage.js";
12
+ export { SimpleDocPage } from "./templates/SimpleDocPage.js";
13
+ export { ModuleGuidePage } from "./templates/ModuleGuidePage.js";
14
+ export { AuthGuidePage } from "./templates/AuthGuidePage.js";
15
+ export { MigrationsGuidePage } from "./templates/MigrationsGuidePage.js";
@@ -0,0 +1,3 @@
1
+ import type { PropsWithChildren } from "react";
2
+ export declare function AdminLayout({ children }: PropsWithChildren<{}>): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=AdminLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/AdminLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,2CAE9D"}
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ export function AdminLayout({ children }) {
4
+ return _jsx("div", { className: "pt-18 px-2 md:px-5", children: children });
5
+ }
@@ -0,0 +1,13 @@
1
+ import type { PropsWithChildren } from "react";
2
+ import type { User } from "@supabase/supabase-js";
3
+ export declare function useModules(): import("@lastbrain/core").ModuleBuildConfig[];
4
+ export declare function useNotifications(): {
5
+ messages: string[];
6
+ };
7
+ export declare function useAuth(): {
8
+ user: User | null;
9
+ loading: boolean;
10
+ isSuperAdmin: boolean;
11
+ };
12
+ export declare function AppProviders({ children }: PropsWithChildren<{}>): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=AppProviders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppProviders.d.ts","sourceRoot":"","sources":["../../src/layouts/AppProviders.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAK/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAelD,wBAAgB,UAAU,kDAEzB;AAED,wBAAgB,gBAAgB;cAf4B,MAAM,EAAE;EAiBnE;AAED,wBAAgB,OAAO;UAjBf,IAAI,GAAG,IAAI;aACR,OAAO;kBACF,OAAO;EAiBtB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,2CA0B/D"}
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { createContext, useContext, useMemo } from "react";
4
+ import { getModuleConfigs } from "../modules/module-loader.js";
5
+ import { ToastProvider } from "@lastbrain/ui";
6
+ import { useAuthSession } from "../auth/useAuthSession.js";
7
+ const ModuleContext = createContext(getModuleConfigs());
8
+ const NotificationContext = createContext({ messages: [] });
9
+ const AuthContext = createContext({
10
+ user: null,
11
+ loading: true,
12
+ isSuperAdmin: false,
13
+ });
14
+ export function useModules() {
15
+ return useContext(ModuleContext);
16
+ }
17
+ export function useNotifications() {
18
+ return useContext(NotificationContext);
19
+ }
20
+ export function useAuth() {
21
+ return useContext(AuthContext);
22
+ }
23
+ export function AppProviders({ children }) {
24
+ const modules = useMemo(() => getModuleConfigs(), []);
25
+ const notifications = useMemo(() => ({ messages: [] }), []);
26
+ const { user, loading, isSuperAdmin } = useAuthSession();
27
+ // const router = useRouter();
28
+ const authValue = useMemo(() => ({ user, loading, isSuperAdmin }), [user, loading, isSuperAdmin]);
29
+ // const handleLogout = async () => {
30
+ // const { signOut } = await import("../auth/authHelpers.js");
31
+ // await signOut();
32
+ // router.push("/auth/signin");
33
+ // };
34
+ return (_jsx(AuthContext.Provider, { value: authValue, children: _jsx(ModuleContext.Provider, { value: modules, children: _jsxs(NotificationContext.Provider, { value: notifications, children: [children, _jsx(ToastProvider, { placement: "top-right", toastOffset: 75 })] }) }) }));
35
+ }
@@ -0,0 +1,3 @@
1
+ import type { PropsWithChildren } from "react";
2
+ export declare function AuthLayout({ children }: PropsWithChildren<{}>): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=AuthLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/AuthLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,2CAE7D"}
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ export function AuthLayout({ children }) {
4
+ return _jsx("div", { className: "pt-18 px-2 md:px-5 ", children: children });
5
+ }
@@ -0,0 +1,3 @@
1
+ import type { PropsWithChildren } from "react";
2
+ export declare function PublicLayout({ children }: PropsWithChildren<{}>): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=PublicLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublicLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/PublicLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,2CAE/D"}
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ export function PublicLayout({ children }) {
4
+ return _jsx("section", { className: " px-4 ", children: children });
5
+ }
@@ -0,0 +1,3 @@
1
+ import type { PropsWithChildren } from "react";
2
+ export declare function RootLayout({ children }: PropsWithChildren<{}>): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=RootLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/RootLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAK/C,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,2CAmB7D"}
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { ThemeProvider } from "next-themes";
4
+ import { AppProviders } from "./AppProviders.js";
5
+ // Note: L'app Next.js doit importer son propre globals.css dans son layout
6
+ export function RootLayout({ children }) {
7
+ return (_jsx("html", { lang: "fr", suppressHydrationWarning: true, children: _jsx("body", { className: "min-h-screen", children: _jsx(ThemeProvider, { attribute: "class", defaultTheme: "light", enableSystem: false, storageKey: "lastbrain-theme", children: _jsx(AppProviders, { children: _jsx("div", { className: " min-h-screen bg-slate-50 text-slate-900 dark:bg-slate-950 dark:text-white", children: children }) }) }) }) }));
8
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runModuleBuild(): void;
2
+ //# sourceMappingURL=module-build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../src/module-build.ts"],"names":[],"mappings":"AAuDA,wBAAgB,cAAc,SAO7B"}
@@ -0,0 +1,50 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { moduleConfigs } from "./modules/index.js";
5
+ const webAppRoot = path.join(fileURLToPath(new URL("../../../apps/web", import.meta.url)));
6
+ const appDirectory = path.join(webAppRoot, "app");
7
+ function ensureDirectory(dir) {
8
+ fs.mkdirSync(dir, { recursive: true });
9
+ }
10
+ function toPascalCase(value) {
11
+ return value
12
+ .split(/[^a-zA-Z0-9]+/)
13
+ .filter(Boolean)
14
+ .map((segment) => segment[0].toUpperCase() + segment.slice(1))
15
+ .join("");
16
+ }
17
+ function buildPage(moduleConfig, page) {
18
+ const segments = page.path.replace(/^\//, "").split("/").filter(Boolean);
19
+ const routeDir = path.join(appDirectory, ...segments);
20
+ const filePath = path.join(routeDir, "page.tsx");
21
+ ensureDirectory(routeDir);
22
+ const wrapperSuffix = segments.length ? toPascalCase(segments.join("-")) : "Root";
23
+ const wrapperName = `${page.componentExport}${wrapperSuffix}Route`;
24
+ const content = `import { ${page.componentExport} } from "${moduleConfig.moduleName}";
25
+
26
+ export default function ${wrapperName}() {
27
+ return <${page.componentExport} />;
28
+ }
29
+ `;
30
+ fs.writeFileSync(filePath, content);
31
+ console.log(`⭐ Generated page: ${filePath}`);
32
+ }
33
+ function buildApi(moduleConfig, api) {
34
+ const segments = api.path.replace(/^\//, "").split("/").filter(Boolean);
35
+ const routeDir = path.join(appDirectory, ...segments);
36
+ const filePath = path.join(routeDir, "route.ts");
37
+ ensureDirectory(routeDir);
38
+ const content = `export { ${api.handlerExport} } from "${moduleConfig.moduleName}/${api.entryPoint}";
39
+ `;
40
+ fs.writeFileSync(filePath, content);
41
+ console.log(`🔌 Generated API route: ${filePath}`);
42
+ }
43
+ export function runModuleBuild() {
44
+ ensureDirectory(appDirectory);
45
+ for (const moduleConfig of moduleConfigs) {
46
+ moduleConfig.pages.forEach((page) => buildPage(moduleConfig, page));
47
+ moduleConfig.apis.forEach((api) => buildApi(moduleConfig, api));
48
+ }
49
+ }
50
+ runModuleBuild();
@@ -0,0 +1,3 @@
1
+ import type { ModuleBuildConfig } from "@lastbrain/core";
2
+ export declare const moduleConfigs: ModuleBuildConfig[];
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGzD,eAAO,MAAM,aAAa,EAAE,iBAAiB,EAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import authBuildConfig from "@lastbrain/module-auth/auth.build.config";
2
+ export const moduleConfigs = [authBuildConfig];
@@ -0,0 +1,5 @@
1
+ import type { ModuleBuildConfig } from "@lastbrain/core";
2
+ export declare const moduleConfigs: ModuleBuildConfig[];
3
+ export declare function getModuleConfigs(): ModuleBuildConfig[];
4
+ export declare function registerModuleConfig(config: ModuleBuildConfig): void;
5
+ //# sourceMappingURL=module-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-loader.d.ts","sourceRoot":"","sources":["../../src/modules/module-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKzD,eAAO,MAAM,aAAa,EAAE,iBAAiB,EAAO,CAAC;AAErD,wBAAgB,gBAAgB,wBAE/B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,QAE7D"}
@@ -0,0 +1,10 @@
1
+ // Ce fichier est utilisé côté client par AppProviders
2
+ // Le chargement des modules se fait uniquement au build-time dans module-build.ts
3
+ // Côté client, on exporte un tableau vide car les modules sont déjà compilés
4
+ export const moduleConfigs = [];
5
+ export function getModuleConfigs() {
6
+ return moduleConfigs;
7
+ }
8
+ export function registerModuleConfig(config) {
9
+ moduleConfigs.push(config);
10
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=db-init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-init.d.ts","sourceRoot":"","sources":["../../src/scripts/db-init.ts"],"names":[],"mappings":""}
@@ -0,0 +1,281 @@
1
+ import { spawn, spawnSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ // Utiliser PROJECT_ROOT si défini (pour pnpm --filter), sinon process.cwd()
6
+ const projectRoot = process.env.PROJECT_ROOT || process.cwd();
7
+ const supabaseDir = path.join(projectRoot, "supabase");
8
+ const envTargets = [path.join(projectRoot, ".env.local")];
9
+ // Trouver le template dans le package @lastbrain/app
10
+ const packageAppDir = path
11
+ .dirname(fileURLToPath(import.meta.url))
12
+ .replace(/dist\/scripts$/, "src");
13
+ const envExampleTemplate = path.join(packageAppDir, "templates/env.example/.env.example");
14
+ function ensureDirectory(dir) {
15
+ fs.mkdirSync(dir, { recursive: true });
16
+ }
17
+ function runSupabase(...args) {
18
+ const bin = path.join(projectRoot, "node_modules", ".bin", "supabase");
19
+ // Ensure PATH includes common binary locations
20
+ const PATH = process.env.PATH || "";
21
+ const enhancedPath = `/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:${PATH}`;
22
+ // Check if first argument is a boolean (captureOutput flag)
23
+ const captureOutput = typeof args[0] === "boolean" ? args.shift() : false;
24
+ const stdio = captureOutput ? "pipe" : "inherit";
25
+ const runners = [
26
+ () => spawnSync("supabase", args, {
27
+ cwd: projectRoot,
28
+ stdio: stdio,
29
+ env: { ...process.env, PATH: enhancedPath },
30
+ shell: true,
31
+ }),
32
+ () => spawnSync(bin, args, {
33
+ cwd: projectRoot,
34
+ stdio: stdio,
35
+ env: { ...process.env, PATH: enhancedPath },
36
+ }),
37
+ () => spawnSync("pnpm", ["exec", "supabase", ...args], {
38
+ cwd: projectRoot,
39
+ stdio: stdio,
40
+ env: { ...process.env, PATH: enhancedPath },
41
+ shell: true,
42
+ }),
43
+ ];
44
+ for (let i = 0; i < runners.length; i++) {
45
+ const result = runners[i]();
46
+ if (result.error) {
47
+ // Si c'est une erreur ENOENT (commande non trouvée), essayer la suivante
48
+ if (result.error.code === "ENOENT") {
49
+ continue;
50
+ }
51
+ // Si c'est une autre erreur, la propager
52
+ throw result.error;
53
+ }
54
+ // Si le processus s'est terminé avec un code de sortie non nul, propager l'erreur
55
+ if (result.status !== 0) {
56
+ const error = new Error(`Command failed with exit code ${result.status}`);
57
+ error.status = result.status;
58
+ throw error;
59
+ }
60
+ // Succès !
61
+ return result.stdout || null;
62
+ }
63
+ throw new Error("Unable to locate Supabase CLI (install it globally or via pnpm).");
64
+ }
65
+ function ensureSupabaseInit() {
66
+ const configPath = path.join(supabaseDir, "config.toml");
67
+ if (!fs.existsSync(configPath)) {
68
+ runSupabase("init");
69
+ }
70
+ }
71
+ function parseEnvFile(filePath) {
72
+ const data = fs.readFileSync(filePath, "utf-8");
73
+ return Object.fromEntries(data
74
+ .split("\n")
75
+ .map((line) => line.trim())
76
+ .filter((line) => line && !line.startsWith("#"))
77
+ .map((line) => {
78
+ const [key, ...value] = line.split("=");
79
+ return [key, value.join("=")];
80
+ }));
81
+ }
82
+ function ensureEnvFile(values) {
83
+ const content = Object.entries(values)
84
+ .map(([key, value]) => `${key}=${value}`)
85
+ .join("\n");
86
+ envTargets.forEach((target) => {
87
+ fs.writeFileSync(target, content);
88
+ console.log(`📝 Wrote env to ${target}`);
89
+ });
90
+ }
91
+ function buildEnvPayload(creds) {
92
+ return {
93
+ NEXT_PUBLIC_SUPABASE_URL: creds.url ?? "",
94
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: creds.anon ?? "",
95
+ SUPABASE_URL: creds.url ?? "",
96
+ SUPABASE_ANON_KEY: creds.anon ?? "",
97
+ SUPABASE_SERVICE_ROLE_KEY: creds.service ?? "",
98
+ SUPABASE_DB_URL: creds.db ?? "",
99
+ SUPABASE_JWT_SECRET: creds.jwt ?? "",
100
+ };
101
+ }
102
+ function applyEnvToProcess(values) {
103
+ process.env.NEXT_PUBLIC_SUPABASE_URL = values.NEXT_PUBLIC_SUPABASE_URL;
104
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY =
105
+ values.NEXT_PUBLIC_SUPABASE_ANON_KEY;
106
+ process.env.SUPABASE_URL = values.SUPABASE_URL;
107
+ process.env.SUPABASE_ANON_KEY = values.SUPABASE_ANON_KEY;
108
+ process.env.SUPABASE_SERVICE_ROLE_KEY = values.SUPABASE_SERVICE_ROLE_KEY;
109
+ process.env.SUPABASE_DB_URL = values.SUPABASE_DB_URL;
110
+ process.env.SUPABASE_JWT_SECRET = values.SUPABASE_JWT_SECRET;
111
+ }
112
+ function copyEnvExample() {
113
+ if (!fs.existsSync(envExampleTemplate)) {
114
+ return null;
115
+ }
116
+ const target = envTargets[0];
117
+ ensureDirectory(path.dirname(target));
118
+ fs.copyFileSync(envExampleTemplate, target);
119
+ return target;
120
+ }
121
+ function readSupabaseEnv() {
122
+ const candidate = path.join(supabaseDir, ".env");
123
+ if (fs.existsSync(candidate)) {
124
+ return parseEnvFile(candidate);
125
+ }
126
+ const candidateLocal = path.join(supabaseDir, ".env.local");
127
+ if (fs.existsSync(candidateLocal)) {
128
+ return parseEnvFile(candidateLocal);
129
+ }
130
+ return {};
131
+ }
132
+ function getSupabaseStatusEnv() {
133
+ try {
134
+ const result = runSupabase(true, "status", "-o", "env");
135
+ if (!result)
136
+ return null;
137
+ const envString = result.toString();
138
+ const lines = envString
139
+ .split("\n")
140
+ .map((line) => line.trim())
141
+ .filter((line) => line && !line.startsWith("#") && line.includes("="));
142
+ const env = {};
143
+ for (const line of lines) {
144
+ const equalIndex = line.indexOf("=");
145
+ if (equalIndex > 0) {
146
+ const key = line.substring(0, equalIndex);
147
+ const value = line
148
+ .substring(equalIndex + 1)
149
+ .replace(/^["']|["']$/g, "");
150
+ env[key] = value;
151
+ }
152
+ }
153
+ return Object.keys(env).length > 0 ? env : null;
154
+ }
155
+ catch {
156
+ return null;
157
+ }
158
+ }
159
+ function buildCredsFromStatus(status) {
160
+ if (!status) {
161
+ return null;
162
+ }
163
+ return {
164
+ url: status.API_URL ?? status.SUPABASE_URL ?? "",
165
+ anon: status.ANON_KEY ?? "",
166
+ service: status.SERVICE_ROLE_KEY ?? status.SECRET_KEY ?? "",
167
+ jwt: status.JWT_SECRET ?? "",
168
+ db: status.DB_URL ?? status.DATABASE_URL ?? "",
169
+ };
170
+ }
171
+ function findLocalKeysFallback() {
172
+ const env = readSupabaseEnv();
173
+ if (Object.keys(env).length === 0) {
174
+ return null;
175
+ }
176
+ return {
177
+ url: env.SUPABASE_URL ?? env.API_URL ?? null,
178
+ anon: env.SUPABASE_ANON_KEY ?? env.ANON_KEY ?? null,
179
+ service: env.SUPABASE_SERVICE_ROLE_KEY ?? env.SERVICE_ROLE_KEY ?? null,
180
+ jwt: env.JWT_SECRET ?? null,
181
+ db: env.SUPABASE_DB_URL ?? env.DB_URL ?? null,
182
+ };
183
+ }
184
+ async function wait(ms) {
185
+ await new Promise((resolve) => setTimeout(resolve, ms));
186
+ }
187
+ async function waitForStatus() {
188
+ const maxAttempts = 10;
189
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
190
+ const status = getSupabaseStatusEnv();
191
+ if (status && Object.keys(status).length > 0) {
192
+ return status;
193
+ }
194
+ await wait(1000);
195
+ }
196
+ return null;
197
+ }
198
+ async function gatherCredentials() {
199
+ const envStatus = await waitForStatus();
200
+ let creds = envStatus ? buildCredsFromStatus(envStatus) : null;
201
+ if (!creds || !creds.url || !creds.anon) {
202
+ const fallback = findLocalKeysFallback();
203
+ if (fallback) {
204
+ creds = {
205
+ url: fallback.url ?? "",
206
+ anon: fallback.anon ?? "",
207
+ service: fallback.service ?? "",
208
+ jwt: fallback.jwt ?? "",
209
+ db: fallback.db ?? "",
210
+ };
211
+ }
212
+ }
213
+ return creds;
214
+ }
215
+ async function main() {
216
+ ensureSupabaseInit();
217
+ const PATH = process.env.PATH || "";
218
+ const enhancedPath = `/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:${PATH}`;
219
+ const migrationResult = spawnSync("pnpm", ["--filter", "web", "db:migrations:sync"], {
220
+ cwd: projectRoot,
221
+ stdio: "inherit",
222
+ env: { ...process.env, PATH: enhancedPath },
223
+ shell: true,
224
+ });
225
+ if (migrationResult.error || migrationResult.status !== 0) {
226
+ console.warn("⚠️ Migration sync failed, continuing anyway...");
227
+ }
228
+ console.log("⚙️ Starting Supabase...");
229
+ try {
230
+ runSupabase("start");
231
+ }
232
+ catch (error) {
233
+ console.warn("⚠️ Supabase start had issues, continuing...");
234
+ }
235
+ console.log("🔄 Resetting database...");
236
+ try {
237
+ runSupabase("db", "reset");
238
+ console.log("✅ Database reset complete.");
239
+ }
240
+ catch (error) {
241
+ console.error("⚠️ supabase db reset failed:", error);
242
+ throw error;
243
+ }
244
+ console.log("🛠 Waiting for services to restart...");
245
+ await wait(3000);
246
+ const creds = await gatherCredentials();
247
+ if (creds && creds.url && creds.anon) {
248
+ const payload = buildEnvPayload(creds);
249
+ ensureEnvFile(payload);
250
+ applyEnvToProcess(payload);
251
+ console.log("✅ Environment configured successfully!");
252
+ }
253
+ else {
254
+ const example = copyEnvExample();
255
+ if (example) {
256
+ console.log("ℹ️ Copied .env.example into .env.local as fallback.");
257
+ }
258
+ console.warn("⚠️ Impossible de récupérer automatiquement les accès Supabase.");
259
+ }
260
+ if (process.argv.includes("--with-dev")) {
261
+ console.log("🚀 Launching Next dev server...");
262
+ const devProcess = spawn("pnpm", ["--filter", "web", "dev"], {
263
+ cwd: projectRoot,
264
+ stdio: "inherit",
265
+ });
266
+ devProcess.on("exit", (code) => {
267
+ console.log("🧹 Stopping Supabase");
268
+ try {
269
+ runSupabase("stop");
270
+ }
271
+ catch {
272
+ // Ignore errors when stopping
273
+ }
274
+ process.exit(code ?? 0);
275
+ });
276
+ }
277
+ }
278
+ main().catch((error) => {
279
+ console.error(error);
280
+ process.exit(1);
281
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=db-migrations-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrations-sync.d.ts","sourceRoot":"","sources":["../../src/scripts/db-migrations-sync.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { getModuleConfigs } from "../modules/module-loader.js";
4
+ // Utiliser PROJECT_ROOT si défini (pour pnpm --filter), sinon process.cwd()
5
+ const projectRoot = process.env.PROJECT_ROOT || process.cwd();
6
+ const migrationsDir = path.join(projectRoot, "supabase/migrations");
7
+ function ensureDirectory(dir) {
8
+ fs.mkdirSync(dir, { recursive: true });
9
+ }
10
+ var CopyStrategy;
11
+ (function (CopyStrategy) {
12
+ CopyStrategy[CopyStrategy["overwrite"] = 0] = "overwrite";
13
+ CopyStrategy[CopyStrategy["skip"] = 1] = "skip";
14
+ })(CopyStrategy || (CopyStrategy = {}));
15
+ function getModulePackageDir(moduleName) {
16
+ return path.join(projectRoot, "node_modules", ...moduleName.split("/"));
17
+ }
18
+ function copyMigration(moduleConfig, migration, file, index) {
19
+ const moduleDir = getModulePackageDir(moduleConfig.moduleName);
20
+ const migrationsPath = migration.path ?? "supabase/migrations";
21
+ const sourceDir = path.join(moduleDir, migrationsPath);
22
+ const sourceFile = path.join(sourceDir, file);
23
+ if (!fs.existsSync(sourceFile)) {
24
+ console.warn(`⚠️ Missing migration file ${sourceFile}`);
25
+ return;
26
+ }
27
+ ensureDirectory(migrationsDir);
28
+ const moduleSlug = moduleConfig.moduleName.replace("@lastbrain/", "module-");
29
+ const prefix = String((migration.priority ?? 0) * 10 + index + 1).padStart(3, "0");
30
+ const fileName = `${prefix}_${moduleSlug}_${file}`;
31
+ const targetFile = path.join(migrationsDir, fileName);
32
+ fs.copyFileSync(sourceFile, targetFile);
33
+ console.log(`📜 Copied migration ${fileName}`);
34
+ }
35
+ function syncModuleMigrations() {
36
+ const moduleConfigs = getModuleConfigs();
37
+ moduleConfigs.forEach((moduleConfig) => {
38
+ const migrationBlock = moduleConfig.migrations;
39
+ if (!migrationBlock || !migrationBlock.enabled) {
40
+ return;
41
+ }
42
+ const moduleMigrationPath = path.join(getModulePackageDir(moduleConfig.moduleName), migrationBlock.path ?? "supabase/migrations");
43
+ let files = migrationBlock.files;
44
+ if (!files?.length && fs.existsSync(moduleMigrationPath)) {
45
+ files = fs
46
+ .readdirSync(moduleMigrationPath)
47
+ .filter((file) => file.endsWith(".sql"))
48
+ .sort();
49
+ }
50
+ files?.forEach((file, index) => {
51
+ copyMigration(moduleConfig, migrationBlock, file, index);
52
+ });
53
+ });
54
+ }
55
+ syncModuleMigrations();
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dev-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-sync.d.ts","sourceRoot":"","sources":["../../src/scripts/dev-sync.ts"],"names":[],"mappings":""}