a3aff9fa49
- add `src/core/modules/` with registry, discovery (server), and public index - add `src/core/public-pages/` with registry, server component, and public index - add `src/core/users/permissions-registry.js` for runtime permission registration - expose `./modules`, `./public-pages`, and `./public-pages/server` package exports - rename `registerFeatureRoutes` to `registerApiRoutes` with backward-compatible alias - extend `seedDefaultRolesAndPermissions` to include module-registered permissions - update `initializeZen` and shared init to wire module discovery and registration - add `docs/MODULES.md` documenting the `@zen/module-*` authoring contract - update `docs/DEV.md` with references to module system docs
37 lines
1.5 KiB
JavaScript
37 lines
1.5 KiB
JavaScript
/**
|
|
* Registre runtime des pages publiques `/zen/<module>/<...>`.
|
|
*
|
|
* Chaque module externe enregistre un composant racine pour son namespace.
|
|
* Le composant reçoit `{ params, segments }` où `segments` est le tableau
|
|
* de chemins après `/zen/<module>/` ; le module fait son propre routage interne.
|
|
*
|
|
* Le préfixe `api` est réservé : tout enregistrement sous moduleName === 'api'
|
|
* est rejeté pour éviter les collisions avec les routes API.
|
|
*/
|
|
|
|
const REGISTRY_KEY = Symbol.for('__ZEN_PUBLIC_MODULE_PAGES__');
|
|
if (!globalThis[REGISTRY_KEY]) globalThis[REGISTRY_KEY] = new Map();
|
|
/** @type {Map<string, { moduleName: string, Component: any, title?: string }>} */
|
|
const registry = globalThis[REGISTRY_KEY];
|
|
|
|
export function registerPublicModulePage({ moduleName, Component, title }) {
|
|
if (typeof moduleName !== 'string' || !moduleName) {
|
|
throw new TypeError('registerPublicModulePage: "moduleName" must be a non-empty string');
|
|
}
|
|
if (moduleName === 'api') {
|
|
throw new Error('registerPublicModulePage: "api" is a reserved namespace under /zen/');
|
|
}
|
|
if (typeof Component !== 'function' && typeof Component !== 'object') {
|
|
throw new TypeError(`registerPublicModulePage(${moduleName}): "Component" must be a React component`);
|
|
}
|
|
registry.set(moduleName, { moduleName, Component, title });
|
|
}
|
|
|
|
export function getPublicModulePage(moduleName) {
|
|
return registry.get(moduleName);
|
|
}
|
|
|
|
export function getPublicModulePages() {
|
|
return [...registry.values()];
|
|
}
|