@arch-cadre/modules 0.0.26 → 0.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  2. package/dist/client/extension-point.cjs +19 -0
  3. package/dist/client/extension-point.d.cts +21 -0
  4. package/dist/client/extension-point.d.cts.map +1 -0
  5. package/dist/client/extension-point.d.mts +21 -0
  6. package/dist/client/extension-point.d.mts.map +1 -0
  7. package/dist/client/extension-point.mjs +19 -0
  8. package/dist/client/extension-point.mjs.map +1 -0
  9. package/dist/client/widget-area.cjs +20 -0
  10. package/dist/client/widget-area.d.cts +19 -0
  11. package/dist/client/widget-area.d.cts.map +1 -0
  12. package/dist/client/widget-area.d.mts +19 -0
  13. package/dist/client/widget-area.d.mts.map +1 -0
  14. package/dist/client/widget-area.mjs +20 -0
  15. package/dist/client/widget-area.mjs.map +1 -0
  16. package/dist/index.cjs +5 -19
  17. package/dist/index.d.cts +4 -20
  18. package/dist/index.d.mts +4 -20
  19. package/dist/index.mjs +4 -19
  20. package/dist/server/lifecycle.cjs +193 -0
  21. package/dist/server/lifecycle.d.cts +9 -0
  22. package/dist/server/lifecycle.d.cts.map +1 -0
  23. package/dist/server/lifecycle.d.mts +9 -0
  24. package/dist/server/lifecycle.d.mts.map +1 -0
  25. package/dist/server/lifecycle.mjs +189 -0
  26. package/dist/server/lifecycle.mjs.map +1 -0
  27. package/dist/server/manage.cjs +126 -0
  28. package/dist/server/manage.d.cts +31 -0
  29. package/dist/server/manage.d.cts.map +1 -0
  30. package/dist/server/manage.d.mts +31 -0
  31. package/dist/server/manage.d.mts.map +1 -0
  32. package/dist/server/manage.mjs +118 -0
  33. package/dist/server/manage.mjs.map +1 -0
  34. package/dist/server/registry.cjs +86 -0
  35. package/dist/server/registry.d.cts +5 -0
  36. package/dist/server/registry.d.cts.map +1 -0
  37. package/dist/server/registry.d.mts +5 -0
  38. package/dist/server/registry.d.mts.map +1 -0
  39. package/dist/server/registry.mjs +86 -0
  40. package/dist/server/registry.mjs.map +1 -0
  41. package/dist/server/ui.cjs +180 -0
  42. package/dist/server/ui.d.cts +17 -0
  43. package/dist/server/ui.d.cts.map +1 -0
  44. package/dist/server/ui.d.mts +17 -0
  45. package/dist/server/ui.d.mts.map +1 -0
  46. package/dist/{ui-lsiPxu_C.mjs → server/ui.mjs} +5 -129
  47. package/dist/server/ui.mjs.map +1 -0
  48. package/dist/server.cjs +19 -292
  49. package/dist/server.d.cts +7 -59
  50. package/dist/server.d.mts +7 -59
  51. package/dist/server.mjs +8 -280
  52. package/dist/types.cjs +19 -0
  53. package/dist/{ui-CWGtK5lA.d.cts → types.d.cts} +2 -15
  54. package/dist/types.d.cts.map +1 -0
  55. package/dist/{ui-aeAUERbe.d.mts → types.d.mts} +2 -15
  56. package/dist/types.d.mts.map +1 -0
  57. package/dist/types.mjs +19 -0
  58. package/dist/types.mjs.map +1 -0
  59. package/package.json +1 -1
  60. package/dist/index.d.cts.map +0 -1
  61. package/dist/index.d.mts.map +0 -1
  62. package/dist/index.mjs.map +0 -1
  63. package/dist/server.d.cts.map +0 -1
  64. package/dist/server.d.mts.map +0 -1
  65. package/dist/server.mjs.map +0 -1
  66. package/dist/ui-CCBvXMXH.cjs +0 -441
  67. package/dist/ui-CWGtK5lA.d.cts.map +0 -1
  68. package/dist/ui-aeAUERbe.d.mts.map +0 -1
  69. package/dist/ui-lsiPxu_C.mjs.map +0 -1
