retrex-extensibles-core 1.3.2 → 1.3.3

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
@@ -129,7 +129,7 @@ function toggleModule(name, enabled) {
129
129
  const modules = getModules();
130
130
  const mod = modules.find((m) => m.lowerName === name.toLowerCase());
131
131
  if (!mod) throw new Error(`Module ${name} not found`);
132
- const metaPath = path2.join(paths.modules, mod.lowerName, "module.json");
132
+ const metaPath = path2.join(useSettings.getPaths().modules, mod.lowerName, "module.json");
133
133
  const meta = loadJSON(metaPath) || {};
134
134
  meta.enabled = enabled;
135
135
  saveJSON(metaPath, meta);
@@ -137,10 +137,10 @@ function toggleModule(name, enabled) {
137
137
  else onModuleDisabled(mod.name);
138
138
  }
139
139
  function getServices() {
140
- if (!paths?.services) throw new Error("Services path not registered.");
141
- const dirs = import_fs_extra.default.readdirSync(paths.services).filter((d) => import_fs_extra.default.statSync(path2.join(paths.services, d)).isDirectory());
140
+ if (!useSettings.getPaths().services) throw new Error("Services path not registered.");
141
+ const dirs = import_fs_extra.default.readdirSync(useSettings.getPaths().services).filter((d) => import_fs_extra.default.statSync(path2.join(useSettings.getPaths().services, d)).isDirectory());
142
142
  return dirs.map((dir) => {
143
- const meta = loadJSON(path2.join(paths.services, dir, "service.json")) || {};
143
+ const meta = loadJSON(path2.join(useSettings.getPaths().services, dir, "service.json")) || {};
144
144
  return {
145
145
  name: meta.name || dir,
146
146
  lowerName: meta.lowerName || dir.toLowerCase(),
@@ -160,7 +160,7 @@ function toggleService(name, enabled) {
160
160
  const services = getServices();
161
161
  const svc = services.find((s) => s.lowerName === name.toLowerCase());
162
162
  if (!svc) throw new Error(`Service ${name} not found`);
163
- const metaPath = path2.join(paths.services, svc.lowerName, "service.json");
163
+ const metaPath = path2.join(useSettings.getPaths().services, svc.lowerName, "service.json");
164
164
  const meta = loadJSON(metaPath) || {};
165
165
  meta.enabled = enabled;
166
166
  saveJSON(metaPath, meta);
@@ -168,15 +168,15 @@ function toggleService(name, enabled) {
168
168
  else onServiceDisabled(svc.name);
169
169
  }
170
170
  function getTemplateBasePath(type) {
171
- if (!paths?.templates) throw new Error("Templates path not registered.");
171
+ if (!useSettings.getPaths().templates) throw new Error("Templates path not registered.");
172
172
  switch (type) {
173
173
  case "admin-theme":
174
174
  case "client-theme":
175
- return path2.join(paths.templates, "themes");
175
+ return path2.join(useSettings.getPaths().templates, "themes");
176
176
  case "portal":
177
- return path2.join(paths.templates, "portals");
177
+ return path2.join(useSettings.getPaths().templates, "portals");
178
178
  case "email":
179
- return path2.join(paths.templates, "emails");
179
+ return path2.join(useSettings.getPaths().templates, "emails");
180
180
  default:
181
181
  throw new Error(`Unknown template type: ${type}`);
182
182
  }
@@ -228,10 +228,10 @@ function onTemplateSelect(type, name) {
228
228
  console.log(`Template selected: type=${type}, name=${name}`);
229
229
  }
230
230
  async function registerEvents() {
231
- if (!paths?.modules) throw new Error("Modules path not registered.");
231
+ if (!useSettings.getPaths().modules) throw new Error("Modules path not registered.");
232
232
  const modules = getModules().filter((m) => m.enabled);
233
233
  for (const mod of modules) {
234
- const eventsFile = path2.join(paths.modules, mod.lowerName, "events.server.js");
234
+ const eventsFile = path2.join(useSettings.getPaths().modules, mod.lowerName, "events.server.js");
235
235
  if (import_fs_extra.default.existsSync(eventsFile)) {
236
236
  const modEvents = await import(eventsFile);
237
237
  if (modEvents?.registerEvents) await modEvents.registerEvents();
@@ -239,10 +239,10 @@ async function registerEvents() {
239
239
  }
240
240
  }
241
241
  async function registerMiddleware() {
242
- if (!paths?.modules) throw new Error("Modules path not registered.");
242
+ if (!useSettings.getPaths().modules) throw new Error("Modules path not registered.");
243
243
  const modules = getModules().filter((m) => m.enabled);
244
244
  for (const mod of modules) {
245
- const middlewareFile = path2.join(paths.modules, mod.lowerName, "middleware.server.js");
245
+ const middlewareFile = path2.join(useSettings.getPaths().modules, mod.lowerName, "middleware.server.js");
246
246
  if (import_fs_extra.default.existsSync(middlewareFile)) {
247
247
  const modMiddleware = await import(middlewareFile);
248
248
  if (modMiddleware?.registerMiddleware) await modMiddleware.registerMiddleware();
@@ -260,15 +260,15 @@ async function registerRoutes(routesFolderPath) {
260
260
  }
261
261
  }
262
262
  async function loadProviders() {
263
- const paths2 = {
263
+ paths = {
264
264
  modules: useSettings.getPaths().modules,
265
265
  templates: useSettings.getPaths().templates,
266
266
  services: useSettings.getPaths().services,
267
267
  events: useSettings.getPaths().events
268
268
  };
269
269
  const all = [
270
- { type: "module", list: getModules(), basePath: paths2.modules },
271
- { type: "service", list: getServices(), basePath: paths2.services }
270
+ { type: "module", list: getModules(), basePath: useSettings.getPaths().modules },
271
+ { type: "service", list: getServices(), basePath: useSettings.getPaths().services }
272
272
  ];
273
273
  for (const { type, list, basePath } of all) {
274
274
  for (const item of list) {
@@ -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/hooks/useUtils.ts","../src/core/providers/ThemeProvider.tsx"],"sourcesContent":["// src/index.ts\r\n\r\n// export * from './core/controller/EventController';\r\n// export * from './core/controller/MiddlewareController';\r\nexport * from './core/hooks/useExtensibles';\r\nexport * from './core/hooks/useSettings';\r\nexport * from './core/hooks/useModules';\r\nexport * from './core/hooks/useServices';\r\nexport * from './core/hooks/useTemplates';\r\nexport * from './core/hooks/useEvents';\r\nexport * from './core/hooks/useRoutes';\r\nexport * from './core/hooks/useUtils';\r\n// export * as ThemeProvider from './core/providers/ThemeProvider';\r\nexport * from './core/providers/ThemeProvider';\r\n","// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { pathToFileURL } from 'url';\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 (!useSettings.getPaths().modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(useSettings.getPaths().modules)\r\n .filter((d: any) => fs.statSync(path.join(useSettings.getPaths().modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(useSettings.getPaths().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|jsx|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 paths = {\r\n modules: useSettings.getPaths().modules,\r\n templates: useSettings.getPaths().templates,\r\n services: useSettings.getPaths().services,\r\n events: useSettings.getPaths().events,\r\n };\r\n\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 providerAbsPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerURL = pathToFileURL(providerAbsPath).href; // ✅ Convert to file:// URL\r\n const providerModule = await import(providerURL);\r\n\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default();\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\r\n\r\n// export async function loadProviders() {\r\n// paths = {\r\n// modules: useSettings.getPaths().modules,\r\n// templates: useSettings.getPaths().templates,\r\n// services: useSettings.getPaths().services,\r\n// events: useSettings.getPaths().events,\r\n// }\r\n// const all = [\r\n// { type: 'module', list: getModules(), basePath: paths.modules },\r\n// { type: 'service', list: getServices(), basePath: paths.services },\r\n// ];\r\n\r\n// for (const { type, list, basePath } of all) {\r\n// for (const item of list) {\r\n// if (!item.enabled) continue;\r\n\r\n// const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n// const meta = loadJSON(metaPath);\r\n// if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n// for (const providerRelPath of meta.providers) {\r\n// try {\r\n// const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n// const providerModule = await import(providerPath);\r\n// if (typeof providerModule.default === 'function') {\r\n// await providerModule.default(); // Call provider\r\n// console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n// } else {\r\n// console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n// }\r\n// } catch (err) {\r\n// console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n// }\r\n// }\r\n// }\r\n// }\r\n// }\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\nexport const routesManager = {\r\n /**\r\n * Register a dynamic route from a module/service.\r\n */\r\n registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n },\r\n\r\n /**\r\n * Return all registered dynamic routes.\r\n */\r\n getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n },\r\n\r\n /**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\n async mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport const useUtils = {\r\n async loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n ): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["path","paths","extensiblePaths","fs","paths","path","fs","import_fs","path","fs","import_fs","path","fs","import_fs_extra","fs","path","import_url","import_path","import_url","import_fs_extra","path","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/hooks/useExtensibles.ts","../src/core/hooks/useSettings.ts","../src/core/hooks/useModules.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTemplates.ts","../src/core/hooks/useEvents.ts","../src/core/hooks/useRoutes.ts","../src/core/hooks/useUtils.ts","../src/core/providers/ThemeProvider.tsx"],"sourcesContent":["// src/index.ts\r\n\r\n// export * from './core/controller/EventController';\r\n// export * from './core/controller/MiddlewareController';\r\nexport * from './core/hooks/useExtensibles';\r\nexport * from './core/hooks/useSettings';\r\nexport * from './core/hooks/useModules';\r\nexport * from './core/hooks/useServices';\r\nexport * from './core/hooks/useTemplates';\r\nexport * from './core/hooks/useEvents';\r\nexport * from './core/hooks/useRoutes';\r\nexport * from './core/hooks/useUtils';\r\n// export * as ThemeProvider from './core/providers/ThemeProvider';\r\nexport * from './core/providers/ThemeProvider';\r\n","// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { pathToFileURL } from 'url';\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 (!useSettings.getPaths().modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(useSettings.getPaths().modules)\r\n .filter((d: any) => fs.statSync(path.join(useSettings.getPaths().modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(useSettings.getPaths().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(useSettings.getPaths().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 (!useSettings.getPaths().services) throw new Error('Services path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(useSettings.getPaths().services)\r\n .filter((d: any) => fs.statSync(path.join(useSettings.getPaths().services, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(useSettings.getPaths().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(useSettings.getPaths().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 (!useSettings.getPaths().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(useSettings.getPaths().templates, 'themes');\r\n case 'portal':\r\n return path.join(useSettings.getPaths().templates, 'portals');\r\n case 'email':\r\n return path.join(useSettings.getPaths().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 (!useSettings.getPaths().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(useSettings.getPaths().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 (!useSettings.getPaths().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(useSettings.getPaths().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|jsx|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 paths = {\r\n modules: useSettings.getPaths().modules,\r\n templates: useSettings.getPaths().templates,\r\n services: useSettings.getPaths().services,\r\n events: useSettings.getPaths().events,\r\n };\r\n\r\n const all = [\r\n { type: 'module', list: getModules(), basePath: useSettings.getPaths().modules },\r\n { type: 'service', list: getServices(), basePath: useSettings.getPaths().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 providerAbsPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerURL = pathToFileURL(providerAbsPath).href; // ✅ Convert to file:// URL\r\n const providerModule = await import(providerURL);\r\n\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default();\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\r\n\r\n// export async function loadProviders() {\r\n// paths = {\r\n// modules: useSettings.getPaths().modules,\r\n// templates: useSettings.getPaths().templates,\r\n// services: useSettings.getPaths().services,\r\n// events: useSettings.getPaths().events,\r\n// }\r\n// const all = [\r\n// { type: 'module', list: getModules(), basePath: useSettings.getPaths().modules },\r\n// { type: 'service', list: getServices(), basePath: useSettings.getPaths().services },\r\n// ];\r\n\r\n// for (const { type, list, basePath } of all) {\r\n// for (const item of list) {\r\n// if (!item.enabled) continue;\r\n\r\n// const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n// const meta = loadJSON(metaPath);\r\n// if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n// for (const providerRelPath of meta.providers) {\r\n// try {\r\n// const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n// const providerModule = await import(providerPath);\r\n// if (typeof providerModule.default === 'function') {\r\n// await providerModule.default(); // Call provider\r\n// console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n// } else {\r\n// console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n// }\r\n// } catch (err) {\r\n// console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n// }\r\n// }\r\n// }\r\n// }\r\n// }\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\nexport const routesManager = {\r\n /**\r\n * Register a dynamic route from a module/service.\r\n */\r\n registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n },\r\n\r\n /**\r\n * Return all registered dynamic routes.\r\n */\r\n getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n },\r\n\r\n /**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\n async mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport const useUtils = {\r\n async loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n ): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["path","paths","extensiblePaths","fs","path","fs","import_fs","path","fs","import_fs","path","fs","import_fs_extra","fs","path","import_url","import_path","import_url","import_fs_extra","path","fs"]}
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ function toggleModule(name, enabled) {
64
64
  const modules = getModules();
65
65
  const mod = modules.find((m) => m.lowerName === name.toLowerCase());
66
66
  if (!mod) throw new Error(`Module ${name} not found`);
67
- const metaPath = path2.join(paths.modules, mod.lowerName, "module.json");
67
+ const metaPath = path2.join(useSettings.getPaths().modules, mod.lowerName, "module.json");
68
68
  const meta = loadJSON(metaPath) || {};
69
69
  meta.enabled = enabled;
70
70
  saveJSON(metaPath, meta);
@@ -72,10 +72,10 @@ function toggleModule(name, enabled) {
72
72
  else onModuleDisabled(mod.name);
73
73
  }
74
74
  function getServices() {
75
- if (!paths?.services) throw new Error("Services path not registered.");
76
- const dirs = fs.readdirSync(paths.services).filter((d) => fs.statSync(path2.join(paths.services, d)).isDirectory());
75
+ if (!useSettings.getPaths().services) throw new Error("Services path not registered.");
76
+ const dirs = fs.readdirSync(useSettings.getPaths().services).filter((d) => fs.statSync(path2.join(useSettings.getPaths().services, d)).isDirectory());
77
77
  return dirs.map((dir) => {
78
- const meta = loadJSON(path2.join(paths.services, dir, "service.json")) || {};
78
+ const meta = loadJSON(path2.join(useSettings.getPaths().services, dir, "service.json")) || {};
79
79
  return {
80
80
  name: meta.name || dir,
81
81
  lowerName: meta.lowerName || dir.toLowerCase(),
@@ -95,7 +95,7 @@ function toggleService(name, enabled) {
95
95
  const services = getServices();
96
96
  const svc = services.find((s) => s.lowerName === name.toLowerCase());
97
97
  if (!svc) throw new Error(`Service ${name} not found`);
98
- const metaPath = path2.join(paths.services, svc.lowerName, "service.json");
98
+ const metaPath = path2.join(useSettings.getPaths().services, svc.lowerName, "service.json");
99
99
  const meta = loadJSON(metaPath) || {};
100
100
  meta.enabled = enabled;
101
101
  saveJSON(metaPath, meta);
@@ -103,15 +103,15 @@ function toggleService(name, enabled) {
103
103
  else onServiceDisabled(svc.name);
104
104
  }
105
105
  function getTemplateBasePath(type) {
106
- if (!paths?.templates) throw new Error("Templates path not registered.");
106
+ if (!useSettings.getPaths().templates) throw new Error("Templates path not registered.");
107
107
  switch (type) {
108
108
  case "admin-theme":
109
109
  case "client-theme":
110
- return path2.join(paths.templates, "themes");
110
+ return path2.join(useSettings.getPaths().templates, "themes");
111
111
  case "portal":
112
- return path2.join(paths.templates, "portals");
112
+ return path2.join(useSettings.getPaths().templates, "portals");
113
113
  case "email":
114
- return path2.join(paths.templates, "emails");
114
+ return path2.join(useSettings.getPaths().templates, "emails");
115
115
  default:
116
116
  throw new Error(`Unknown template type: ${type}`);
117
117
  }
@@ -163,10 +163,10 @@ function onTemplateSelect(type, name) {
163
163
  console.log(`Template selected: type=${type}, name=${name}`);
164
164
  }
165
165
  async function registerEvents() {
166
- if (!paths?.modules) throw new Error("Modules path not registered.");
166
+ if (!useSettings.getPaths().modules) throw new Error("Modules path not registered.");
167
167
  const modules = getModules().filter((m) => m.enabled);
168
168
  for (const mod of modules) {
169
- const eventsFile = path2.join(paths.modules, mod.lowerName, "events.server.js");
169
+ const eventsFile = path2.join(useSettings.getPaths().modules, mod.lowerName, "events.server.js");
170
170
  if (fs.existsSync(eventsFile)) {
171
171
  const modEvents = await import(eventsFile);
172
172
  if (modEvents?.registerEvents) await modEvents.registerEvents();
@@ -174,10 +174,10 @@ async function registerEvents() {
174
174
  }
175
175
  }
176
176
  async function registerMiddleware() {
177
- if (!paths?.modules) throw new Error("Modules path not registered.");
177
+ if (!useSettings.getPaths().modules) throw new Error("Modules path not registered.");
178
178
  const modules = getModules().filter((m) => m.enabled);
179
179
  for (const mod of modules) {
180
- const middlewareFile = path2.join(paths.modules, mod.lowerName, "middleware.server.js");
180
+ const middlewareFile = path2.join(useSettings.getPaths().modules, mod.lowerName, "middleware.server.js");
181
181
  if (fs.existsSync(middlewareFile)) {
182
182
  const modMiddleware = await import(middlewareFile);
183
183
  if (modMiddleware?.registerMiddleware) await modMiddleware.registerMiddleware();
@@ -195,15 +195,15 @@ async function registerRoutes(routesFolderPath) {
195
195
  }
196
196
  }
197
197
  async function loadProviders() {
198
- const paths2 = {
198
+ paths = {
199
199
  modules: useSettings.getPaths().modules,
200
200
  templates: useSettings.getPaths().templates,
201
201
  services: useSettings.getPaths().services,
202
202
  events: useSettings.getPaths().events
203
203
  };
204
204
  const all = [
205
- { type: "module", list: getModules(), basePath: paths2.modules },
206
- { type: "service", list: getServices(), basePath: paths2.services }
205
+ { type: "module", list: getModules(), basePath: useSettings.getPaths().modules },
206
+ { type: "service", list: getServices(), basePath: useSettings.getPaths().services }
207
207
  ];
208
208
  for (const { type, list, basePath } of all) {
209
209
  for (const item of list) {
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/hooks/useUtils.ts","../src/core/providers/ThemeProvider.tsx"],"sourcesContent":["// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { pathToFileURL } from 'url';\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 (!useSettings.getPaths().modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(useSettings.getPaths().modules)\r\n .filter((d: any) => fs.statSync(path.join(useSettings.getPaths().modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(useSettings.getPaths().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|jsx|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 paths = {\r\n modules: useSettings.getPaths().modules,\r\n templates: useSettings.getPaths().templates,\r\n services: useSettings.getPaths().services,\r\n events: useSettings.getPaths().events,\r\n };\r\n\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 providerAbsPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerURL = pathToFileURL(providerAbsPath).href; // ✅ Convert to file:// URL\r\n const providerModule = await import(providerURL);\r\n\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default();\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\r\n\r\n// export async function loadProviders() {\r\n// paths = {\r\n// modules: useSettings.getPaths().modules,\r\n// templates: useSettings.getPaths().templates,\r\n// services: useSettings.getPaths().services,\r\n// events: useSettings.getPaths().events,\r\n// }\r\n// const all = [\r\n// { type: 'module', list: getModules(), basePath: paths.modules },\r\n// { type: 'service', list: getServices(), basePath: paths.services },\r\n// ];\r\n\r\n// for (const { type, list, basePath } of all) {\r\n// for (const item of list) {\r\n// if (!item.enabled) continue;\r\n\r\n// const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n// const meta = loadJSON(metaPath);\r\n// if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n// for (const providerRelPath of meta.providers) {\r\n// try {\r\n// const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n// const providerModule = await import(providerPath);\r\n// if (typeof providerModule.default === 'function') {\r\n// await providerModule.default(); // Call provider\r\n// console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n// } else {\r\n// console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n// }\r\n// } catch (err) {\r\n// console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n// }\r\n// }\r\n// }\r\n// }\r\n// }\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\nexport const routesManager = {\r\n /**\r\n * Register a dynamic route from a module/service.\r\n */\r\n registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n },\r\n\r\n /**\r\n * Return all registered dynamic routes.\r\n */\r\n getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n },\r\n\r\n /**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\n async mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport const useUtils = {\r\n async loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n ): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["path","paths","extensiblePaths","paths","fs","path","fs","fs","path","fs","fs","path","fs","fs","path","fs","path","pathToFileURL","path","pathToFileURL","fs","path","fs","pathToFileURL"]}
1
+ {"version":3,"sources":["../src/core/hooks/useExtensibles.ts","../src/core/hooks/useSettings.ts","../src/core/hooks/useModules.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTemplates.ts","../src/core/hooks/useEvents.ts","../src/core/hooks/useRoutes.ts","../src/core/hooks/useUtils.ts","../src/core/providers/ThemeProvider.tsx"],"sourcesContent":["// src/hooks/useExtensibles.ts\r\n\r\nimport fs from 'fs-extra';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { pathToFileURL } from 'url';\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 (!useSettings.getPaths().modules) throw new Error('Modules path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(useSettings.getPaths().modules)\r\n .filter((d: any) => fs.statSync(path.join(useSettings.getPaths().modules, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(useSettings.getPaths().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(useSettings.getPaths().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 (!useSettings.getPaths().services) throw new Error('Services path not registered.');\r\n\r\n const dirs = fs\r\n .readdirSync(useSettings.getPaths().services)\r\n .filter((d: any) => fs.statSync(path.join(useSettings.getPaths().services, d)).isDirectory());\r\n\r\n return dirs.map((dir: any) => {\r\n const meta = loadJSON(path.join(useSettings.getPaths().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(useSettings.getPaths().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 (!useSettings.getPaths().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(useSettings.getPaths().templates, 'themes');\r\n case 'portal':\r\n return path.join(useSettings.getPaths().templates, 'portals');\r\n case 'email':\r\n return path.join(useSettings.getPaths().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 (!useSettings.getPaths().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(useSettings.getPaths().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 (!useSettings.getPaths().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(useSettings.getPaths().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|jsx|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 paths = {\r\n modules: useSettings.getPaths().modules,\r\n templates: useSettings.getPaths().templates,\r\n services: useSettings.getPaths().services,\r\n events: useSettings.getPaths().events,\r\n };\r\n\r\n const all = [\r\n { type: 'module', list: getModules(), basePath: useSettings.getPaths().modules },\r\n { type: 'service', list: getServices(), basePath: useSettings.getPaths().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 providerAbsPath = path.join(basePath, item.lowerName, providerRelPath);\r\n const providerURL = pathToFileURL(providerAbsPath).href; // ✅ Convert to file:// URL\r\n const providerModule = await import(providerURL);\r\n\r\n if (typeof providerModule.default === 'function') {\r\n await providerModule.default();\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\r\n\r\n// export async function loadProviders() {\r\n// paths = {\r\n// modules: useSettings.getPaths().modules,\r\n// templates: useSettings.getPaths().templates,\r\n// services: useSettings.getPaths().services,\r\n// events: useSettings.getPaths().events,\r\n// }\r\n// const all = [\r\n// { type: 'module', list: getModules(), basePath: useSettings.getPaths().modules },\r\n// { type: 'service', list: getServices(), basePath: useSettings.getPaths().services },\r\n// ];\r\n\r\n// for (const { type, list, basePath } of all) {\r\n// for (const item of list) {\r\n// if (!item.enabled) continue;\r\n\r\n// const metaPath = path.join(basePath, item.lowerName, `${type}.json`);\r\n// const meta = loadJSON(metaPath);\r\n// if (!meta?.providers || !Array.isArray(meta.providers)) continue;\r\n\r\n// for (const providerRelPath of meta.providers) {\r\n// try {\r\n// const providerPath = path.join(basePath, item.lowerName, providerRelPath);\r\n// const providerModule = await import(providerPath);\r\n// if (typeof providerModule.default === 'function') {\r\n// await providerModule.default(); // Call provider\r\n// console.log(`[${type}] Provider loaded: ${providerRelPath}`);\r\n// } else {\r\n// console.warn(`[${type}] Provider ${providerRelPath} has no default export.`);\r\n// }\r\n// } catch (err) {\r\n// console.error(`[${type}] Failed to load provider ${providerRelPath}:`, err);\r\n// }\r\n// }\r\n// }\r\n// }\r\n// }\r\n","// src/hooks/useSettings.ts\r\n\r\nimport * as path from 'path';\r\n\r\nimport { ExtensiblePaths, loadJSON, saveJSON } from './useExtensibles';\r\n\r\n// export interface ExtensiblePaths {\r\n// modulesPath: string;\r\n// templatesPath: string;\r\n// servicesPath: string;\r\n// }\r\n\r\nlet extensiblePaths: ExtensiblePaths = {\r\n modules: path.resolve(process.cwd(), 'modules'),\r\n templates: path.resolve(process.cwd(), 'resources/themes'),\r\n services: path.resolve(process.cwd(), 'app/services'),\r\n events: path.resolve(process.cwd(), 'events'),\r\n};\r\n\r\nexport const useSettings = {\r\n getPaths(): ExtensiblePaths {\r\n extensiblePaths = loadJSON(\"extensiblePaths.json\");\r\n return extensiblePaths;\r\n },\r\n\r\n setPaths(paths: Partial<ExtensiblePaths>) {\r\n saveJSON(\"extensiblePaths.json\", {\r\n ...extensiblePaths,\r\n ...paths,\r\n })\r\n extensiblePaths = {\r\n ...extensiblePaths,\r\n ...paths,\r\n };\r\n },\r\n};\r\n","// src/hooks/useModules.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ModuleMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n}\r\n\r\nexport const useModules = {\r\n loadModules(): ModuleMeta[] {\r\n const modulesDir = useSettings.getPaths().modules;\r\n if (!fs.existsSync(modulesDir)) return [];\r\n\r\n const moduleFolders = fs.readdirSync(modulesDir);\r\n const modules: ModuleMeta[] = [];\r\n\r\n moduleFolders.forEach((folder) => {\r\n const modulePath = path.join(modulesDir, folder);\r\n const moduleJsonPath = path.join(modulePath, 'module.json');\r\n if (!fs.existsSync(moduleJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(moduleJsonPath, 'utf-8');\r\n const moduleData = JSON.parse(rawData) as ModuleMeta;\r\n modules.push(moduleData);\r\n } catch {\r\n // invalid json or read error, ignore\r\n }\r\n });\r\n\r\n return modules;\r\n },\r\n\r\n isModuleEnabled(moduleName: string): boolean {\r\n const modules = useModules.loadModules();\r\n const mod = modules.find((m) => m.lowerName === moduleName.toLowerCase());\r\n return mod ? mod.enabled : false;\r\n },\r\n\r\n toggleModule(moduleName: string, enabled: boolean): boolean {\r\n const modulesDir = useSettings.getPaths().modules;\r\n const modules = useModules.loadModules();\r\n const modIndex = modules.findIndex((m) => m.lowerName === moduleName.toLowerCase());\r\n if (modIndex === -1) return false;\r\n\r\n const moduleMeta = modules[modIndex];\r\n moduleMeta.enabled = enabled;\r\n\r\n const moduleJsonPath = path.join(modulesDir, moduleMeta.lowerName, 'module.json');\r\n try {\r\n fs.writeFileSync(moduleJsonPath, JSON.stringify(moduleMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getModules(): ModuleMeta[] {\r\n return useModules.loadModules();\r\n },\r\n};\r\n","// src/hooks/useServices.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport interface ServiceMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n providers?: string[];\r\n serviceType?: string;\r\n}\r\n\r\nexport const useServices = {\r\n loadServices(): ServiceMeta[] {\r\n const servicesDir = useSettings.getPaths().services;\r\n if (!fs.existsSync(servicesDir)) return [];\r\n\r\n const serviceFolders = fs.readdirSync(servicesDir);\r\n const services: ServiceMeta[] = [];\r\n\r\n serviceFolders.forEach((folder) => {\r\n const servicePath = path.join(servicesDir, folder);\r\n const serviceJsonPath = path.join(servicePath, 'service.json');\r\n if (!fs.existsSync(serviceJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(serviceJsonPath, 'utf-8');\r\n const serviceData = JSON.parse(rawData) as ServiceMeta;\r\n services.push(serviceData);\r\n } catch {\r\n // ignore invalid json or errors\r\n }\r\n });\r\n\r\n return services;\r\n },\r\n\r\n isServiceEnabled(serviceName: string): boolean {\r\n const services = useServices.loadServices();\r\n const service = services.find((s) => s.lowerName === serviceName.toLowerCase());\r\n return service ? service.enabled : false;\r\n },\r\n\r\n toggleService(serviceName: string, enabled: boolean): boolean {\r\n const servicesDir = useSettings.getPaths().services;\r\n const services = useServices.loadServices();\r\n const index = services.findIndex((s) => s.lowerName === serviceName.toLowerCase());\r\n if (index === -1) return false;\r\n\r\n const serviceMeta = services[index];\r\n serviceMeta.enabled = enabled;\r\n\r\n const serviceJsonPath = path.join(servicesDir, serviceMeta.lowerName, 'service.json');\r\n try {\r\n fs.writeFileSync(serviceJsonPath, JSON.stringify(serviceMeta, null, 2), 'utf-8');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getServices(): ServiceMeta[] {\r\n return useServices.loadServices();\r\n },\r\n};\r\n","// src/hooks/useTemplates.ts\r\n\r\nimport fs from 'fs';\r\nimport * as path from 'path';\r\nimport { useSettings } from './useSettings';\r\nimport { TemplateType } from './useExtensibles';\r\n\r\nexport interface TemplateMeta {\r\n name: string;\r\n lowerName: string;\r\n version?: string;\r\n author?: string;\r\n icon?: string;\r\n description?: string;\r\n enabled: boolean;\r\n templateType: TemplateType;\r\n}\r\n\r\nexport const useTemplates = {\r\n loadTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n const templatesDir = useSettings.getPaths().templates;\r\n if (!fs.existsSync(templatesDir)) return [];\r\n\r\n const templateFolders = fs.readdirSync(templatesDir);\r\n const templates: TemplateMeta[] = [];\r\n\r\n templateFolders.forEach((folder) => {\r\n const templatePath = path.join(templatesDir, folder);\r\n const templateJsonPath = path.join(templatePath, 'template.json');\r\n if (!fs.existsSync(templateJsonPath)) return;\r\n\r\n try {\r\n const rawData = fs.readFileSync(templateJsonPath, 'utf-8');\r\n const templateData = JSON.parse(rawData) as TemplateMeta;\r\n\r\n if (templateType) {\r\n if (templateData.templateType === templateType) {\r\n templates.push(templateData);\r\n }\r\n } else {\r\n templates.push(templateData);\r\n }\r\n } catch {\r\n // ignore invalid JSON or errors\r\n }\r\n });\r\n\r\n return templates;\r\n },\r\n\r\n isTemplateActive(templateType: TemplateType, templateName: string): boolean {\r\n const templates = useTemplates.loadTemplates(templateType);\r\n const template = templates.find(\r\n (t) => t.lowerName === templateName.toLowerCase() && t.enabled\r\n );\r\n return !!template;\r\n },\r\n\r\n toggleTemplate(templateType: TemplateType, templateName: string): boolean {\r\n // Since only one template of each type can be enabled, disable others and enable this one\r\n const templatesDir = useSettings.getPaths().templates;\r\n const templates = useTemplates.loadTemplates(templateType);\r\n\r\n let toggled = false;\r\n\r\n templates.forEach((template) => {\r\n if (template.name.toLowerCase() === templateName.toLowerCase()) {\r\n if (!template.enabled) {\r\n template.enabled = true;\r\n toggled = true;\r\n }\r\n } else {\r\n if (template.enabled) {\r\n template.enabled = false;\r\n }\r\n }\r\n\r\n const templateJsonPath = path.join(templatesDir, template.lowerName, 'template.json');\r\n try {\r\n fs.writeFileSync(templateJsonPath, JSON.stringify(template, null, 2), 'utf-8');\r\n } catch {\r\n // ignore write errors\r\n }\r\n });\r\n\r\n return toggled;\r\n },\r\n\r\n getTemplates(templateType?: TemplateType): TemplateMeta[] {\r\n return useTemplates.loadTemplates(templateType);\r\n },\r\n};\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { Server as SocketIOServer, Socket } from 'socket.io';\r\nimport { useSettings } from './useSettings';\r\n\r\n// Type signature for an event controller\r\ninterface EventController {\r\n onRegister?: (io: SocketIOServer) => void;\r\n onEvent?: (socket: Socket, event: any) => void;\r\n}\r\n\r\n// Dynamically import and register events\r\nexport async function useEvents(io: SocketIOServer) {\r\n const { modules, services, events: appEventsPath } = useSettings.getPaths();\r\n\r\n const sources = [\r\n { type: 'module', root: modules },\r\n { type: 'service', root: services },\r\n { type: 'app', root: appEventsPath },\r\n ];\r\n\r\n for (const source of sources) {\r\n if (!(await fs.pathExists(source.root))) continue;\r\n\r\n const dirs = await fs.readdir(source.root);\r\n for (const dir of dirs) {\r\n const base = path.join(source.root, dir);\r\n const eventsDir = source.type === 'app' ? base : path.join(base, 'events');\r\n\r\n if (!(await fs.pathExists(eventsDir))) continue;\r\n\r\n const files = (await fs.readdir(eventsDir)).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));\r\n\r\n for (const file of files) {\r\n const eventPath = path.join(eventsDir, file);\r\n try {\r\n const imported = await import(eventPath);\r\n const controller: EventController = imported.default || imported[Object.keys(imported)[0]];\r\n\r\n if (controller?.onRegister) {\r\n controller.onRegister(io);\r\n }\r\n\r\n if (controller?.onEvent) {\r\n io.on('connection', (socket) => {\r\n const eventName = file.replace(/\\.(ts|js)$/, '');\r\n socket.on(eventName, (data) => controller.onEvent!(socket, data));\r\n });\r\n }\r\n } catch (err) {\r\n console.warn(`⚠️ Failed to load event: ${eventPath}`, err);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/useRoutes.ts\r\nimport { Application, Request, Response, NextFunction } from 'express';\r\nimport { pathToFileURL } from 'url';\r\nimport type { LoaderFunctionArgs, ActionFunctionArgs } from '@remix-run/node';\r\n\r\ninterface RouteDefinition {\r\n path: string;\r\n method: 'get' | 'post' | 'put' | 'patch' | 'delete';\r\n filePath: string; // absolute path to .tsx file\r\n}\r\n\r\n// Registry for dynamically added routes\r\nconst registeredRoutes: RouteDefinition[] = [];\r\nexport const routesManager = {\r\n /**\r\n * Register a dynamic route from a module/service.\r\n */\r\n registerRoute(def: RouteDefinition): void {\r\n registeredRoutes.push(def);\r\n },\r\n\r\n /**\r\n * Return all registered dynamic routes.\r\n */\r\n getRegisteredRoutes(): RouteDefinition[] {\r\n return registeredRoutes;\r\n },\r\n\r\n /**\r\n * Loads and mounts all registered dynamic routes into an Express app.\r\n */\r\n async mountRegisteredRoutes(app: Application): Promise<void> {\r\n for (const route of registeredRoutes) {\r\n const mod = await import(pathToFileURL(route.filePath).toString());\r\n\r\n const hasLoader = typeof mod.loader === 'function';\r\n const hasAction = typeof mod.action === 'function';\r\n const hasDefault = typeof mod.default !== 'undefined';\r\n\r\n // Handle API routes with loader/action\r\n if (!hasDefault && (hasLoader || hasAction)) {\r\n app[route.method](route.path, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (route.method === 'get' && hasLoader) {\r\n const result = await mod.loader({ request: req });\r\n res.json(result);\r\n } else if (hasAction) {\r\n const result = await mod.action({ request: req });\r\n res.json(result);\r\n } else {\r\n res.status(405).json({ error: 'Method Not Allowed' });\r\n }\r\n } catch (err) {\r\n next(err);\r\n }\r\n });\r\n }\r\n\r\n // Handle Page Routes (React component as default export)\r\n else if (hasDefault) {\r\n app.use(route.path, (req: Request, res: Response, next: NextFunction) => {\r\n res.locals.__dynamicPageComponent = mod.default;\r\n next(); // forward to Remix handler\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","// packages/retrex-extensibles-core/utils/loadThemeComponent.ts\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport fs from 'fs-extra';\r\nimport { useSettings } from './useSettings';\r\n\r\nexport const useUtils = {\r\n async loadThemeComponent(\r\n componentName: string,\r\n options: {\r\n theme: {\r\n name: string;\r\n type: 'admin' | 'client' | 'portal' | 'email';\r\n };\r\n search?: {\r\n themes?: boolean;\r\n modules?: boolean;\r\n services?: boolean;\r\n };\r\n }\r\n ): Promise<React.ComponentType<any> | null> {\r\n const { search = {}, theme } = options;\r\n const searchThemes = search.themes ?? true;\r\n const searchModules = search.modules ?? true;\r\n const searchServices = search.services ?? true;\r\n\r\n const possiblePaths: string[] = [];\r\n\r\n if (searchThemes) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'resources',\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n\r\n if (searchModules) {\r\n const moduleDirs = await fs.readdir(useSettings.getPaths().modules);\r\n for (const mod of moduleDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'modules',\r\n mod,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n if (searchServices) {\r\n const serviceDirs = await fs.readdir(useSettings.getPaths().services);\r\n for (const svc of serviceDirs) {\r\n possiblePaths.push(\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'routes',\r\n `${componentName}.tsx`\r\n ),\r\n path.resolve(\r\n 'services',\r\n svc,\r\n 'themes',\r\n theme.type,\r\n theme.name,\r\n 'components',\r\n `${componentName}.tsx`\r\n )\r\n );\r\n }\r\n }\r\n\r\n for (const filePath of possiblePaths) {\r\n if (await fs.pathExists(filePath)) {\r\n try {\r\n const mod = await import(pathToFileURL(filePath).toString());\r\n if (mod.default) return mod.default;\r\n } catch (err) {\r\n console.error(`Error loading component at ${filePath}:`, err);\r\n }\r\n }\r\n }\r\n\r\n console.warn(`Component \"${componentName}\" not found in theme \"${theme.name}\" of type \"${theme.type}\".`);\r\n return null;\r\n }\r\n}\r\n","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport path from 'path';\r\nimport { useSettings } from '../hooks/useSettings';\r\nimport { getTemplates, TemplateType } from '../hooks/useExtensibles';\r\n\r\ninterface ThemeContextProps {\r\n templateType: TemplateType;\r\n activeTheme: string;\r\n setActiveTheme: (theme: string) => void;\r\n}\r\n\r\nconst ThemeContext = createContext<ThemeContextProps | null>(null);\r\n\r\nexport const ThemeProvider: React.FC<{\r\n type: TemplateType;\r\n children: React.ReactNode;\r\n}> = ({ type, children }) => {\r\n const [activeTheme, setActiveTheme] = useState<string>(() => {\r\n const templates = getTemplates(type);\r\n const enabled = templates.find(t => t.enabled);\r\n return enabled?.lowerName ?? templates[0]?.lowerName ?? 'default';\r\n });\r\n\r\n return (\r\n <ThemeContext.Provider value={{ templateType: type, activeTheme, setActiveTheme }}>\r\n {children}\r\n </ThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport function useTheme() {\r\n const ctx = useContext(ThemeContext);\r\n if (!ctx) throw new Error('useTheme must be used inside a ThemeProvider');\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["path","paths","extensiblePaths","fs","path","fs","fs","path","fs","fs","path","fs","fs","path","fs","path","pathToFileURL","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.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "The Core System for the New Upcoming Billing System Called retrex-Billing",
5
5
  "license": "ISC",
6
6
  "author": "",