retrex-extensibles-core 1.2.7 → 1.2.9

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/index.cjs CHANGED
@@ -30,7 +30,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- RouteManager: () => useRoutes_exports,
34
33
  ThemeProvider: () => ThemeProvider,
35
34
  getModules: () => getModules,
36
35
  getServices: () => getServices,
@@ -49,6 +48,7 @@ __export(index_exports, {
49
48
  registerExtensibles: () => registerExtensibles,
50
49
  registerMiddleware: () => registerMiddleware,
51
50
  registerRoutes: () => registerRoutes,
51
+ routesManager: () => routesManager,
52
52
  saveJSON: () => saveJSON,
53
53
  toggleModule: () => toggleModule,
54
54
  toggleService: () => toggleService,
@@ -59,7 +59,7 @@ __export(index_exports, {
59
59
  useSettings: () => useSettings,
60
60
  useTemplates: () => useTemplates,
61
61
  useTheme: () => useTheme,
62
- utils: () => loadThemeComponent_exports
62
+ useUtils: () => useUtils
63
63
  });
64
64
  module.exports = __toCommonJS(index_exports);
65
65
 
@@ -483,110 +483,71 @@ async function useEvents(io) {
483
483
  }
484
484
 
485
485
  // src/core/hooks/useRoutes.ts
486
- var useRoutes_exports = {};
487
- __export(useRoutes_exports, {
488
- getRegisteredRoutes: () => getRegisteredRoutes,
489
- mountRegisteredRoutes: () => mountRegisteredRoutes,
490
- registerRoute: () => registerRoute
491
- });
492
486
  var import_url = require("url");
493
487
  var registeredRoutes = [];
494
- function registerRoute(def) {
495
- registeredRoutes.push(def);
496
- }
497
- function getRegisteredRoutes() {
498
- return registeredRoutes;
499
- }
500
- async function mountRegisteredRoutes(app) {
501
- for (const route of registeredRoutes) {
502
- const mod = await import((0, import_url.pathToFileURL)(route.filePath).toString());
503
- const hasLoader = typeof mod.loader === "function";
504
- const hasAction = typeof mod.action === "function";
505
- const hasDefault = typeof mod.default !== "undefined";
506
- if (!hasDefault && (hasLoader || hasAction)) {
507
- app[route.method](route.path, async (req, res, next) => {
508
- try {
509
- if (route.method === "get" && hasLoader) {
510
- const result = await mod.loader({ request: req });
511
- res.json(result);
512
- } else if (hasAction) {
513
- const result = await mod.action({ request: req });
514
- res.json(result);
515
- } else {
516
- res.status(405).json({ error: "Method Not Allowed" });
488
+ var routesManager = {
489
+ /**
490
+ * Register a dynamic route from a module/service.
491
+ */
492
+ registerRoute(def) {
493
+ registeredRoutes.push(def);
494
+ },
495
+ /**
496
+ * Return all registered dynamic routes.
497
+ */
498
+ getRegisteredRoutes() {
499
+ return registeredRoutes;
500
+ },
501
+ /**
502
+ * Loads and mounts all registered dynamic routes into an Express app.
503
+ */
504
+ async mountRegisteredRoutes(app) {
505
+ for (const route of registeredRoutes) {
506
+ const mod = await import((0, import_url.pathToFileURL)(route.filePath).toString());
507
+ const hasLoader = typeof mod.loader === "function";
508
+ const hasAction = typeof mod.action === "function";
509
+ const hasDefault = typeof mod.default !== "undefined";
510
+ if (!hasDefault && (hasLoader || hasAction)) {
511
+ app[route.method](route.path, async (req, res, next) => {
512
+ try {
513
+ if (route.method === "get" && hasLoader) {
514
+ const result = await mod.loader({ request: req });
515
+ res.json(result);
516
+ } else if (hasAction) {
517
+ const result = await mod.action({ request: req });
518
+ res.json(result);
519
+ } else {
520
+ res.status(405).json({ error: "Method Not Allowed" });
521
+ }
522
+ } catch (err) {
523
+ next(err);
517
524
  }
518
- } catch (err) {
519
- next(err);
520
- }
521
- });
522
- } else if (hasDefault) {
523
- app.use(route.path, (req, res, next) => {
524
- res.locals.__dynamicPageComponent = mod.default;
525
- next();
526
- });
525
+ });
526
+ } else if (hasDefault) {
527
+ app.use(route.path, (req, res, next) => {
528
+ res.locals.__dynamicPageComponent = mod.default;
529
+ next();
530
+ });
531
+ }
527
532
  }
528
533
  }
529
- }
530
-
531
- // src/core/providers/ThemeProvider.tsx
532
- var import_react = require("react");
533
- var import_jsx_runtime = require("react/jsx-runtime");
534
- var ThemeContext = (0, import_react.createContext)(null);
535
- var ThemeProvider = ({ type, children }) => {
536
- const [activeTheme, setActiveTheme] = (0, import_react.useState)(() => {
537
- const templates = getTemplates(type);
538
- const enabled = templates.find((t) => t.enabled);
539
- return enabled?.lowerName ?? templates[0]?.lowerName ?? "default";
540
- });
541
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value: { templateType: type, activeTheme, setActiveTheme }, children });
542
534
  };
543
- function useTheme() {
544
- const ctx = (0, import_react.useContext)(ThemeContext);
545
- if (!ctx) throw new Error("useTheme must be used inside a ThemeProvider");
546
- return ctx;
547
- }
548
535
 
549
- // src/core/utils/loadThemeComponent.ts
550
- var loadThemeComponent_exports = {};
551
- __export(loadThemeComponent_exports, {
552
- loadThemeComponent: () => loadThemeComponent
553
- });
536
+ // src/core/hooks/useUtils.ts
554
537
  var import_path2 = __toESM(require("path"), 1);
555
538
  var import_url2 = require("url");
556
539
  var import_fs_extra3 = __toESM(require("fs-extra"), 1);
557
- async function loadThemeComponent(componentName, options) {
558
- const { search = {}, theme } = options;
559
- const searchThemes = search.themes ?? true;
560
- const searchModules = search.modules ?? true;
561
- const searchServices = search.services ?? true;
562
- const possiblePaths = [];
563
- if (searchThemes) {
564
- possiblePaths.push(
565
- import_path2.default.resolve(
566
- "resources",
567
- "themes",
568
- theme.type,
569
- theme.name,
570
- "routes",
571
- `${componentName}.tsx`
572
- ),
573
- import_path2.default.resolve(
574
- "resources",
575
- "themes",
576
- theme.type,
577
- theme.name,
578
- "components",
579
- `${componentName}.tsx`
580
- )
581
- );
582
- }
583
- if (searchModules) {
584
- const moduleDirs = await import_fs_extra3.default.readdir(useSettings.getPaths().modules);
585
- for (const mod of moduleDirs) {
540
+ var useUtils = {
541
+ async loadThemeComponent(componentName, options) {
542
+ const { search = {}, theme } = options;
543
+ const searchThemes = search.themes ?? true;
544
+ const searchModules = search.modules ?? true;
545
+ const searchServices = search.services ?? true;
546
+ const possiblePaths = [];
547
+ if (searchThemes) {
586
548
  possiblePaths.push(
587
549
  import_path2.default.resolve(
588
- "modules",
589
- mod,
550
+ "resources",
590
551
  "themes",
591
552
  theme.type,
592
553
  theme.name,
@@ -594,8 +555,7 @@ async function loadThemeComponent(componentName, options) {
594
555
  `${componentName}.tsx`
595
556
  ),
596
557
  import_path2.default.resolve(
597
- "modules",
598
- mod,
558
+ "resources",
599
559
  "themes",
600
560
  theme.type,
601
561
  theme.name,
@@ -604,48 +564,90 @@ async function loadThemeComponent(componentName, options) {
604
564
  )
605
565
  );
606
566
  }
607
- }
608
- if (searchServices) {
609
- const serviceDirs = await import_fs_extra3.default.readdir(useSettings.getPaths().services);
610
- for (const svc of serviceDirs) {
611
- possiblePaths.push(
612
- import_path2.default.resolve(
613
- "services",
614
- svc,
615
- "themes",
616
- theme.type,
617
- theme.name,
618
- "routes",
619
- `${componentName}.tsx`
620
- ),
621
- import_path2.default.resolve(
622
- "services",
623
- svc,
624
- "themes",
625
- theme.type,
626
- theme.name,
627
- "components",
628
- `${componentName}.tsx`
629
- )
630
- );
567
+ if (searchModules) {
568
+ const moduleDirs = await import_fs_extra3.default.readdir(useSettings.getPaths().modules);
569
+ for (const mod of moduleDirs) {
570
+ possiblePaths.push(
571
+ import_path2.default.resolve(
572
+ "modules",
573
+ mod,
574
+ "themes",
575
+ theme.type,
576
+ theme.name,
577
+ "routes",
578
+ `${componentName}.tsx`
579
+ ),
580
+ import_path2.default.resolve(
581
+ "modules",
582
+ mod,
583
+ "themes",
584
+ theme.type,
585
+ theme.name,
586
+ "components",
587
+ `${componentName}.tsx`
588
+ )
589
+ );
590
+ }
631
591
  }
632
- }
633
- for (const filePath of possiblePaths) {
634
- if (await import_fs_extra3.default.pathExists(filePath)) {
635
- try {
636
- const mod = await import((0, import_url2.pathToFileURL)(filePath).toString());
637
- if (mod.default) return mod.default;
638
- } catch (err) {
639
- console.error(`Error loading component at ${filePath}:`, err);
592
+ if (searchServices) {
593
+ const serviceDirs = await import_fs_extra3.default.readdir(useSettings.getPaths().services);
594
+ for (const svc of serviceDirs) {
595
+ possiblePaths.push(
596
+ import_path2.default.resolve(
597
+ "services",
598
+ svc,
599
+ "themes",
600
+ theme.type,
601
+ theme.name,
602
+ "routes",
603
+ `${componentName}.tsx`
604
+ ),
605
+ import_path2.default.resolve(
606
+ "services",
607
+ svc,
608
+ "themes",
609
+ theme.type,
610
+ theme.name,
611
+ "components",
612
+ `${componentName}.tsx`
613
+ )
614
+ );
615
+ }
616
+ }
617
+ for (const filePath of possiblePaths) {
618
+ if (await import_fs_extra3.default.pathExists(filePath)) {
619
+ try {
620
+ const mod = await import((0, import_url2.pathToFileURL)(filePath).toString());
621
+ if (mod.default) return mod.default;
622
+ } catch (err) {
623
+ console.error(`Error loading component at ${filePath}:`, err);
624
+ }
640
625
  }
641
626
  }
627
+ console.warn(`Component "${componentName}" not found in theme "${theme.name}" of type "${theme.type}".`);
628
+ return null;
642
629
  }
643
- console.warn(`Component "${componentName}" not found in theme "${theme.name}" of type "${theme.type}".`);
644
- return null;
630
+ };
631
+
632
+ // src/core/providers/ThemeProvider.tsx
633
+ var import_react = require("react");
634
+ var import_jsx_runtime = require("react/jsx-runtime");
635
+ var ThemeContext = (0, import_react.createContext)(null);
636
+ var ThemeProvider = ({ type, children }) => {
637
+ const [activeTheme, setActiveTheme] = (0, import_react.useState)(() => {
638
+ const templates = getTemplates(type);
639
+ const enabled = templates.find((t) => t.enabled);
640
+ return enabled?.lowerName ?? templates[0]?.lowerName ?? "default";
641
+ });
642
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value: { templateType: type, activeTheme, setActiveTheme }, children });
643
+ };
644
+ function useTheme() {
645
+ const ctx = (0, import_react.useContext)(ThemeContext);
646
+ if (!ctx) throw new Error("useTheme must be used inside a ThemeProvider");
647
+ return ctx;
645
648
  }
646
649
  // Annotate the CommonJS export names for ESM import in node:
647
650
  0 && (module.exports = {
648
- RouteManager,
649
651
  ThemeProvider,
650
652
  getModules,
651
653
  getServices,
@@ -664,6 +666,7 @@ async function loadThemeComponent(componentName, options) {
664
666
  registerExtensibles,
665
667
  registerMiddleware,
666
668
  registerRoutes,
669
+ routesManager,
667
670
  saveJSON,
668
671
  toggleModule,
669
672
  toggleService,
@@ -674,6 +677,6 @@ async function loadThemeComponent(componentName, options) {
674
677
  useSettings,
675
678
  useTemplates,
676
679
  useTheme,
677
- utils
680
+ useUtils
678
681
  });
679
682
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/hooks/useExtensibles.ts","../src/core/hooks/useSettings.ts","../src/core/hooks/useModules.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTemplates.ts","../src/core/hooks/useEvents.ts","../src/core/hooks/useRoutes.ts","../src/core/providers/ThemeProvider.tsx","../src/core/utils/loadThemeComponent.ts"],"sourcesContent":["// src/index.ts\r\n\r\nexport * from './core/hooks/useExtensibles';\r\nexport * from './core/hooks/useSettings';\r\n// export * from './core/controller/EventController';\r\n// export * from './core/controller/MiddlewareController';\r\nexport * from './core/hooks/useModules';\r\nexport * from './core/hooks/useServices';\r\nexport * from './core/hooks/useTemplates';\r\nexport * from './core/hooks/useEvents';\r\nexport * as RouteManager from './core/hooks/useRoutes';\r\n// export * as ThemeProvider from './core/providers/ThemeProvider';\r\nexport * from './core/providers/ThemeProvider';\r\nexport * as utils from './core/utils/loadThemeComponent';\r\n","// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\n\r\nexport type TemplateType = 'admin-theme' | 'client-theme' | 'portal' | 'email';\r\n\r\nexport interface ExtensibleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n description?: string;\r\n author?: string;\r\n icon?: string;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface ExtensiblePaths {\r\n modules: string;\r\n templates: string;\r\n services: string;\r\n events: string;\r\n}\r\n\r\nlet paths: ExtensiblePaths;\r\n\r\nexport function registerExtensibles(extensiblePaths: ExtensiblePaths) {\r\n paths = extensiblePaths;\r\n}\r\n\r\nexport function loadJSON(filePath: string): any {\r\n if (!fs.existsSync(filePath)) return null;\r\n return JSON.parse(fs.readFileSync(filePath, 'utf-8'));\r\n}\r\n\r\nexport function saveJSON(filePath: string, data: any) {\r\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\r\n}\r\n\r\n// --- MODULES ---\r\n\r\nexport function getModules(): ExtensibleMeta[] {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.modules)\r\n .filter((d: any) => fs.statSync(path.join(paths.modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.modules, dir, 'module.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isModuleEnabled(name: string) {\r\n const modules = getModules();\r\n return modules.find((m) => m.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleModule(name: string, enabled: boolean) {\r\n const modules = getModules();\r\n const mod = modules.find((m) => m.lowerName === name.toLowerCase());\r\n if (!mod) throw new Error(`Module ${name} not found`);\r\n\r\n const metaPath = path.join(paths.modules, mod.lowerName, 'module.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onModuleEnabled(mod.name);\r\n else onModuleDisabled(mod.name);\r\n}\r\n\r\n// --- SERVICES ---\r\n\r\nexport function getServices(): ExtensibleMeta[] {\r\n if (!paths?.services) throw new Error('Services path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.services)\r\n .filter((d: any) => fs.statSync(path.join(paths.services, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.services, dir, 'service.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isServiceEnabled(name: string) {\r\n const services = getServices();\r\n return services.find((s) => s.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleService(name: string, enabled: boolean) {\r\n const services = getServices();\r\n const svc = services.find((s) => s.lowerName === name.toLowerCase());\r\n if (!svc) throw new Error(`Service ${name} not found`);\r\n\r\n const metaPath = path.join(paths.services, svc.lowerName, 'service.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onServiceEnabled(svc.name);\r\n else onServiceDisabled(svc.name);\r\n}\r\n\r\n// --- TEMPLATES ---\r\n\r\n// Helper to get base path for a template type\r\nfunction getTemplateBasePath(type: TemplateType): string {\r\n if (!paths?.templates) throw new Error('Templates path not registered.');\r\n switch (type) {\r\n case 'admin-theme':\r\n case 'client-theme':\r\n return path.join(paths.templates, 'themes');\r\n case 'portal':\r\n return path.join(paths.templates, 'portals');\r\n case 'email':\r\n return path.join(paths.templates, 'emails');\r\n default:\r\n throw new Error(`Unknown template type: ${type}`);\r\n }\r\n}\r\n\r\nexport function getTemplates(type: TemplateType): ExtensibleMeta[] {\r\n const basePath = getTemplateBasePath(type);\r\n if (!fs.existsSync(basePath)) return [];\r\n\r\n const dirs = fs\r\n .readdirSync(basePath)\r\n .filter((d: any) => fs.statSync(path.join(basePath, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(basePath, dir, 'template.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isTemplateActive(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n return templates.find((t) => t.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\n// Toggle templates: only 1 active per type allowed\r\nexport function toggleTemplate(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n\r\n templates.forEach((tpl) => {\r\n const metaPath = path.join(getTemplateBasePath(type), tpl.lowerName, 'template.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = tpl.lowerName === name.toLowerCase();\r\n saveJSON(metaPath, meta);\r\n });\r\n\r\n onTemplateSelect(type, name);\r\n}\r\n\r\n// --- EVENTS (replace with your event system integration) ---\r\n\r\nexport function onModuleEnabled(name: string) {\r\n console.log(`Module enabled: ${name}`);\r\n // emit event or custom logic here\r\n}\r\n\r\nexport function onModuleDisabled(name: string) {\r\n console.log(`Module disabled: ${name}`);\r\n}\r\n\r\nexport function onServiceEnabled(name: string) {\r\n console.log(`Service enabled: ${name}`);\r\n}\r\n\r\nexport function onServiceDisabled(name: string) {\r\n console.log(`Service disabled: ${name}`);\r\n}\r\n\r\nexport function onTemplateSelect(type: TemplateType, name: string) {\r\n console.log(`Template selected: type=${type}, name=${name}`);\r\n}\r\n\r\n// --- REGISTER HOOKS FOR MODULES ---\r\n\r\nexport async function registerEvents() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const eventsFile = path.join(paths.modules, mod.lowerName, 'events.server.js');\r\n if (fs.existsSync(eventsFile)) {\r\n const modEvents = await import(eventsFile);\r\n if (modEvents?.registerEvents) await modEvents.registerEvents();\r\n }\r\n }\r\n}\r\n\r\nexport async function registerMiddleware() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const middlewareFile = path.join(paths.modules, mod.lowerName, 'middleware.server.js');\r\n if (fs.existsSync(middlewareFile)) {\r\n const modMiddleware = await import(middlewareFile);\r\n if (modMiddleware?.registerMiddleware) await modMiddleware.registerMiddleware();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Registers routes given a path to routes folder (for pages and API routes)\r\n * @param routesFolderPath string - path to module/service routes folder\r\n */\r\nexport async function registerRoutes(routesFolderPath: string) {\r\n if (!fs.existsSync(routesFolderPath)) return;\r\n\r\n const routeFiles = fs.readdirSync(routesFolderPath).filter((f: any) => /\\.(js|ts|tsx)$/.test(f));\r\n for (const file of routeFiles) {\r\n const routeModule = await import(path.join(routesFolderPath, file));\r\n if (routeModule?.registerRoute) {\r\n await routeModule.registerRoute();\r\n }\r\n }\r\n}\r\n\r\nexport async function loadProviders() {\r\n const all = [\r\n { type: 'module', list: getModules(), basePath: paths.modules },\r\n { type: 'service', list: getServices(), basePath: paths.services }\r\n ];\r\n\r\n for (const { type, list, basePath } of all) {\r\n for (const item of list) {\r\n if (!item.enabled) continue;\r\n\r\n const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n const meta = loadJSON(metaPath);\r\n if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n for (const providerRelPath of meta.providers) {\r\n try {\r\n const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerModule = await import(providerPath);\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default(); // Call provider\r\n console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n } else {\r\n console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n }\r\n } catch (err) {\r\n console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\n\r\n/**\r\n * Register a dynamic route from a module/service.\r\n */\r\nexport function registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n}\r\n\r\n/**\r\n * Return all registered dynamic routes.\r\n */\r\nexport function getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n}\r\n\r\n/**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\nexport async function mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from '../hooks/useSettings';\r\n\r\nexport async function loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n}\r\n"],"mappings":"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","names":["extensiblePaths","fs","path","paths","path","fs","import_fs","path","fs","import_fs","path","fs","import_fs_extra","fs","path","import_path","import_url","import_fs_extra","path","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/hooks/useExtensibles.ts","../src/core/hooks/useSettings.ts","../src/core/hooks/useModules.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTemplates.ts","../src/core/hooks/useEvents.ts","../src/core/hooks/useRoutes.ts","../src/core/hooks/useUtils.ts","../src/core/providers/ThemeProvider.tsx"],"sourcesContent":["// src/index.ts\r\n\r\n// export * from './core/controller/EventController';\r\n// export * from './core/controller/MiddlewareController';\r\nexport * from './core/hooks/useExtensibles';\r\nexport * from './core/hooks/useSettings';\r\nexport * from './core/hooks/useModules';\r\nexport * from './core/hooks/useServices';\r\nexport * from './core/hooks/useTemplates';\r\nexport * from './core/hooks/useEvents';\r\nexport * from './core/hooks/useRoutes';\r\nexport * from './core/hooks/useUtils';\r\n// export * as ThemeProvider from './core/providers/ThemeProvider';\r\nexport * from './core/providers/ThemeProvider';\r\n","// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\n\r\nexport type TemplateType = 'admin-theme' | 'client-theme' | 'portal' | 'email';\r\n\r\nexport interface ExtensibleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n description?: string;\r\n author?: string;\r\n icon?: string;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface ExtensiblePaths {\r\n modules: string;\r\n templates: string;\r\n services: string;\r\n events: string;\r\n}\r\n\r\nlet paths: ExtensiblePaths;\r\n\r\nexport function registerExtensibles(extensiblePaths: ExtensiblePaths) {\r\n paths = extensiblePaths;\r\n}\r\n\r\nexport function loadJSON(filePath: string): any {\r\n if (!fs.existsSync(filePath)) return null;\r\n return JSON.parse(fs.readFileSync(filePath, 'utf-8'));\r\n}\r\n\r\nexport function saveJSON(filePath: string, data: any) {\r\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\r\n}\r\n\r\n// --- MODULES ---\r\n\r\nexport function getModules(): ExtensibleMeta[] {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.modules)\r\n .filter((d: any) => fs.statSync(path.join(paths.modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.modules, dir, 'module.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isModuleEnabled(name: string) {\r\n const modules = getModules();\r\n return modules.find((m) => m.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleModule(name: string, enabled: boolean) {\r\n const modules = getModules();\r\n const mod = modules.find((m) => m.lowerName === name.toLowerCase());\r\n if (!mod) throw new Error(`Module ${name} not found`);\r\n\r\n const metaPath = path.join(paths.modules, mod.lowerName, 'module.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onModuleEnabled(mod.name);\r\n else onModuleDisabled(mod.name);\r\n}\r\n\r\n// --- SERVICES ---\r\n\r\nexport function getServices(): ExtensibleMeta[] {\r\n if (!paths?.services) throw new Error('Services path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.services)\r\n .filter((d: any) => fs.statSync(path.join(paths.services, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.services, dir, 'service.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isServiceEnabled(name: string) {\r\n const services = getServices();\r\n return services.find((s) => s.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleService(name: string, enabled: boolean) {\r\n const services = getServices();\r\n const svc = services.find((s) => s.lowerName === name.toLowerCase());\r\n if (!svc) throw new Error(`Service ${name} not found`);\r\n\r\n const metaPath = path.join(paths.services, svc.lowerName, 'service.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onServiceEnabled(svc.name);\r\n else onServiceDisabled(svc.name);\r\n}\r\n\r\n// --- TEMPLATES ---\r\n\r\n// Helper to get base path for a template type\r\nfunction getTemplateBasePath(type: TemplateType): string {\r\n if (!paths?.templates) throw new Error('Templates path not registered.');\r\n switch (type) {\r\n case 'admin-theme':\r\n case 'client-theme':\r\n return path.join(paths.templates, 'themes');\r\n case 'portal':\r\n return path.join(paths.templates, 'portals');\r\n case 'email':\r\n return path.join(paths.templates, 'emails');\r\n default:\r\n throw new Error(`Unknown template type: ${type}`);\r\n }\r\n}\r\n\r\nexport function getTemplates(type: TemplateType): ExtensibleMeta[] {\r\n const basePath = getTemplateBasePath(type);\r\n if (!fs.existsSync(basePath)) return [];\r\n\r\n const dirs = fs\r\n .readdirSync(basePath)\r\n .filter((d: any) => fs.statSync(path.join(basePath, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(basePath, dir, 'template.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isTemplateActive(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n return templates.find((t) => t.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\n// Toggle templates: only 1 active per type allowed\r\nexport function toggleTemplate(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n\r\n templates.forEach((tpl) => {\r\n const metaPath = path.join(getTemplateBasePath(type), tpl.lowerName, 'template.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = tpl.lowerName === name.toLowerCase();\r\n saveJSON(metaPath, meta);\r\n });\r\n\r\n onTemplateSelect(type, name);\r\n}\r\n\r\n// --- EVENTS (replace with your event system integration) ---\r\n\r\nexport function onModuleEnabled(name: string) {\r\n console.log(`Module enabled: ${name}`);\r\n // emit event or custom logic here\r\n}\r\n\r\nexport function onModuleDisabled(name: string) {\r\n console.log(`Module disabled: ${name}`);\r\n}\r\n\r\nexport function onServiceEnabled(name: string) {\r\n console.log(`Service enabled: ${name}`);\r\n}\r\n\r\nexport function onServiceDisabled(name: string) {\r\n console.log(`Service disabled: ${name}`);\r\n}\r\n\r\nexport function onTemplateSelect(type: TemplateType, name: string) {\r\n console.log(`Template selected: type=${type}, name=${name}`);\r\n}\r\n\r\n// --- REGISTER HOOKS FOR MODULES ---\r\n\r\nexport async function registerEvents() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const eventsFile = path.join(paths.modules, mod.lowerName, 'events.server.js');\r\n if (fs.existsSync(eventsFile)) {\r\n const modEvents = await import(eventsFile);\r\n if (modEvents?.registerEvents) await modEvents.registerEvents();\r\n }\r\n }\r\n}\r\n\r\nexport async function registerMiddleware() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const middlewareFile = path.join(paths.modules, mod.lowerName, 'middleware.server.js');\r\n if (fs.existsSync(middlewareFile)) {\r\n const modMiddleware = await import(middlewareFile);\r\n if (modMiddleware?.registerMiddleware) await modMiddleware.registerMiddleware();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Registers routes given a path to routes folder (for pages and API routes)\r\n * @param routesFolderPath string - path to module/service routes folder\r\n */\r\nexport async function registerRoutes(routesFolderPath: string) {\r\n if (!fs.existsSync(routesFolderPath)) return;\r\n\r\n const routeFiles = fs.readdirSync(routesFolderPath).filter((f: any) => /\\.(js|ts|tsx)$/.test(f));\r\n for (const file of routeFiles) {\r\n const routeModule = await import(path.join(routesFolderPath, file));\r\n if (routeModule?.registerRoute) {\r\n await routeModule.registerRoute();\r\n }\r\n }\r\n}\r\n\r\nexport async function loadProviders() {\r\n const all = [\r\n { type: 'module', list: getModules(), basePath: paths.modules },\r\n { type: 'service', list: getServices(), basePath: paths.services }\r\n ];\r\n\r\n for (const { type, list, basePath } of all) {\r\n for (const item of list) {\r\n if (!item.enabled) continue;\r\n\r\n const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n const meta = loadJSON(metaPath);\r\n if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n for (const providerRelPath of meta.providers) {\r\n try {\r\n const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerModule = await import(providerPath);\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default(); // Call provider\r\n console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n } else {\r\n console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n }\r\n } catch (err) {\r\n console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\nexport const routesManager = {\r\n /**\r\n * Register a dynamic route from a module/service.\r\n */\r\n registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n },\r\n\r\n /**\r\n * Return all registered dynamic routes.\r\n */\r\n getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n },\r\n\r\n /**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\n async mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport const useUtils = {\r\n async loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n ): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["extensiblePaths","fs","path","paths","path","fs","import_fs","path","fs","import_fs","path","fs","import_fs_extra","fs","path","import_path","import_url","import_fs_extra","path","fs"]}
package/dist/index.d.cts CHANGED
@@ -108,25 +108,34 @@ interface RouteDefinition {
108
108
  method: 'get' | 'post' | 'put' | 'patch' | 'delete';
109
109
  filePath: string;
110
110
  }
111
- /**
112
- * Register a dynamic route from a module/service.
113
- */
114
- declare function registerRoute(def: RouteDefinition): void;
115
- /**
116
- * Return all registered dynamic routes.
117
- */
118
- declare function getRegisteredRoutes(): RouteDefinition[];
119
- /**
120
- * Loads and mounts all registered dynamic routes into an Express app.
121
- */
122
- declare function mountRegisteredRoutes(app: Application): Promise<void>;
111
+ declare const routesManager: {
112
+ /**
113
+ * Register a dynamic route from a module/service.
114
+ */
115
+ registerRoute(def: RouteDefinition): void;
116
+ /**
117
+ * Return all registered dynamic routes.
118
+ */
119
+ getRegisteredRoutes(): RouteDefinition[];
120
+ /**
121
+ * Loads and mounts all registered dynamic routes into an Express app.
122
+ */
123
+ mountRegisteredRoutes(app: Application): Promise<void>;
124
+ };
123
125
 
124
- declare const useRoutes_getRegisteredRoutes: typeof getRegisteredRoutes;
125
- declare const useRoutes_mountRegisteredRoutes: typeof mountRegisteredRoutes;
126
- declare const useRoutes_registerRoute: typeof registerRoute;
127
- declare namespace useRoutes {
128
- export { useRoutes_getRegisteredRoutes as getRegisteredRoutes, useRoutes_mountRegisteredRoutes as mountRegisteredRoutes, useRoutes_registerRoute as registerRoute };
129
- }
126
+ declare const useUtils: {
127
+ loadThemeComponent(componentName: string, options: {
128
+ theme: {
129
+ name: string;
130
+ type: "admin" | "client" | "portal" | "email";
131
+ };
132
+ search?: {
133
+ themes?: boolean;
134
+ modules?: boolean;
135
+ services?: boolean;
136
+ };
137
+ }): Promise<React.ComponentType<any> | null>;
138
+ };
130
139
 
131
140
  interface ThemeContextProps {
132
141
  templateType: TemplateType;
@@ -139,21 +148,4 @@ declare const ThemeProvider: React$1.FC<{
139
148
  }>;
140
149
  declare function useTheme(): ThemeContextProps;
141
150
 
142
- declare function loadThemeComponent(componentName: string, options: {
143
- theme: {
144
- name: string;
145
- type: 'admin' | 'client' | 'portal' | 'email';
146
- };
147
- search?: {
148
- themes?: boolean;
149
- modules?: boolean;
150
- services?: boolean;
151
- };
152
- }): Promise<React.ComponentType<any> | null>;
153
-
154
- declare const loadThemeComponent$1_loadThemeComponent: typeof loadThemeComponent;
155
- declare namespace loadThemeComponent$1 {
156
- export { loadThemeComponent$1_loadThemeComponent as loadThemeComponent };
157
- }
158
-
159
- export { type ExtensibleMeta, type ExtensiblePaths, type ModuleMeta, useRoutes as RouteManager, type ServiceMeta, type TemplateMeta, type TemplateType, ThemeProvider, getModules, getServices, getTemplates, isModuleEnabled, isServiceEnabled, isTemplateActive, loadJSON, loadProviders, onModuleDisabled, onModuleEnabled, onServiceDisabled, onServiceEnabled, onTemplateSelect, registerEvents, registerExtensibles, registerMiddleware, registerRoutes, saveJSON, toggleModule, toggleService, toggleTemplate, useEvents, useModules, useServices, useSettings, useTemplates, useTheme, loadThemeComponent$1 as utils };
151
+ export { type ExtensibleMeta, type ExtensiblePaths, type ModuleMeta, type ServiceMeta, type TemplateMeta, type TemplateType, ThemeProvider, getModules, getServices, getTemplates, isModuleEnabled, isServiceEnabled, isTemplateActive, loadJSON, loadProviders, onModuleDisabled, onModuleEnabled, onServiceDisabled, onServiceEnabled, onTemplateSelect, registerEvents, registerExtensibles, registerMiddleware, registerRoutes, routesManager, saveJSON, toggleModule, toggleService, toggleTemplate, useEvents, useModules, useServices, useSettings, useTemplates, useTheme, useUtils };
package/dist/index.d.ts CHANGED
@@ -108,25 +108,34 @@ interface RouteDefinition {
108
108
  method: 'get' | 'post' | 'put' | 'patch' | 'delete';
109
109
  filePath: string;
110
110
  }
111
- /**
112
- * Register a dynamic route from a module/service.
113
- */
114
- declare function registerRoute(def: RouteDefinition): void;
115
- /**
116
- * Return all registered dynamic routes.
117
- */
118
- declare function getRegisteredRoutes(): RouteDefinition[];
119
- /**
120
- * Loads and mounts all registered dynamic routes into an Express app.
121
- */
122
- declare function mountRegisteredRoutes(app: Application): Promise<void>;
111
+ declare const routesManager: {
112
+ /**
113
+ * Register a dynamic route from a module/service.
114
+ */
115
+ registerRoute(def: RouteDefinition): void;
116
+ /**
117
+ * Return all registered dynamic routes.
118
+ */
119
+ getRegisteredRoutes(): RouteDefinition[];
120
+ /**
121
+ * Loads and mounts all registered dynamic routes into an Express app.
122
+ */
123
+ mountRegisteredRoutes(app: Application): Promise<void>;
124
+ };
123
125
 
124
- declare const useRoutes_getRegisteredRoutes: typeof getRegisteredRoutes;
125
- declare const useRoutes_mountRegisteredRoutes: typeof mountRegisteredRoutes;
126
- declare const useRoutes_registerRoute: typeof registerRoute;
127
- declare namespace useRoutes {
128
- export { useRoutes_getRegisteredRoutes as getRegisteredRoutes, useRoutes_mountRegisteredRoutes as mountRegisteredRoutes, useRoutes_registerRoute as registerRoute };
129
- }
126
+ declare const useUtils: {
127
+ loadThemeComponent(componentName: string, options: {
128
+ theme: {
129
+ name: string;
130
+ type: "admin" | "client" | "portal" | "email";
131
+ };
132
+ search?: {
133
+ themes?: boolean;
134
+ modules?: boolean;
135
+ services?: boolean;
136
+ };
137
+ }): Promise<React.ComponentType<any> | null>;
138
+ };
130
139
 
131
140
  interface ThemeContextProps {
132
141
  templateType: TemplateType;
@@ -139,21 +148,4 @@ declare const ThemeProvider: React$1.FC<{
139
148
  }>;
140
149
  declare function useTheme(): ThemeContextProps;
141
150
 
142
- declare function loadThemeComponent(componentName: string, options: {
143
- theme: {
144
- name: string;
145
- type: 'admin' | 'client' | 'portal' | 'email';
146
- };
147
- search?: {
148
- themes?: boolean;
149
- modules?: boolean;
150
- services?: boolean;
151
- };
152
- }): Promise<React.ComponentType<any> | null>;
153
-
154
- declare const loadThemeComponent$1_loadThemeComponent: typeof loadThemeComponent;
155
- declare namespace loadThemeComponent$1 {
156
- export { loadThemeComponent$1_loadThemeComponent as loadThemeComponent };
157
- }
158
-
159
- export { type ExtensibleMeta, type ExtensiblePaths, type ModuleMeta, useRoutes as RouteManager, type ServiceMeta, type TemplateMeta, type TemplateType, ThemeProvider, getModules, getServices, getTemplates, isModuleEnabled, isServiceEnabled, isTemplateActive, loadJSON, loadProviders, onModuleDisabled, onModuleEnabled, onServiceDisabled, onServiceEnabled, onTemplateSelect, registerEvents, registerExtensibles, registerMiddleware, registerRoutes, saveJSON, toggleModule, toggleService, toggleTemplate, useEvents, useModules, useServices, useSettings, useTemplates, useTheme, loadThemeComponent$1 as utils };
151
+ export { type ExtensibleMeta, type ExtensiblePaths, type ModuleMeta, type ServiceMeta, type TemplateMeta, type TemplateType, ThemeProvider, getModules, getServices, getTemplates, isModuleEnabled, isServiceEnabled, isTemplateActive, loadJSON, loadProviders, onModuleDisabled, onModuleEnabled, onServiceDisabled, onServiceEnabled, onTemplateSelect, registerEvents, registerExtensibles, registerMiddleware, registerRoutes, routesManager, saveJSON, toggleModule, toggleService, toggleTemplate, useEvents, useModules, useServices, useSettings, useTemplates, useTheme, useUtils };
package/dist/index.js CHANGED
@@ -1,9 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
1
  // src/core/hooks/useExtensibles.ts
8
2
  import fs from "fs-extra";
9
3
  import * as path from "path";
@@ -424,110 +418,71 @@ async function useEvents(io) {
424
418
  }
425
419
 
426
420
  // src/core/hooks/useRoutes.ts
427
- var useRoutes_exports = {};
428
- __export(useRoutes_exports, {
429
- getRegisteredRoutes: () => getRegisteredRoutes,
430
- mountRegisteredRoutes: () => mountRegisteredRoutes,
431
- registerRoute: () => registerRoute
432
- });
433
421
  import { pathToFileURL } from "url";
434
422
  var registeredRoutes = [];
435
- function registerRoute(def) {
436
- registeredRoutes.push(def);
437
- }
438
- function getRegisteredRoutes() {
439
- return registeredRoutes;
440
- }
441
- async function mountRegisteredRoutes(app) {
442
- for (const route of registeredRoutes) {
443
- const mod = await import(pathToFileURL(route.filePath).toString());
444
- const hasLoader = typeof mod.loader === "function";
445
- const hasAction = typeof mod.action === "function";
446
- const hasDefault = typeof mod.default !== "undefined";
447
- if (!hasDefault && (hasLoader || hasAction)) {
448
- app[route.method](route.path, async (req, res, next) => {
449
- try {
450
- if (route.method === "get" && hasLoader) {
451
- const result = await mod.loader({ request: req });
452
- res.json(result);
453
- } else if (hasAction) {
454
- const result = await mod.action({ request: req });
455
- res.json(result);
456
- } else {
457
- res.status(405).json({ error: "Method Not Allowed" });
423
+ var routesManager = {
424
+ /**
425
+ * Register a dynamic route from a module/service.
426
+ */
427
+ registerRoute(def) {
428
+ registeredRoutes.push(def);
429
+ },
430
+ /**
431
+ * Return all registered dynamic routes.
432
+ */
433
+ getRegisteredRoutes() {
434
+ return registeredRoutes;
435
+ },
436
+ /**
437
+ * Loads and mounts all registered dynamic routes into an Express app.
438
+ */
439
+ async mountRegisteredRoutes(app) {
440
+ for (const route of registeredRoutes) {
441
+ const mod = await import(pathToFileURL(route.filePath).toString());
442
+ const hasLoader = typeof mod.loader === "function";
443
+ const hasAction = typeof mod.action === "function";
444
+ const hasDefault = typeof mod.default !== "undefined";
445
+ if (!hasDefault && (hasLoader || hasAction)) {
446
+ app[route.method](route.path, async (req, res, next) => {
447
+ try {
448
+ if (route.method === "get" && hasLoader) {
449
+ const result = await mod.loader({ request: req });
450
+ res.json(result);
451
+ } else if (hasAction) {
452
+ const result = await mod.action({ request: req });
453
+ res.json(result);
454
+ } else {
455
+ res.status(405).json({ error: "Method Not Allowed" });
456
+ }
457
+ } catch (err) {
458
+ next(err);
458
459
  }
459
- } catch (err) {
460
- next(err);
461
- }
462
- });
463
- } else if (hasDefault) {
464
- app.use(route.path, (req, res, next) => {
465
- res.locals.__dynamicPageComponent = mod.default;
466
- next();
467
- });
460
+ });
461
+ } else if (hasDefault) {
462
+ app.use(route.path, (req, res, next) => {
463
+ res.locals.__dynamicPageComponent = mod.default;
464
+ next();
465
+ });
466
+ }
468
467
  }
469
468
  }
470
- }
471
-
472
- // src/core/providers/ThemeProvider.tsx
473
- import { createContext, useContext, useState } from "react";
474
- import { jsx } from "react/jsx-runtime";
475
- var ThemeContext = createContext(null);
476
- var ThemeProvider = ({ type, children }) => {
477
- const [activeTheme, setActiveTheme] = useState(() => {
478
- const templates = getTemplates(type);
479
- const enabled = templates.find((t) => t.enabled);
480
- return enabled?.lowerName ?? templates[0]?.lowerName ?? "default";
481
- });
482
- return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: { templateType: type, activeTheme, setActiveTheme }, children });
483
469
  };
484
- function useTheme() {
485
- const ctx = useContext(ThemeContext);
486
- if (!ctx) throw new Error("useTheme must be used inside a ThemeProvider");
487
- return ctx;
488
- }
489
470
 
490
- // src/core/utils/loadThemeComponent.ts
491
- var loadThemeComponent_exports = {};
492
- __export(loadThemeComponent_exports, {
493
- loadThemeComponent: () => loadThemeComponent
494
- });
471
+ // src/core/hooks/useUtils.ts
495
472
  import path7 from "path";
496
473
  import { pathToFileURL as pathToFileURL2 } from "url";
497
474
  import fs6 from "fs-extra";
498
- async function loadThemeComponent(componentName, options) {
499
- const { search = {}, theme } = options;
500
- const searchThemes = search.themes ?? true;
501
- const searchModules = search.modules ?? true;
502
- const searchServices = search.services ?? true;
503
- const possiblePaths = [];
504
- if (searchThemes) {
505
- possiblePaths.push(
506
- path7.resolve(
507
- "resources",
508
- "themes",
509
- theme.type,
510
- theme.name,
511
- "routes",
512
- `${componentName}.tsx`
513
- ),
514
- path7.resolve(
515
- "resources",
516
- "themes",
517
- theme.type,
518
- theme.name,
519
- "components",
520
- `${componentName}.tsx`
521
- )
522
- );
523
- }
524
- if (searchModules) {
525
- const moduleDirs = await fs6.readdir(useSettings.getPaths().modules);
526
- for (const mod of moduleDirs) {
475
+ var useUtils = {
476
+ async loadThemeComponent(componentName, options) {
477
+ const { search = {}, theme } = options;
478
+ const searchThemes = search.themes ?? true;
479
+ const searchModules = search.modules ?? true;
480
+ const searchServices = search.services ?? true;
481
+ const possiblePaths = [];
482
+ if (searchThemes) {
527
483
  possiblePaths.push(
528
484
  path7.resolve(
529
- "modules",
530
- mod,
485
+ "resources",
531
486
  "themes",
532
487
  theme.type,
533
488
  theme.name,
@@ -535,8 +490,7 @@ async function loadThemeComponent(componentName, options) {
535
490
  `${componentName}.tsx`
536
491
  ),
537
492
  path7.resolve(
538
- "modules",
539
- mod,
493
+ "resources",
540
494
  "themes",
541
495
  theme.type,
542
496
  theme.name,
@@ -545,47 +499,89 @@ async function loadThemeComponent(componentName, options) {
545
499
  )
546
500
  );
547
501
  }
548
- }
549
- if (searchServices) {
550
- const serviceDirs = await fs6.readdir(useSettings.getPaths().services);
551
- for (const svc of serviceDirs) {
552
- possiblePaths.push(
553
- path7.resolve(
554
- "services",
555
- svc,
556
- "themes",
557
- theme.type,
558
- theme.name,
559
- "routes",
560
- `${componentName}.tsx`
561
- ),
562
- path7.resolve(
563
- "services",
564
- svc,
565
- "themes",
566
- theme.type,
567
- theme.name,
568
- "components",
569
- `${componentName}.tsx`
570
- )
571
- );
502
+ if (searchModules) {
503
+ const moduleDirs = await fs6.readdir(useSettings.getPaths().modules);
504
+ for (const mod of moduleDirs) {
505
+ possiblePaths.push(
506
+ path7.resolve(
507
+ "modules",
508
+ mod,
509
+ "themes",
510
+ theme.type,
511
+ theme.name,
512
+ "routes",
513
+ `${componentName}.tsx`
514
+ ),
515
+ path7.resolve(
516
+ "modules",
517
+ mod,
518
+ "themes",
519
+ theme.type,
520
+ theme.name,
521
+ "components",
522
+ `${componentName}.tsx`
523
+ )
524
+ );
525
+ }
572
526
  }
573
- }
574
- for (const filePath of possiblePaths) {
575
- if (await fs6.pathExists(filePath)) {
576
- try {
577
- const mod = await import(pathToFileURL2(filePath).toString());
578
- if (mod.default) return mod.default;
579
- } catch (err) {
580
- console.error(`Error loading component at ${filePath}:`, err);
527
+ if (searchServices) {
528
+ const serviceDirs = await fs6.readdir(useSettings.getPaths().services);
529
+ for (const svc of serviceDirs) {
530
+ possiblePaths.push(
531
+ path7.resolve(
532
+ "services",
533
+ svc,
534
+ "themes",
535
+ theme.type,
536
+ theme.name,
537
+ "routes",
538
+ `${componentName}.tsx`
539
+ ),
540
+ path7.resolve(
541
+ "services",
542
+ svc,
543
+ "themes",
544
+ theme.type,
545
+ theme.name,
546
+ "components",
547
+ `${componentName}.tsx`
548
+ )
549
+ );
550
+ }
551
+ }
552
+ for (const filePath of possiblePaths) {
553
+ if (await fs6.pathExists(filePath)) {
554
+ try {
555
+ const mod = await import(pathToFileURL2(filePath).toString());
556
+ if (mod.default) return mod.default;
557
+ } catch (err) {
558
+ console.error(`Error loading component at ${filePath}:`, err);
559
+ }
581
560
  }
582
561
  }
562
+ console.warn(`Component "${componentName}" not found in theme "${theme.name}" of type "${theme.type}".`);
563
+ return null;
583
564
  }
584
- console.warn(`Component "${componentName}" not found in theme "${theme.name}" of type "${theme.type}".`);
585
- return null;
565
+ };
566
+
567
+ // src/core/providers/ThemeProvider.tsx
568
+ import { createContext, useContext, useState } from "react";
569
+ import { jsx } from "react/jsx-runtime";
570
+ var ThemeContext = createContext(null);
571
+ var ThemeProvider = ({ type, children }) => {
572
+ const [activeTheme, setActiveTheme] = useState(() => {
573
+ const templates = getTemplates(type);
574
+ const enabled = templates.find((t) => t.enabled);
575
+ return enabled?.lowerName ?? templates[0]?.lowerName ?? "default";
576
+ });
577
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: { templateType: type, activeTheme, setActiveTheme }, children });
578
+ };
579
+ function useTheme() {
580
+ const ctx = useContext(ThemeContext);
581
+ if (!ctx) throw new Error("useTheme must be used inside a ThemeProvider");
582
+ return ctx;
586
583
  }
587
584
  export {
588
- useRoutes_exports as RouteManager,
589
585
  ThemeProvider,
590
586
  getModules,
591
587
  getServices,
@@ -604,6 +600,7 @@ export {
604
600
  registerExtensibles,
605
601
  registerMiddleware,
606
602
  registerRoutes,
603
+ routesManager,
607
604
  saveJSON,
608
605
  toggleModule,
609
606
  toggleService,
@@ -614,6 +611,6 @@ export {
614
611
  useSettings,
615
612
  useTemplates,
616
613
  useTheme,
617
- loadThemeComponent_exports as utils
614
+ useUtils
618
615
  };
619
616
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/hooks/useExtensibles.ts","../src/core/hooks/useSettings.ts","../src/core/hooks/useModules.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTemplates.ts","../src/core/hooks/useEvents.ts","../src/core/hooks/useRoutes.ts","../src/core/providers/ThemeProvider.tsx","../src/core/utils/loadThemeComponent.ts"],"sourcesContent":["// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\n\r\nexport type TemplateType = 'admin-theme' | 'client-theme' | 'portal' | 'email';\r\n\r\nexport interface ExtensibleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n description?: string;\r\n author?: string;\r\n icon?: string;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface ExtensiblePaths {\r\n modules: string;\r\n templates: string;\r\n services: string;\r\n events: string;\r\n}\r\n\r\nlet paths: ExtensiblePaths;\r\n\r\nexport function registerExtensibles(extensiblePaths: ExtensiblePaths) {\r\n paths = extensiblePaths;\r\n}\r\n\r\nexport function loadJSON(filePath: string): any {\r\n if (!fs.existsSync(filePath)) return null;\r\n return JSON.parse(fs.readFileSync(filePath, 'utf-8'));\r\n}\r\n\r\nexport function saveJSON(filePath: string, data: any) {\r\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\r\n}\r\n\r\n// --- MODULES ---\r\n\r\nexport function getModules(): ExtensibleMeta[] {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.modules)\r\n .filter((d: any) => fs.statSync(path.join(paths.modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.modules, dir, 'module.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isModuleEnabled(name: string) {\r\n const modules = getModules();\r\n return modules.find((m) => m.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleModule(name: string, enabled: boolean) {\r\n const modules = getModules();\r\n const mod = modules.find((m) => m.lowerName === name.toLowerCase());\r\n if (!mod) throw new Error(`Module ${name} not found`);\r\n\r\n const metaPath = path.join(paths.modules, mod.lowerName, 'module.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onModuleEnabled(mod.name);\r\n else onModuleDisabled(mod.name);\r\n}\r\n\r\n// --- SERVICES ---\r\n\r\nexport function getServices(): ExtensibleMeta[] {\r\n if (!paths?.services) throw new Error('Services path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.services)\r\n .filter((d: any) => fs.statSync(path.join(paths.services, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.services, dir, 'service.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isServiceEnabled(name: string) {\r\n const services = getServices();\r\n return services.find((s) => s.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleService(name: string, enabled: boolean) {\r\n const services = getServices();\r\n const svc = services.find((s) => s.lowerName === name.toLowerCase());\r\n if (!svc) throw new Error(`Service ${name} not found`);\r\n\r\n const metaPath = path.join(paths.services, svc.lowerName, 'service.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onServiceEnabled(svc.name);\r\n else onServiceDisabled(svc.name);\r\n}\r\n\r\n// --- TEMPLATES ---\r\n\r\n// Helper to get base path for a template type\r\nfunction getTemplateBasePath(type: TemplateType): string {\r\n if (!paths?.templates) throw new Error('Templates path not registered.');\r\n switch (type) {\r\n case 'admin-theme':\r\n case 'client-theme':\r\n return path.join(paths.templates, 'themes');\r\n case 'portal':\r\n return path.join(paths.templates, 'portals');\r\n case 'email':\r\n return path.join(paths.templates, 'emails');\r\n default:\r\n throw new Error(`Unknown template type: ${type}`);\r\n }\r\n}\r\n\r\nexport function getTemplates(type: TemplateType): ExtensibleMeta[] {\r\n const basePath = getTemplateBasePath(type);\r\n if (!fs.existsSync(basePath)) return [];\r\n\r\n const dirs = fs\r\n .readdirSync(basePath)\r\n .filter((d: any) => fs.statSync(path.join(basePath, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(basePath, dir, 'template.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isTemplateActive(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n return templates.find((t) => t.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\n// Toggle templates: only 1 active per type allowed\r\nexport function toggleTemplate(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n\r\n templates.forEach((tpl) => {\r\n const metaPath = path.join(getTemplateBasePath(type), tpl.lowerName, 'template.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = tpl.lowerName === name.toLowerCase();\r\n saveJSON(metaPath, meta);\r\n });\r\n\r\n onTemplateSelect(type, name);\r\n}\r\n\r\n// --- EVENTS (replace with your event system integration) ---\r\n\r\nexport function onModuleEnabled(name: string) {\r\n console.log(`Module enabled: ${name}`);\r\n // emit event or custom logic here\r\n}\r\n\r\nexport function onModuleDisabled(name: string) {\r\n console.log(`Module disabled: ${name}`);\r\n}\r\n\r\nexport function onServiceEnabled(name: string) {\r\n console.log(`Service enabled: ${name}`);\r\n}\r\n\r\nexport function onServiceDisabled(name: string) {\r\n console.log(`Service disabled: ${name}`);\r\n}\r\n\r\nexport function onTemplateSelect(type: TemplateType, name: string) {\r\n console.log(`Template selected: type=${type}, name=${name}`);\r\n}\r\n\r\n// --- REGISTER HOOKS FOR MODULES ---\r\n\r\nexport async function registerEvents() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const eventsFile = path.join(paths.modules, mod.lowerName, 'events.server.js');\r\n if (fs.existsSync(eventsFile)) {\r\n const modEvents = await import(eventsFile);\r\n if (modEvents?.registerEvents) await modEvents.registerEvents();\r\n }\r\n }\r\n}\r\n\r\nexport async function registerMiddleware() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const middlewareFile = path.join(paths.modules, mod.lowerName, 'middleware.server.js');\r\n if (fs.existsSync(middlewareFile)) {\r\n const modMiddleware = await import(middlewareFile);\r\n if (modMiddleware?.registerMiddleware) await modMiddleware.registerMiddleware();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Registers routes given a path to routes folder (for pages and API routes)\r\n * @param routesFolderPath string - path to module/service routes folder\r\n */\r\nexport async function registerRoutes(routesFolderPath: string) {\r\n if (!fs.existsSync(routesFolderPath)) return;\r\n\r\n const routeFiles = fs.readdirSync(routesFolderPath).filter((f: any) => /\\.(js|ts|tsx)$/.test(f));\r\n for (const file of routeFiles) {\r\n const routeModule = await import(path.join(routesFolderPath, file));\r\n if (routeModule?.registerRoute) {\r\n await routeModule.registerRoute();\r\n }\r\n }\r\n}\r\n\r\nexport async function loadProviders() {\r\n const all = [\r\n { type: 'module', list: getModules(), basePath: paths.modules },\r\n { type: 'service', list: getServices(), basePath: paths.services }\r\n ];\r\n\r\n for (const { type, list, basePath } of all) {\r\n for (const item of list) {\r\n if (!item.enabled) continue;\r\n\r\n const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n const meta = loadJSON(metaPath);\r\n if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n for (const providerRelPath of meta.providers) {\r\n try {\r\n const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerModule = await import(providerPath);\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default(); // Call provider\r\n console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n } else {\r\n console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n }\r\n } catch (err) {\r\n console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\n\r\n/**\r\n * Register a dynamic route from a module/service.\r\n */\r\nexport function registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n}\r\n\r\n/**\r\n * Return all registered dynamic routes.\r\n */\r\nexport function getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n}\r\n\r\n/**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\nexport async function mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from '../hooks/useSettings';\r\n\r\nexport async function loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n}\r\n"],"mappings":"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","names":["extensiblePaths","path","paths","fs","path","fs","fs","path","fs","fs","path","fs","fs","path","fs","path","path","pathToFileURL","fs","path","fs","pathToFileURL"]}
1
+ {"version":3,"sources":["../src/core/hooks/useExtensibles.ts","../src/core/hooks/useSettings.ts","../src/core/hooks/useModules.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTemplates.ts","../src/core/hooks/useEvents.ts","../src/core/hooks/useRoutes.ts","../src/core/hooks/useUtils.ts","../src/core/providers/ThemeProvider.tsx"],"sourcesContent":["// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\n\r\nexport type TemplateType = 'admin-theme' | 'client-theme' | 'portal' | 'email';\r\n\r\nexport interface ExtensibleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n description?: string;\r\n author?: string;\r\n icon?: string;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface ExtensiblePaths {\r\n modules: string;\r\n templates: string;\r\n services: string;\r\n events: string;\r\n}\r\n\r\nlet paths: ExtensiblePaths;\r\n\r\nexport function registerExtensibles(extensiblePaths: ExtensiblePaths) {\r\n paths = extensiblePaths;\r\n}\r\n\r\nexport function loadJSON(filePath: string): any {\r\n if (!fs.existsSync(filePath)) return null;\r\n return JSON.parse(fs.readFileSync(filePath, 'utf-8'));\r\n}\r\n\r\nexport function saveJSON(filePath: string, data: any) {\r\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\r\n}\r\n\r\n// --- MODULES ---\r\n\r\nexport function getModules(): ExtensibleMeta[] {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.modules)\r\n .filter((d: any) => fs.statSync(path.join(paths.modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.modules, dir, 'module.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isModuleEnabled(name: string) {\r\n const modules = getModules();\r\n return modules.find((m) => m.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleModule(name: string, enabled: boolean) {\r\n const modules = getModules();\r\n const mod = modules.find((m) => m.lowerName === name.toLowerCase());\r\n if (!mod) throw new Error(`Module ${name} not found`);\r\n\r\n const metaPath = path.join(paths.modules, mod.lowerName, 'module.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onModuleEnabled(mod.name);\r\n else onModuleDisabled(mod.name);\r\n}\r\n\r\n// --- SERVICES ---\r\n\r\nexport function getServices(): ExtensibleMeta[] {\r\n if (!paths?.services) throw new Error('Services path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(paths.services)\r\n .filter((d: any) => fs.statSync(path.join(paths.services, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(paths.services, dir, 'service.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: meta.lowerName || dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isServiceEnabled(name: string) {\r\n const services = getServices();\r\n return services.find((s) => s.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\nexport function toggleService(name: string, enabled: boolean) {\r\n const services = getServices();\r\n const svc = services.find((s) => s.lowerName === name.toLowerCase());\r\n if (!svc) throw new Error(`Service ${name} not found`);\r\n\r\n const metaPath = path.join(paths.services, svc.lowerName, 'service.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = enabled;\r\n saveJSON(metaPath, meta);\r\n\r\n if (enabled) onServiceEnabled(svc.name);\r\n else onServiceDisabled(svc.name);\r\n}\r\n\r\n// --- TEMPLATES ---\r\n\r\n// Helper to get base path for a template type\r\nfunction getTemplateBasePath(type: TemplateType): string {\r\n if (!paths?.templates) throw new Error('Templates path not registered.');\r\n switch (type) {\r\n case 'admin-theme':\r\n case 'client-theme':\r\n return path.join(paths.templates, 'themes');\r\n case 'portal':\r\n return path.join(paths.templates, 'portals');\r\n case 'email':\r\n return path.join(paths.templates, 'emails');\r\n default:\r\n throw new Error(`Unknown template type: ${type}`);\r\n }\r\n}\r\n\r\nexport function getTemplates(type: TemplateType): ExtensibleMeta[] {\r\n const basePath = getTemplateBasePath(type);\r\n if (!fs.existsSync(basePath)) return [];\r\n\r\n const dirs = fs\r\n .readdirSync(basePath)\r\n .filter((d: any) => fs.statSync(path.join(basePath, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(basePath, dir, 'template.json')) || {};\r\n return {\r\n name: meta.name || dir,\r\n lowerName: dir.toLowerCase(),\r\n version: meta.version,\r\n description: meta.description,\r\n author: meta.author,\r\n icon: meta.icon,\r\n enabled: meta.enabled ?? false,\r\n };\r\n });\r\n}\r\n\r\nexport function isTemplateActive(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n return templates.find((t) => t.lowerName === name.toLowerCase())?.enabled ?? false;\r\n}\r\n\r\n// Toggle templates: only 1 active per type allowed\r\nexport function toggleTemplate(type: TemplateType, name: string) {\r\n const templates = getTemplates(type);\r\n\r\n templates.forEach((tpl) => {\r\n const metaPath = path.join(getTemplateBasePath(type), tpl.lowerName, 'template.json');\r\n const meta = loadJSON(metaPath) || {};\r\n meta.enabled = tpl.lowerName === name.toLowerCase();\r\n saveJSON(metaPath, meta);\r\n });\r\n\r\n onTemplateSelect(type, name);\r\n}\r\n\r\n// --- EVENTS (replace with your event system integration) ---\r\n\r\nexport function onModuleEnabled(name: string) {\r\n console.log(`Module enabled: ${name}`);\r\n // emit event or custom logic here\r\n}\r\n\r\nexport function onModuleDisabled(name: string) {\r\n console.log(`Module disabled: ${name}`);\r\n}\r\n\r\nexport function onServiceEnabled(name: string) {\r\n console.log(`Service enabled: ${name}`);\r\n}\r\n\r\nexport function onServiceDisabled(name: string) {\r\n console.log(`Service disabled: ${name}`);\r\n}\r\n\r\nexport function onTemplateSelect(type: TemplateType, name: string) {\r\n console.log(`Template selected: type=${type}, name=${name}`);\r\n}\r\n\r\n// --- REGISTER HOOKS FOR MODULES ---\r\n\r\nexport async function registerEvents() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const eventsFile = path.join(paths.modules, mod.lowerName, 'events.server.js');\r\n if (fs.existsSync(eventsFile)) {\r\n const modEvents = await import(eventsFile);\r\n if (modEvents?.registerEvents) await modEvents.registerEvents();\r\n }\r\n }\r\n}\r\n\r\nexport async function registerMiddleware() {\r\n if (!paths?.modules) throw new Error('Modules path not registered.');\r\n const modules = getModules().filter((m) => m.enabled);\r\n for (const mod of modules) {\r\n const middlewareFile = path.join(paths.modules, mod.lowerName, 'middleware.server.js');\r\n if (fs.existsSync(middlewareFile)) {\r\n const modMiddleware = await import(middlewareFile);\r\n if (modMiddleware?.registerMiddleware) await modMiddleware.registerMiddleware();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Registers routes given a path to routes folder (for pages and API routes)\r\n * @param routesFolderPath string - path to module/service routes folder\r\n */\r\nexport async function registerRoutes(routesFolderPath: string) {\r\n if (!fs.existsSync(routesFolderPath)) return;\r\n\r\n const routeFiles = fs.readdirSync(routesFolderPath).filter((f: any) => /\\.(js|ts|tsx)$/.test(f));\r\n for (const file of routeFiles) {\r\n const routeModule = await import(path.join(routesFolderPath, file));\r\n if (routeModule?.registerRoute) {\r\n await routeModule.registerRoute();\r\n }\r\n }\r\n}\r\n\r\nexport async function loadProviders() {\r\n const all = [\r\n { type: 'module', list: getModules(), basePath: paths.modules },\r\n { type: 'service', list: getServices(), basePath: paths.services }\r\n ];\r\n\r\n for (const { type, list, basePath } of all) {\r\n for (const item of list) {\r\n if (!item.enabled) continue;\r\n\r\n const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n const meta = loadJSON(metaPath);\r\n if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n for (const providerRelPath of meta.providers) {\r\n try {\r\n const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerModule = await import(providerPath);\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default(); // Call provider\r\n console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n } else {\r\n console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n }\r\n } catch (err) {\r\n console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\nexport const routesManager = {\r\n /**\r\n * Register a dynamic route from a module/service.\r\n */\r\n registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n },\r\n\r\n /**\r\n * Return all registered dynamic routes.\r\n */\r\n getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n },\r\n\r\n /**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\n async mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport const useUtils = {\r\n async loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n ): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["extensiblePaths","path","paths","fs","path","fs","fs","path","fs","fs","path","fs","fs","path","fs","path","path","pathToFileURL","fs","path","fs","pathToFileURL"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "retrex-extensibles-core",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "description": "The Core System for the New Upcoming Billing System Called retrex-Billing",
5
5
  "license": "ISC",
6
6
  "author": "",