@@ -0,0 +1,86 @@
1
+ "use server";
2
+
3
+ import { getModuleInstance, getModules, isModuleEnabled } from "./manage.mjs";
4
+ import { db } from "@arch-cadre/core/server";
5
+ import { eventBus, systemModulesTable } from "@arch-cadre/core";
6
+ import { eq } from "drizzle-orm";
7
+
8
+ //#region src/server/registry.ts
9
+ const globalForRegistry = globalThis;
10
+ async function initModules(force = false) {
11
+ if (globalForRegistry.__KRYO_MODULES_INITIALIZED__ && !force) return;
12
+ if (force) {
13
+ console.log("[Kernel:Registry] Forcing re-initialization...");
14
+ eventBus.clearAll();
15
+ }
16
+ console.log("[Kernel:Registry] Synchronizing module listeners...");
17
+ globalForRegistry.__KRYO_MODULES_INITIALIZED__ = true;
18
+ await eventBus.publish("system:modules:init:start", { timestamp: Date.now() });
19
+ const processedModuleIds = /* @__PURE__ */ new Set();
20
+ let hasNewModules = true;
21
+ let iterations = 0;
22
+ const MAX_ITERATIONS = 10;
23
+ while (hasNewModules && iterations < MAX_ITERATIONS) {
24
+ hasNewModules = false;
25
+ iterations++;
26
+ const pendingModules = (await getModules()).filter((mod) => !processedModuleIds.has(mod.id));
27
+ if (pendingModules.length === 0) break;
28
+ for (const mod of pendingModules) try {
29
+ await db.insert(systemModulesTable).values({
30
+ id: mod.id,
31
+ enabled: mod.system ?? false,
32
+ installed: mod.system ?? false,
33
+ system: mod.system ?? false
34
+ }).onConflictDoNothing();
35
+ } catch (_e) {}
36
+ const sortedPending = [...pendingModules].sort((a, b) => a.system === b.system ? 0 : a.system ? -1 : 1);
37
+ for (const mod of sortedPending) {
38
+ processedModuleIds.add(mod.id);
39
+ hasNewModules = true;
40
+ try {
41
+ const enabled = await isModuleEnabled(mod.id);
42
+ if (!enabled) continue;
43
+ const instance = await getModuleInstance(mod.id);
44
+ if (!instance) {
45
+ console.warn(`[Kernel:Registry] No instance found for module ${mod.id}. Ensure it is registered correctly.`);
46
+ continue;
47
+ }
48
+ let dbMod = null;
49
+ try {
50
+ [dbMod] = await db.select().from(systemModulesTable).where(eq(systemModulesTable.id, mod.id));
51
+ } catch (_e) {}
52
+ if (enabled && (!dbMod || !dbMod.installed)) {
53
+ console.log(`[Kernel:Registry] Installing module ${mod.id}...`);
54
+ if (instance.onMigrate) {
55
+ console.log(`[Kernel:Registry] Running onMigrate for ${mod.id}...`);
56
+ await instance.onMigrate();
57
+ }
58
+ console.log(`[Kernel:Registry] Running onEnable for ${mod.id}...`);
59
+ if (instance.onEnable) await instance.onEnable();
60
+ try {
61
+ await db.update(systemModulesTable).set({
62
+ installed: true,
63
+ lastStep: null
64
+ }).where(eq(systemModulesTable.id, mod.id));
65
+ } catch (_e) {}
66
+ }
67
+ if (instance.init) {
68
+ console.log(`[Kernel:Registry] Initializing ${mod.id}...`);
69
+ await instance.init();
70
+ console.log(`[Kernel:Registry] Module ${mod.id} is active.`);
71
+ }
72
+ } catch (error) {
73
+ console.error(`[Kernel:Registry] Critical failure for ${mod.id}:`, error);
74
+ }
75
+ }
76
+ }
77
+ if (iterations >= MAX_ITERATIONS) console.warn("[Kernel:Registry] Max init iterations reached. Check for circular module registrations.");
78
+ await eventBus.publish("system:modules:init:end", {
79
+ timestamp: Date.now(),
80
+ moduleCount: processedModuleIds.size
81
+ });
82
+ }
83
+
84
+ //#endregion
85
+ export { initModules };
86
+ //# sourceMappingURL=registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.mjs","names":[],"sources":["../../src/server/registry.ts"],"sourcesContent":["\"use server\";\n\nimport { eventBus, systemModulesTable } from \"@arch-cadre/core\";\nimport { db } from \"@arch-cadre/core/server\";\nimport { eq } from \"drizzle-orm\";\nimport { getModuleInstance, getModules, isModuleEnabled } from \"./manage\";\n\nconst globalForRegistry = globalThis as unknown as {\n __KRYO_MODULES_INITIALIZED__: boolean | undefined;\n};\n\nexport async function initModules(force = false) {\n if (globalForRegistry.__KRYO_MODULES_INITIALIZED__ && !force) return;\n\n if (force) {\n console.log(\"[Kernel:Registry] Forcing re-initialization...\");\n eventBus.clearAll();\n }\n\n console.log(\"[Kernel:Registry] Synchronizing module listeners...\");\n globalForRegistry.__KRYO_MODULES_INITIALIZED__ = true;\n\n await eventBus.publish(\"system:modules:init:start\", {\n timestamp: Date.now(),\n });\n\n const processedModuleIds = new Set<string>();\n let hasNewModules = true;\n let iterations = 0;\n const MAX_ITERATIONS = 10; // Bezpiecznik przed nieskończoną pętlą\n\n while (hasNewModules && iterations < MAX_ITERATIONS) {\n hasNewModules = false;\n iterations++;\n\n // 1. Get ALL currently registered modules (including newly added ones)\n const currentModules = await getModules();\n\n // 2. Filter out modules that are already processed\n const pendingModules = currentModules.filter(\n (mod) => !processedModuleIds.has(mod.id),\n );\n\n if (pendingModules.length === 0) {\n break;\n }\n\n // 3. Synchronize new modules with database\n for (const mod of pendingModules) {\n try {\n await db\n .insert(systemModulesTable)\n .values({\n id: mod.id,\n enabled: mod.system ?? false,\n installed: mod.system ?? false,\n system: mod.system ?? false,\n })\n .onConflictDoNothing();\n } catch (_e) {\n // Table might not exist yet\n }\n }\n\n // 4. Sort pending modules: system modules first\n const sortedPending = [...pendingModules].sort((a, b) =>\n a.system === b.system ? 0 : a.system ? -1 : 1,\n );\n\n // 5. Initialize modules\n for (const mod of sortedPending) {\n // Mark as processed immediately to avoid cycles\n processedModuleIds.add(mod.id);\n hasNewModules = true; // We processed something, so we should check again in case it added more\n\n try {\n const enabled = await isModuleEnabled(mod.id);\n if (!enabled) continue;\n\n const instance = await getModuleInstance(mod.id);\n\n if (!instance) {\n console.warn(\n `[Kernel:Registry] No instance found for module ${mod.id}. Ensure it is registered correctly.`,\n );\n continue;\n }\n\n let dbMod: any = null;\n try {\n [dbMod] = await db\n .select()\n .from(systemModulesTable)\n .where(eq(systemModulesTable.id, mod.id));\n } catch (_e) {\n // Ignore missing table\n }\n\n // onEnable lifecycle\n if (enabled && (!dbMod || !dbMod.installed)) {\n console.log(`[Kernel:Registry] Installing module ${mod.id}...`);\n\n // 1. Run migrations first\n if (instance.onMigrate) {\n console.log(`[Kernel:Registry] Running onMigrate for ${mod.id}...`);\n await instance.onMigrate();\n }\n\n // 2. Run enable hook\n console.log(`[Kernel:Registry] Running onEnable for ${mod.id}...`);\n if (instance.onEnable) await instance.onEnable();\n\n try {\n await db\n .update(systemModulesTable)\n .set({ installed: true, lastStep: null })\n .where(eq(systemModulesTable.id, mod.id));\n } catch (_e) {\n // Ignore missing table\n }\n }\n\n // Operational init\n if (instance.init) {\n console.log(`[Kernel:Registry] Initializing ${mod.id}...`);\n await instance.init();\n console.log(`[Kernel:Registry] Module ${mod.id} is active.`);\n }\n } catch (error) {\n console.error(\n `[Kernel:Registry] Critical failure for ${mod.id}:`,\n error,\n );\n }\n }\n }\n\n if (iterations >= MAX_ITERATIONS) {\n console.warn(\n \"[Kernel:Registry] Max init iterations reached. Check for circular module registrations.\",\n );\n }\n\n await eventBus.publish(\"system:modules:init:end\", {\n timestamp: Date.now(),\n moduleCount: processedModuleIds.size,\n });\n}\n"],"mappings":";;;;;;;;AAOA,MAAM,oBAAoB;AAI1B,eAAsB,YAAY,QAAQ,OAAO;AAC/C,KAAI,kBAAkB,gCAAgC,CAAC,MAAO;AAE9D,KAAI,OAAO;AACT,UAAQ,IAAI,iDAAiD;AAC7D,WAAS,UAAU;;AAGrB,SAAQ,IAAI,sDAAsD;AAClE,mBAAkB,+BAA+B;AAEjD,OAAM,SAAS,QAAQ,6BAA6B,EAClD,WAAW,KAAK,KAAK,EACtB,CAAC;CAEF,MAAM,qCAAqB,IAAI,KAAa;CAC5C,IAAI,gBAAgB;CACpB,IAAI,aAAa;CACjB,MAAM,iBAAiB;AAEvB,QAAO,iBAAiB,aAAa,gBAAgB;AACnD,kBAAgB;AAChB;EAMA,MAAM,kBAHiB,MAAM,YAAY,EAGH,QACnC,QAAQ,CAAC,mBAAmB,IAAI,IAAI,GAAG,CACzC;AAED,MAAI,eAAe,WAAW,EAC5B;AAIF,OAAK,MAAM,OAAO,eAChB,KAAI;AACF,SAAM,GACH,OAAO,mBAAmB,CAC1B,OAAO;IACN,IAAI,IAAI;IACR,SAAS,IAAI,UAAU;IACvB,WAAW,IAAI,UAAU;IACzB,QAAQ,IAAI,UAAU;IACvB,CAAC,CACD,qBAAqB;WACjB,IAAI;EAMf,MAAM,gBAAgB,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,MACjD,EAAE,WAAW,EAAE,SAAS,IAAI,EAAE,SAAS,KAAK,EAC7C;AAGD,OAAK,MAAM,OAAO,eAAe;AAE/B,sBAAmB,IAAI,IAAI,GAAG;AAC9B,mBAAgB;AAEhB,OAAI;IACF,MAAM,UAAU,MAAM,gBAAgB,IAAI,GAAG;AAC7C,QAAI,CAAC,QAAS;IAEd,MAAM,WAAW,MAAM,kBAAkB,IAAI,GAAG;AAEhD,QAAI,CAAC,UAAU;AACb,aAAQ,KACN,kDAAkD,IAAI,GAAG,sCAC1D;AACD;;IAGF,IAAI,QAAa;AACjB,QAAI;AACF,MAAC,SAAS,MAAM,GACb,QAAQ,CACR,KAAK,mBAAmB,CACxB,MAAM,GAAG,mBAAmB,IAAI,IAAI,GAAG,CAAC;aACpC,IAAI;AAKb,QAAI,YAAY,CAAC,SAAS,CAAC,MAAM,YAAY;AAC3C,aAAQ,IAAI,uCAAuC,IAAI,GAAG,KAAK;AAG/D,SAAI,SAAS,WAAW;AACtB,cAAQ,IAAI,2CAA2C,IAAI,GAAG,KAAK;AACnE,YAAM,SAAS,WAAW;;AAI5B,aAAQ,IAAI,0CAA0C,IAAI,GAAG,KAAK;AAClE,SAAI,SAAS,SAAU,OAAM,SAAS,UAAU;AAEhD,SAAI;AACF,YAAM,GACH,OAAO,mBAAmB,CAC1B,IAAI;OAAE,WAAW;OAAM,UAAU;OAAM,CAAC,CACxC,MAAM,GAAG,mBAAmB,IAAI,IAAI,GAAG,CAAC;cACpC,IAAI;;AAMf,QAAI,SAAS,MAAM;AACjB,aAAQ,IAAI,kCAAkC,IAAI,GAAG,KAAK;AAC1D,WAAM,SAAS,MAAM;AACrB,aAAQ,IAAI,4BAA4B,IAAI,GAAG,aAAa;;YAEvD,OAAO;AACd,YAAQ,MACN,0CAA0C,IAAI,GAAG,IACjD,MACD;;;;AAKP,KAAI,cAAc,eAChB,SAAQ,KACN,0FACD;AAGH,OAAM,SAAS,QAAQ,2BAA2B;EAChD,WAAW,KAAK,KAAK;EACrB,aAAa,mBAAmB;EACjC,CAAC"}
@@ -0,0 +1,180 @@
1
+ "use server";
2
+
3
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
4
+ const require_manage = require('./manage.cjs');
5
+ let _arch_cadre_core_server = require("@arch-cadre/core/server");
6
+
7
+ //#region src/server/ui.ts
8
+ /**
9
+ * Helper to check and filter a navigation item based on roles and permissions.
10
+ * Returns the item (potentially with filtered sub-items) or null if access is denied.
11
+ */
12
+ function filterNavItem(item, userRoles, userPermissions) {
13
+ if (item.roles && item.roles.length > 0) {
14
+ if (!item.roles.some((role) => userRoles.includes(role))) return null;
15
+ }
16
+ if (item.permissions && item.permissions.length > 0) {
17
+ if (!item.permissions.every((perm) => userPermissions.includes(perm))) return null;
18
+ }
19
+ if (item.items && item.items.length > 0) {
20
+ const filteredSubItems = item.items.map((subItem) => filterNavItem(subItem, userRoles, userPermissions)).filter((subItem) => subItem !== null);
21
+ return {
22
+ ...item,
23
+ items: filteredSubItems
24
+ };
25
+ }
26
+ return item;
27
+ }
28
+ async function getModuleNavigationGrouped(type) {
29
+ const { user } = await (0, _arch_cadre_core_server.getCurrentSession)();
30
+ const userRoles = user?.roles || [];
31
+ const userPermissions = user?.permissions || [];
32
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
33
+ const groups = {};
34
+ for (const mod of active) try {
35
+ const instanceNav = (await require_manage.getModuleInstance(mod.id))?.navigation?.[type];
36
+ if (instanceNav) for (const [groupName, items] of Object.entries(instanceNav)) {
37
+ if (!groups[groupName]) groups[groupName] = [];
38
+ for (const rawItem of items) {
39
+ const item = filterNavItem(rawItem, userRoles, userPermissions);
40
+ if (item && !groups[groupName].some((existing) => existing.url === item.url)) groups[groupName].push(item);
41
+ }
42
+ }
43
+ } catch (_e) {
44
+ console.warn(`[Kernel:UI] Failed to load navigation for module ${mod.id}:`, _e);
45
+ }
46
+ return groups;
47
+ }
48
+ async function getKryoPathPrefix() {
49
+ try {
50
+ return (await require_manage.getModuleConfig("kryo-panel"))?.pathPrefix ?? "/kryo";
51
+ } catch (_e) {
52
+ return "/kryo";
53
+ }
54
+ }
55
+ async function getKryoModuleNavigationGrouped(type) {
56
+ const groups = await getModuleNavigationGrouped(type);
57
+ const prefix = await getKryoPathPrefix();
58
+ const prefixUrl = (url) => {
59
+ if (url.startsWith(prefix)) return url;
60
+ return url === "/" ? prefix : `${prefix}${url}`;
61
+ };
62
+ const processItems = (items) => {
63
+ return items.map((item) => ({
64
+ ...item,
65
+ url: prefixUrl(item.url),
66
+ items: item.items ? processItems(item.items) : void 0
67
+ }));
68
+ };
69
+ const transformedGroups = {};
70
+ for (const [group, items] of Object.entries(groups)) transformedGroups[group] = processItems(items);
71
+ return transformedGroups;
72
+ }
73
+ async function getModuleNavigation(type) {
74
+ const { user } = await (0, _arch_cadre_core_server.getCurrentSession)();
75
+ const userRoles = user?.roles || [];
76
+ const userPermissions = user?.permissions || [];
77
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
78
+ const all = [];
79
+ for (const mod of active) try {
80
+ const instance = await require_manage.getModuleInstance(mod.id);
81
+ if (instance?.navigation?.[type]) {
82
+ const items = instance.navigation[type];
83
+ for (const rawItem of items) {
84
+ const item = filterNavItem(rawItem, userRoles, userPermissions);
85
+ if (item) all.push(item);
86
+ }
87
+ }
88
+ } catch {}
89
+ return all;
90
+ }
91
+ async function getPublicModuleRoutes() {
92
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
93
+ const allRoutes = [];
94
+ for (const mod of active) try {
95
+ const instance = await require_manage.getModuleInstance(mod.id);
96
+ if (instance?.routes?.public) allRoutes.push(...instance.routes.public);
97
+ } catch {}
98
+ return allRoutes;
99
+ }
100
+ async function getPrivateModuleRoutes() {
101
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
102
+ const allRoutes = [];
103
+ for (const mod of active) try {
104
+ const instance = await require_manage.getModuleInstance(mod.id);
105
+ if (instance?.routes?.private) allRoutes.push(...instance.routes.private);
106
+ } catch {}
107
+ return allRoutes;
108
+ }
109
+ async function getKryoModuleRoutes() {
110
+ const routes = await getPrivateModuleRoutes();
111
+ const prefix = await getKryoPathPrefix();
112
+ return routes.map((route) => ({
113
+ ...route,
114
+ path: route.path === "/" ? prefix : `${prefix}${route.path}`
115
+ }));
116
+ }
117
+ async function getApiModuleRoutes() {
118
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
119
+ const allRoutes = [];
120
+ for (const mod of active) try {
121
+ const instance = await require_manage.getModuleInstance(mod.id);
122
+ if (instance?.routes?.api) allRoutes.push(...instance.routes.api);
123
+ } catch {}
124
+ return allRoutes;
125
+ }
126
+ async function getModuleWidgets(area) {
127
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
128
+ const widgets = [];
129
+ for (const mod of active) try {
130
+ const instance = await require_manage.getModuleInstance(mod.id);
131
+ if (instance?.widgets) {
132
+ const matching = instance.widgets.filter((w) => w.area === area);
133
+ widgets.push(...matching);
134
+ }
135
+ } catch (_e) {}
136
+ return widgets.sort((a, b) => (a.priority || 0) - (b.priority || 0));
137
+ }
138
+ async function getExtensions(targetModule, point) {
139
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
140
+ const extensions = [];
141
+ for (const mod of active) try {
142
+ const instance = await require_manage.getModuleInstance(mod.id);
143
+ if (instance?.extensions) {
144
+ const matching = instance.extensions.filter((ext) => {
145
+ const isTarget = ext.targetModule === targetModule;
146
+ const isPoint = point ? ext.point === point : true;
147
+ return isTarget && isPoint;
148
+ });
149
+ extensions.push(...matching);
150
+ }
151
+ } catch (_e) {}
152
+ return extensions.sort((a, b) => (a.priority || 0) - (b.priority || 0));
153
+ }
154
+ async function hasExtension(targetModule, point) {
155
+ const active = (await require_manage.getModules()).filter((m) => m.enabled);
156
+ for (const mod of active) try {
157
+ const instance = await require_manage.getModuleInstance(mod.id);
158
+ if (instance?.extensions) {
159
+ if (instance.extensions.filter((ext) => {
160
+ const isTarget = ext.targetModule === targetModule;
161
+ const isPoint = point ? ext.point === point : true;
162
+ return isTarget && isPoint;
163
+ }).length > 0) return true;
164
+ }
165
+ } catch (_e) {}
166
+ return false;
167
+ }
168
+
169
+ //#endregion
170
+ exports.getApiModuleRoutes = getApiModuleRoutes;
171
+ exports.getExtensions = getExtensions;
172
+ exports.getKryoModuleNavigationGrouped = getKryoModuleNavigationGrouped;
173
+ exports.getKryoModuleRoutes = getKryoModuleRoutes;
174
+ exports.getKryoPathPrefix = getKryoPathPrefix;
175
+ exports.getModuleNavigation = getModuleNavigation;
176
+ exports.getModuleNavigationGrouped = getModuleNavigationGrouped;
177
+ exports.getModuleWidgets = getModuleWidgets;
178
+ exports.getPrivateModuleRoutes = getPrivateModuleRoutes;
179
+ exports.getPublicModuleRoutes = getPublicModuleRoutes;
180
+ exports.hasExtension = hasExtension;
@@ -0,0 +1,17 @@
1
+ import { ApiRouteDefinition, ModuleExtension, ModuleNavElement, ModuleWidget, PrivateRouteDefinition, PublicRouteDefinition } from "../types.cjs";
2
+
3
+ //#region src/server/ui.d.ts
4
+ declare function getModuleNavigationGrouped(type: "admin" | "settings"): Promise<Record<string, ModuleNavElement[]>>;
5
+ declare function getKryoPathPrefix(): Promise<string>;
6
+ declare function getKryoModuleNavigationGrouped(type: "admin" | "settings"): Promise<Record<string, ModuleNavElement[]>>;
7
+ declare function getModuleNavigation(type: "public"): Promise<ModuleNavElement[]>;
8
+ declare function getPublicModuleRoutes(): Promise<PublicRouteDefinition[]>;
9
+ declare function getPrivateModuleRoutes(): Promise<PrivateRouteDefinition[]>;
10
+ declare function getKryoModuleRoutes(): Promise<PrivateRouteDefinition[]>;
11
+ declare function getApiModuleRoutes(): Promise<ApiRouteDefinition[]>;
12
+ declare function getModuleWidgets(area: string): Promise<ModuleWidget[]>;
13
+ declare function getExtensions(targetModule: string, point?: string): Promise<ModuleExtension[]>;
14
+ declare function hasExtension(targetModule: string, point?: string): Promise<boolean>;
15
+ //#endregion
16
+ export { getApiModuleRoutes, getExtensions, getKryoModuleNavigationGrouped, getKryoModuleRoutes, getKryoPathPrefix, getModuleNavigation, getModuleNavigationGrouped, getModuleWidgets, getPrivateModuleRoutes, getPublicModuleRoutes, hasExtension };
17
+ //# sourceMappingURL=ui.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.cts","names":[],"sources":["../../src/server/ui.ts"],"mappings":";;;iBAqDsB,0BAAA,CAA2B,IAAA,yBAA0B,OAAA,CAAA,MAAA,SAAA,gBAAA;AAAA,iBAyCrD,iBAAA,CAAA,GAAqB,OAAA;AAAA,iBASrB,8BAAA,CACpB,IAAA,yBAA0B,OAAA,CAAA,MAAA,SAAA,gBAAA;AAAA,iBA4BN,mBAAA,CACpB,IAAA,aACC,OAAA,CAAQ,gBAAA;AAAA,iBAwBW,qBAAA,CAAA,GAAyB,OAAA,CAC7C,qBAAA;AAAA,iBAmBoB,sBAAA,CAAA,GAA0B,OAAA,CAC9C,sBAAA;AAAA,iBAmBoB,mBAAA,CAAA,GAAuB,OAAA,CAAQ,sBAAA;AAAA,iBAU/B,kBAAA,CAAA,GAAsB,OAAA,CAAQ,kBAAA;AAAA,iBAgB9B,gBAAA,CAAiB,IAAA,WAAY,OAAA,CAAA,YAAA;AAAA,iBAqB7B,aAAA,CAAc,YAAA,UAAsB,KAAA,YAAc,OAAA,CAAA,eAAA;AAAA,iBAuBlD,YAAA,CAAa,YAAA,UAAsB,KAAA,YAAc,OAAA"}
@@ -0,0 +1,17 @@
1
+ import { ApiRouteDefinition, ModuleExtension, ModuleNavElement, ModuleWidget, PrivateRouteDefinition, PublicRouteDefinition } from "../types.mjs";
2
+
3
+ //#region src/server/ui.d.ts
4
+ declare function getModuleNavigationGrouped(type: "admin" | "settings"): Promise<Record<string, ModuleNavElement[]>>;
5
+ declare function getKryoPathPrefix(): Promise<string>;
6
+ declare function getKryoModuleNavigationGrouped(type: "admin" | "settings"): Promise<Record<string, ModuleNavElement[]>>;
7
+ declare function getModuleNavigation(type: "public"): Promise<ModuleNavElement[]>;
8
+ declare function getPublicModuleRoutes(): Promise<PublicRouteDefinition[]>;
9
+ declare function getPrivateModuleRoutes(): Promise<PrivateRouteDefinition[]>;
10
+ declare function getKryoModuleRoutes(): Promise<PrivateRouteDefinition[]>;
11
+ declare function getApiModuleRoutes(): Promise<ApiRouteDefinition[]>;
12
+ declare function getModuleWidgets(area: string): Promise<ModuleWidget[]>;
13
+ declare function getExtensions(targetModule: string, point?: string): Promise<ModuleExtension[]>;
14
+ declare function hasExtension(targetModule: string, point?: string): Promise<boolean>;
15
+ //#endregion
16
+ export { getApiModuleRoutes, getExtensions, getKryoModuleNavigationGrouped, getKryoModuleRoutes, getKryoPathPrefix, getModuleNavigation, getModuleNavigationGrouped, getModuleWidgets, getPrivateModuleRoutes, getPublicModuleRoutes, hasExtension };
17
+ //# sourceMappingURL=ui.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.mts","names":[],"sources":["../../src/server/ui.ts"],"mappings":";;;iBAqDsB,0BAAA,CAA2B,IAAA,yBAA0B,OAAA,CAAA,MAAA,SAAA,gBAAA;AAAA,iBAyCrD,iBAAA,CAAA,GAAqB,OAAA;AAAA,iBASrB,8BAAA,CACpB,IAAA,yBAA0B,OAAA,CAAA,MAAA,SAAA,gBAAA;AAAA,iBA4BN,mBAAA,CACpB,IAAA,aACC,OAAA,CAAQ,gBAAA;AAAA,iBAwBW,qBAAA,CAAA,GAAyB,OAAA,CAC7C,qBAAA;AAAA,iBAmBoB,sBAAA,CAAA,GAA0B,OAAA,CAC9C,sBAAA;AAAA,iBAmBoB,mBAAA,CAAA,GAAuB,OAAA,CAAQ,sBAAA;AAAA,iBAU/B,kBAAA,CAAA,GAAsB,OAAA,CAAQ,kBAAA;AAAA,iBAgB9B,gBAAA,CAAiB,IAAA,WAAY,OAAA,CAAA,YAAA;AAAA,iBAqB7B,aAAA,CAAc,YAAA,UAAsB,KAAA,YAAc,OAAA,CAAA,eAAA;AAAA,iBAuBlD,YAAA,CAAa,YAAA,UAAsB,KAAA,YAAc,OAAA"}
@@ -1,132 +1,8 @@
1
- import { db, getCurrentSession, getModulesDir } from "@arch-cadre/core/server";
2
- import fs from "node:fs/promises";
3
- import path from "node:path";
4
- import { systemModulesTable } from "@arch-cadre/core";
5
- import { eq } from "drizzle-orm";
6
- import { z } from "zod";
1
+ "use server";
7
2
 
