retrex-extensibles-core 1.2.1 → 1.2.2

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
@@ -576,23 +576,23 @@ async function loadThemeComponent(componentName, options) {
576
576
  );
577
577
  }
578
578
  if (searchModules) {
579
- const moduleDirs = await import_fs_extra3.default.readdir("modules");
579
+ const moduleDirs = await import_fs_extra3.default.readdir(useSettings.getPaths().modules);
580
580
  for (const mod of moduleDirs) {
581
581
  possiblePaths.push(
582
582
  import_path2.default.resolve(
583
583
  "modules",
584
584
  mod,
585
585
  "themes",
586
- themeName,
587
586
  themeType,
587
+ themeName,
588
588
  `${componentName}.tsx`
589
589
  ),
590
590
  import_path2.default.resolve(
591
591
  "modules",
592
592
  mod,
593
593
  "themes",
594
- themeName,
595
594
  themeType,
595
+ themeName,
596
596
  "components",
597
597
  `${componentName}.tsx`
598
598
  )
@@ -600,23 +600,23 @@ async function loadThemeComponent(componentName, options) {
600
600
  }
601
601
  }
602
602
  if (searchServices) {
603
- const serviceDirs = await import_fs_extra3.default.readdir("services");
603
+ const serviceDirs = await import_fs_extra3.default.readdir(useSettings.getPaths().services);
604
604
  for (const svc of serviceDirs) {
605
605
  possiblePaths.push(
606
606
  import_path2.default.resolve(
607
607
  "services",
608
608
  svc,
609
609
  "themes",
610
- themeName,
611
610
  themeType,
611
+ themeName,
612
612
  `${componentName}.tsx`
613
613
  ),
614
614
  import_path2.default.resolve(
615
615
  "services",
616
616
  svc,
617
617
  "themes",
618
- themeName,
619
618
  themeType,
619
+ themeName,
620
620
  "components",
621
621
  `${componentName}.tsx`
622
622
  )
@@ -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 * 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 (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 Provider: 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\n\r\nexport async function loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n themeName: string;\r\n themeType: 'admin' | 'client' | 'portal' | 'email';\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 { themeName, themeType, search = {} } = 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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n themeType,\r\n themeName,\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('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 themeName,\r\n themeType,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n themeName,\r\n themeType,\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('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 themeName,\r\n themeType,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n themeName,\r\n themeType,\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 \"${themeName}\"`);\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/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 * 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 (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 Provider: 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 themeName: string;\r\n themeType: 'admin' | 'client' | 'portal' | 'email';\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 { themeName, themeType, search = {} } = 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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n themeType,\r\n themeName,\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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n themeType,\r\n themeName,\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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n themeType,\r\n themeName,\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 \"${themeName}\"`);\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"]}
package/dist/index.js CHANGED
@@ -515,23 +515,23 @@ async function loadThemeComponent(componentName, options) {
515
515
  );
516
516
  }
517
517
  if (searchModules) {
518
- const moduleDirs = await fs6.readdir("modules");
518
+ const moduleDirs = await fs6.readdir(useSettings.getPaths().modules);
519
519
  for (const mod of moduleDirs) {
520
520
  possiblePaths.push(
521
521
  path7.resolve(
522
522
  "modules",
523
523
  mod,
524
524
  "themes",
525
- themeName,
526
525
  themeType,
526
+ themeName,
527
527
  `${componentName}.tsx`
528
528
  ),
529
529
  path7.resolve(
530
530
  "modules",
531
531
  mod,
532
532
  "themes",
533
- themeName,
534
533
  themeType,
534
+ themeName,
535
535
  "components",
536
536
  `${componentName}.tsx`
537
537
  )
@@ -539,23 +539,23 @@ async function loadThemeComponent(componentName, options) {
539
539
  }
540
540
  }
541
541
  if (searchServices) {
542
- const serviceDirs = await fs6.readdir("services");
542
+ const serviceDirs = await fs6.readdir(useSettings.getPaths().services);
543
543
  for (const svc of serviceDirs) {
544
544
  possiblePaths.push(
545
545
  path7.resolve(
546
546
  "services",
547
547
  svc,
548
548
  "themes",
549
- themeName,
550
549
  themeType,
550
+ themeName,
551
551
  `${componentName}.tsx`
552
552
  ),
553
553
  path7.resolve(
554
554
  "services",
555
555
  svc,
556
556
  "themes",
557
- themeName,
558
557
  themeType,
558
+ themeName,
559
559
  "components",
560
560
  `${componentName}.tsx`
561
561
  )
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 (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 Provider: 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\n\r\nexport async function loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n themeName: string;\r\n themeType: 'admin' | 'client' | 'portal' | 'email';\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 { themeName, themeType, search = {} } = 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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n themeType,\r\n themeName,\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('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 themeName,\r\n themeType,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n themeName,\r\n themeType,\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('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 themeName,\r\n themeType,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n themeName,\r\n themeType,\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 \"${themeName}\"`);\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"]}
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 (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 Provider: 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 themeName: string;\r\n themeType: 'admin' | 'client' | 'portal' | 'email';\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 { themeName, themeType, search = {} } = 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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n themeType,\r\n themeName,\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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n themeType,\r\n themeName,\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 themeType,\r\n themeName,\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n themeType,\r\n themeName,\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 \"${themeName}\"`);\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "retrex-extensibles-core",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "The Core System for the New Upcoming Billing System Called retrex-Billing",
5
5
  "license": "ISC",
6
6
  "author": "",