8
- //#region src/types.ts
9
- const ModuleManifestSchema = z.object({
10
- id: z.string(),
11
- name: z.string(),
12
- version: z.string(),
13
- description: z.string().optional(),
14
- dependencies: z.array(z.string()).default([]),
15
- extends: z.array(z.string()).default([]),
16
- enabled: z.boolean().default(true),
17
- system: z.boolean().default(false),
18
- npmDependencies: z.array(z.string()).optional(),
19
- npmDevDependencies: z.array(z.string()).optional()
20
- });
3
+ import { getModuleConfig, getModuleInstance, getModules } from "./manage.mjs";
4
+ import { getCurrentSession } from "@arch-cadre/core/server";
21
5
 
22
- //#endregion
23
- //#region src/server/manage.ts
24
- const globalForModules = globalThis;
25
- if (!globalForModules.__KRYO_REGISTERED_MODULES__) globalForModules.__KRYO_REGISTERED_MODULES__ = /* @__PURE__ */ new Map();
26
- async function registerModules(modules) {
27
- const store = globalForModules.__KRYO_REGISTERED_MODULES__;
28
- for (const mod of modules) if (mod.manifest?.id) store.set(mod.manifest.id, mod);
29
- }
30
- async function getModules() {
31
- try {
32
- const modulesDir = await getModulesDir();
33
- const manifests = [];
34
- const entries = await fs.readdir(modulesDir).catch(() => []);
35
- for (const dir of entries) {
36
- if (dir.startsWith(".")) continue;
37
- try {
38
- const content = await fs.readFile(path.join(modulesDir, dir, "manifest.json"), "utf-8");
39
- const manifest = ModuleManifestSchema.parse(JSON.parse(content));
40
- manifests.push({
41
- ...manifest,
42
- hasDocs: false
43
- });
44
- } catch {}
45
- }
46
- const store = globalForModules.__KRYO_REGISTERED_MODULES__;
47
- for (const mod of store.values()) if (!manifests.some((m) => m.id === mod.manifest.id)) manifests.push({
48
- ...mod.manifest,
49
- hasDocs: false
50
- });
51
- const dbModules = await db.select().from(systemModulesTable).catch(() => []);
52
- const dbMap = new Map(dbModules.map((m) => [m.id, m]));
53
- return manifests.map((mod) => {
54
- const dbEntry = dbMap.get(mod.id);
55
- return {
56
- ...mod,
57
- enabled: mod.system ? true : dbEntry?.enabled ?? false,
58
- installed: mod.system ? true : dbEntry?.installed ?? false,
59
- lastStep: dbEntry?.lastStep,
60
- hasDocs: mod.hasDocs
61
- };
62
- });
63
- } catch {
64
- return [];
65
- }
66
- }
67
- async function getModuleStatus(moduleId) {
68
- try {
69
- const [mod] = await db.select().from(systemModulesTable).where(eq(systemModulesTable.id, moduleId));
70
- return {
71
- enabled: mod?.enabled,
72
- installed: mod?.installed,
73
- lastStep: mod?.lastStep
74
- };
75
- } catch {
76
- return {
77
- enabled: false,
78
- installed: false,
79
- lastStep: null
80
- };
81
- }
82
- }
83
- async function isModuleEnabled(moduleId) {
84
- try {
85
- const [mod] = await db.select().from(systemModulesTable).where(eq(systemModulesTable.id, moduleId));
86
- return !!mod?.enabled || !!mod?.system;
87
- } catch {
88
- return false;
89
- }
90
- }
91
- async function getModuleInstance(moduleId) {
92
- try {
93
- const store = globalForModules.__KRYO_REGISTERED_MODULES__;
94
- if (store.has(moduleId)) {
95
- console.log(`[Kernel:Manage] Module "${moduleId}" found in registry.`);
96
- return store.get(moduleId) || null;
97
- }
98
- console.log(`[Kernel:Manage] Module "${moduleId}" not in registry. Registry size: ${store.size}. Keys: ${Array.from(store.keys()).join(", ")}`);
99
- if (!moduleId.startsWith(".") && !moduleId.startsWith("/")) try {
100
- const mod = await import(`@arch-cadre/${moduleId}`);
101
- console.log(`[Kernel:Manage] Module "${moduleId}" loaded via import().`);
102
- return mod.default || mod || null;
103
- } catch (e) {
104
- console.warn(`[Kernel:Manage] Failed to import module "${moduleId} via import().": ${e.message}`);
105
- }
106
- return null;
107
- } catch (error) {
108
- console.error(`[Kernel:Manage] Error in getModuleInstance for "${moduleId}":`, error);
109
- return null;
110
- }
111
- }
112
- async function getModuleConfig(moduleId) {
113
- try {
114
- const [mod] = await db.select({ config: systemModulesTable.config }).from(systemModulesTable).where(eq(systemModulesTable.id, moduleId));
115
- if (!mod?.config) return null;
116
- return JSON.parse(mod.config);
117
- } catch {
118
- return null;
119
- }
120
- }
121
- async function updateModuleConfig(moduleId, config) {
122
- try {
123
- await db.update(systemModulesTable).set({ config: JSON.stringify(config) }).where(eq(systemModulesTable.id, moduleId));
124
- } catch (e) {
125
- console.warn(`[Kernel:Manage] Failed to update config for ${moduleId}:`, e);
126
- }
127
- }
128
-
129
- //#endregion
130
6
  //#region src/server/ui.ts
131
7
  /**
132
8
  * Helper to check and filter a navigation item based on roles and permissions.
@@ -290,5 +166,5 @@ async function hasExtension(targetModule, point) {
290
166
  }
291
167
 
292
168
  //#endregion
293
- export { registerModules as _, getKryoPathPrefix as a, getModuleWidgets as c, hasExtension as d, getModuleConfig as f, isModuleEnabled as g, getModules as h, getKryoModuleRoutes as i, getPrivateModuleRoutes as l, getModuleStatus as m, getExtensions as n, getModuleNavigation as o, getModuleInstance as p, getKryoModuleNavigationGrouped as r, getModuleNavigationGrouped as s, getApiModuleRoutes as t, getPublicModuleRoutes as u, updateModuleConfig as v, ModuleManifestSchema as y };
294
- //# sourceMappingURL=ui-lsiPxu_C.mjs.map
169
+ export { getApiModuleRoutes, getExtensions, getKryoModuleNavigationGrouped, getKryoModuleRoutes, getKryoPathPrefix, getModuleNavigation, getModuleNavigationGrouped, getModuleWidgets, getPrivateModuleRoutes, getPublicModuleRoutes, hasExtension };
170
+ //# sourceMappingURL=ui.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.mjs","names":[],"sources":["../../src/server/ui.ts"],"sourcesContent":["\"use server\";\n\nimport { getCurrentSession } from \"@arch-cadre/core/server\";\nimport type {\n ApiRouteDefinition,\n ModuleExtension,\n ModuleNavElement,\n ModuleNavigationGroupMap,\n ModuleWidget,\n PrivateRouteDefinition,\n PublicRouteDefinition,\n} from \"../types\";\nimport { getModuleConfig, getModuleInstance, getModules } from \"./manage\";\n\n/**\n * Helper to check and filter a navigation item based on roles and permissions.\n * Returns the item (potentially with filtered sub-items) or null if access is denied.\n */\nfunction filterNavItem(\n item: ModuleNavElement,\n userRoles: string[],\n userPermissions: string[],\n): ModuleNavElement | null {\n // 1. Check access for the item itself\n if (item.roles && item.roles.length > 0) {\n if (!item.roles.some((role) => userRoles.includes(role))) {\n return null;\n }\n }\n\n if (item.permissions && item.permissions.length > 0) {\n if (!item.permissions.every((perm) => userPermissions.includes(perm))) {\n return null;\n }\n }\n\n // 2. Recursively filter sub-items if they exist\n if (item.items && item.items.length > 0) {\n const filteredSubItems = item.items\n .map((subItem) =>\n filterNavItem(subItem as any, userRoles, userPermissions),\n )\n .filter((subItem): subItem is ModuleNavElement => subItem !== null);\n\n return {\n ...item,\n items: filteredSubItems as any,\n };\n }\n\n return item;\n}\n\nexport async function getModuleNavigationGrouped(type: \"admin\" | \"settings\") {\n const { user } = await getCurrentSession();\n const userRoles = user?.roles || [];\n const userPermissions = user?.permissions || [];\n\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n const groups: Record<string, ModuleNavElement[]> = {};\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n\n // 1. From instance\n const instanceNav = instance?.navigation?.[type];\n if (instanceNav) {\n for (const [groupName, items] of Object.entries(\n instanceNav as ModuleNavigationGroupMap,\n )) {\n if (!groups[groupName]) groups[groupName] = [];\n for (const rawItem of items) {\n const item = filterNavItem(rawItem, userRoles, userPermissions);\n if (\n item &&\n !groups[groupName].some((existing) => existing.url === item.url)\n ) {\n groups[groupName].push(item);\n }\n }\n }\n }\n } catch (_e) {\n console.warn(\n `[Kernel:UI] Failed to load navigation for module ${mod.id}:`,\n _e,\n );\n }\n }\n return groups;\n}\n\nexport async function getKryoPathPrefix(): Promise<string> {\n try {\n const config = await getModuleConfig<{ pathPrefix: string }>(\"kryo-panel\");\n return config?.pathPrefix ?? \"/kryo\";\n } catch (_e) {\n return \"/kryo\";\n }\n}\n\nexport async function getKryoModuleNavigationGrouped(\n type: \"admin\" | \"settings\",\n) {\n const groups = await getModuleNavigationGrouped(type);\n const prefix = await getKryoPathPrefix();\n\n const prefixUrl = (url: string) => {\n if (url.startsWith(prefix)) return url;\n return url === \"/\" ? prefix : `${prefix}${url}`;\n };\n\n const processItems = (items: ModuleNavElement[]): ModuleNavElement[] => {\n return items.map((item) => ({\n ...item,\n url: prefixUrl(item.url),\n items: item.items\n ? processItems(item.items as ModuleNavElement[])\n : undefined,\n })) as ModuleNavElement[];\n };\n\n const transformedGroups: Record<string, ModuleNavElement[]> = {};\n for (const [group, items] of Object.entries(groups)) {\n transformedGroups[group] = processItems(items);\n }\n\n return transformedGroups;\n}\n\nexport async function getModuleNavigation(\n type: \"public\",\n): Promise<ModuleNavElement[]> {\n const { user } = await getCurrentSession();\n const userRoles = user?.roles || [];\n const userPermissions = user?.permissions || [];\n\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n const all: ModuleNavElement[] = [];\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n if (instance?.navigation?.[type]) {\n const items = instance.navigation[type] as ModuleNavElement[];\n for (const rawItem of items) {\n const item = filterNavItem(rawItem, userRoles, userPermissions);\n if (item) all.push(item);\n }\n }\n } catch {}\n }\n return all;\n}\n\nexport async function getPublicModuleRoutes(): Promise<\n PublicRouteDefinition[]\n> {\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n const allRoutes: PublicRouteDefinition[] = [];\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n\n // 1. Try from instance (if pre-defined)\n if (instance?.routes?.public) {\n allRoutes.push(...instance.routes.public);\n }\n } catch {}\n }\n return allRoutes;\n}\n\nexport async function getPrivateModuleRoutes(): Promise<\n PrivateRouteDefinition[]\n> {\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n const allRoutes: PrivateRouteDefinition[] = [];\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n\n // 1. Try from instance\n if (instance?.routes?.private) {\n allRoutes.push(...instance.routes.private);\n }\n } catch {}\n }\n return allRoutes;\n}\n\nexport async function getKryoModuleRoutes(): Promise<PrivateRouteDefinition[]> {\n const routes = await getPrivateModuleRoutes();\n const prefix = await getKryoPathPrefix();\n\n return routes.map((route) => ({\n ...route,\n path: route.path === \"/\" ? prefix : `${prefix}${route.path}`,\n }));\n}\n\nexport async function getApiModuleRoutes(): Promise<ApiRouteDefinition[]> {\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n const allRoutes: ApiRouteDefinition[] = [];\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n if (instance?.routes?.api) {\n allRoutes.push(...instance.routes.api);\n }\n } catch {}\n }\n return allRoutes;\n}\n\nexport async function getModuleWidgets(area: string) {\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n const widgets: ModuleWidget[] = [];\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n\n if (instance?.widgets) {\n const matching = instance.widgets.filter(\n (w: ModuleWidget) => w.area === area,\n );\n widgets.push(...matching);\n }\n } catch (_e) {}\n }\n\n return widgets.sort((a, b) => (a.priority || 0) - (b.priority || 0));\n}\n\nexport async function getExtensions(targetModule: string, point?: string) {\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n const extensions: ModuleExtension[] = [];\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n\n if (instance?.extensions) {\n const matching = instance.extensions.filter((ext: ModuleExtension) => {\n const isTarget = ext.targetModule === targetModule;\n const isPoint = point ? ext.point === point : true;\n return isTarget && isPoint;\n });\n extensions.push(...matching);\n }\n } catch (_e) {}\n }\n\n return extensions.sort((a, b) => (a.priority || 0) - (b.priority || 0));\n}\n\nexport async function hasExtension(targetModule: string, point?: string) {\n const modules = await getModules();\n const active = modules.filter((m) => m.enabled);\n\n for (const mod of active) {\n try {\n const instance = await getModuleInstance(mod.id);\n\n if (instance?.extensions) {\n const matching = instance.extensions.filter((ext: ModuleExtension) => {\n const isTarget = ext.targetModule === targetModule;\n const isPoint = point ? ext.point === point : true;\n return isTarget && isPoint;\n });\n if (matching.length > 0) return true;\n }\n } catch (_e) {}\n }\n\n return false;\n}\n"],"mappings":"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"}