wu-framework 2.5.0 → 2.6.0
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.d.cts +20 -0
- package/dist/index.d.ts +20 -0
- package/dist/wu-framework.cjs +2 -2
- package/dist/wu-framework.cjs.map +1 -1
- package/dist/wu-framework.dev.js +93 -4
- package/dist/wu-framework.dev.js.map +1 -1
- package/dist/wu-framework.esm.js +2 -2
- package/dist/wu-framework.esm.js.map +1 -1
- package/dist/wu-framework.umd.js +2 -2
- package/dist/wu-framework.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/wu-framework.dev.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! wu-framework v2.
|
|
1
|
+
/*! wu-framework v2.6.0 | MIT License */
|
|
2
2
|
import { logger } from './core/wu-logger.js';
|
|
3
3
|
export { enableAllLogs, silenceAllLogs } from './core/wu-logger.js';
|
|
4
4
|
export { WuLoader } from './core/wu-loader.js';
|
|
@@ -7400,6 +7400,11 @@ class WuCore {
|
|
|
7400
7400
|
// Estado
|
|
7401
7401
|
this.isInitialized = false;
|
|
7402
7402
|
|
|
7403
|
+
// RBAC: principal actual (quién usa el sistema). Las apps que declaran
|
|
7404
|
+
// `roles` (en su config o manifest) solo se montan si el principal está
|
|
7405
|
+
// autorizado. null = sin principal (las apps restringidas se niegan).
|
|
7406
|
+
this._principal = null;
|
|
7407
|
+
|
|
7403
7408
|
logger.wuInfo('Wu Framework initialized - Universal Microfrontends');
|
|
7404
7409
|
}
|
|
7405
7410
|
|
|
@@ -7495,6 +7500,63 @@ class WuCore {
|
|
|
7495
7500
|
}
|
|
7496
7501
|
}
|
|
7497
7502
|
|
|
7503
|
+
// ── RBAC: aislamiento rol↔módulo (declarativo, enforced en mount) ──────────
|
|
7504
|
+
|
|
7505
|
+
/**
|
|
7506
|
+
* Fija el principal actual (rol/permisos del usuario). Las apps que declaran
|
|
7507
|
+
* `roles` solo se montan si el principal está autorizado. Se refleja también
|
|
7508
|
+
* en wu.store('auth.principal') para que apps/DevTools lo lean.
|
|
7509
|
+
* @param {{role?: string, roles?: string[], permissions?: string[]}|null} principal
|
|
7510
|
+
* @returns {Object|null} el principal efectivo
|
|
7511
|
+
*/
|
|
7512
|
+
setPrincipal(principal) {
|
|
7513
|
+
this._principal = principal || null;
|
|
7514
|
+
try { this.store.set('auth.principal', this._principal); } catch { /* store opcional */ }
|
|
7515
|
+
this.eventBus.emit('principal:changed', { principal: this._principal });
|
|
7516
|
+
return this._principal;
|
|
7517
|
+
}
|
|
7518
|
+
|
|
7519
|
+
/** @returns {Object|null} el principal actual */
|
|
7520
|
+
getPrincipal() {
|
|
7521
|
+
return this._principal;
|
|
7522
|
+
}
|
|
7523
|
+
|
|
7524
|
+
/** Roles permitidos para montar `appName` (de config o manifest), o null si es público. */
|
|
7525
|
+
_requiredRoles(appName) {
|
|
7526
|
+
const app = this.apps.get(appName);
|
|
7527
|
+
const manifest = this.manifests.get(appName);
|
|
7528
|
+
const roles = app?.roles ?? manifest?.wu?.roles ?? manifest?.roles ?? null;
|
|
7529
|
+
return Array.isArray(roles) && roles.length ? roles : null;
|
|
7530
|
+
}
|
|
7531
|
+
|
|
7532
|
+
/** Roles que porta el principal actual (role + roles[]). */
|
|
7533
|
+
_principalRoles() {
|
|
7534
|
+
const p = this._principal;
|
|
7535
|
+
if (!p) return [];
|
|
7536
|
+
const out = [];
|
|
7537
|
+
if (typeof p.role === 'string') out.push(p.role);
|
|
7538
|
+
if (Array.isArray(p.roles)) out.push(...p.roles);
|
|
7539
|
+
return out;
|
|
7540
|
+
}
|
|
7541
|
+
|
|
7542
|
+
/**
|
|
7543
|
+
* ¿Puede el principal actual montar/acceder a `appName`?
|
|
7544
|
+
* App pública (sin `roles`) → siempre true. App restringida → requiere un
|
|
7545
|
+
* principal cuyos roles intersecten, o un permiso `mount:*` / `mount:<app>`.
|
|
7546
|
+
* @param {string} appName
|
|
7547
|
+
* @returns {boolean}
|
|
7548
|
+
*/
|
|
7549
|
+
can(appName) {
|
|
7550
|
+
const required = this._requiredRoles(appName);
|
|
7551
|
+
if (!required) return true; // módulo público
|
|
7552
|
+
const p = this._principal;
|
|
7553
|
+
if (!p) return false; // restringido y sin principal
|
|
7554
|
+
const perms = Array.isArray(p.permissions) ? p.permissions : [];
|
|
7555
|
+
if (perms.includes('mount:*') || perms.includes(`mount:${appName}`)) return true;
|
|
7556
|
+
const roles = this._principalRoles();
|
|
7557
|
+
return roles.some((r) => required.includes(r));
|
|
7558
|
+
}
|
|
7559
|
+
|
|
7498
7560
|
/**
|
|
7499
7561
|
* Definir lifecycle de una micro-app
|
|
7500
7562
|
* @param {string} appName - Nombre de la app
|
|
@@ -7533,6 +7595,27 @@ class WuCore {
|
|
|
7533
7595
|
* @param {string} containerSelector - Selector del contenedor
|
|
7534
7596
|
*/
|
|
7535
7597
|
async mount(appName, containerSelector) {
|
|
7598
|
+
// ── RBAC: negar el montaje de módulos para los que el principal no está
|
|
7599
|
+
// autorizado. Se chequea ANTES del ref-counting → un deny es un early-throw
|
|
7600
|
+
// limpio, sin efectos. Emite `access:denied` (bus) y `wu:access:denied` (DOM)
|
|
7601
|
+
// para que el shell muestre un fallback. NOTA: es enforcement client-side —
|
|
7602
|
+
// mejora corrección/UX; la barrera dura es el server (no servir el bundle).
|
|
7603
|
+
if (!this.can(appName)) {
|
|
7604
|
+
const required = this._requiredRoles(appName) || [];
|
|
7605
|
+
const role = this._principal?.role ?? null;
|
|
7606
|
+
this.eventBus.emit('access:denied', { appName, role, required }, { appName });
|
|
7607
|
+
try {
|
|
7608
|
+
window.dispatchEvent(new CustomEvent('wu:access:denied', { detail: { appName, role, required } }));
|
|
7609
|
+
} catch { /* no-DOM env */ }
|
|
7610
|
+
const err = new Error(
|
|
7611
|
+
`[Wu] Access denied: el rol '${role ?? 'ninguno'}' no puede montar '${appName}' (requiere: ${required.join(', ') || 'un principal'})`,
|
|
7612
|
+
);
|
|
7613
|
+
err.code = 'WU_ACCESS_DENIED';
|
|
7614
|
+
err.appName = appName;
|
|
7615
|
+
err.required = required;
|
|
7616
|
+
throw err;
|
|
7617
|
+
}
|
|
7618
|
+
|
|
7536
7619
|
// ── StrictMode + Suspense compat: reference counting ──
|
|
7537
7620
|
// Old approach was a single 60ms grace timer cancelled by the second
|
|
7538
7621
|
// mount(). That works for one mount→unmount→mount cycle but breaks
|
|
@@ -9445,9 +9528,9 @@ if (typeof window !== 'undefined') {
|
|
|
9445
9528
|
// Augment the instance everywhere (browser AND Node/SSR) — the d.ts declares
|
|
9446
9529
|
// these members unconditionally on WuCore, so they must exist in any runtime.
|
|
9447
9530
|
if (!wu.version) {
|
|
9448
|
-
// "2.
|
|
9531
|
+
// "2.6.0" is replaced at build time with package.json version.
|
|
9449
9532
|
// Fallback handles raw-source imports (no bundler).
|
|
9450
|
-
wu.version = "2.
|
|
9533
|
+
wu.version = "2.6.0" ;
|
|
9451
9534
|
wu.info = {
|
|
9452
9535
|
name: 'Wu Framework',
|
|
9453
9536
|
description: 'Universal Microfrontends',
|
|
@@ -9646,6 +9729,12 @@ const useHook = (phase, middleware, opts) => wu.hooks.use(phase, middleware, opt
|
|
|
9646
9729
|
const provide = (name, impl, opts) => wu.contracts.provide(name, impl, opts);
|
|
9647
9730
|
const consume = (name, range, opts) => wu.contracts.consume(name, range, opts);
|
|
9648
9731
|
|
|
9732
|
+
// RBAC: aislamiento rol↔módulo (v2.6+). `setPrincipal` fija quién usa el sistema;
|
|
9733
|
+
// las apps que declaran `roles` solo se montan si el principal está autorizado.
|
|
9734
|
+
const setPrincipal = (principal) => wu.setPrincipal(principal);
|
|
9735
|
+
const getPrincipal = () => wu.getPrincipal();
|
|
9736
|
+
const can = (appName) => wu.can(appName);
|
|
9737
|
+
|
|
9649
9738
|
// --- AI subsystem ---
|
|
9650
9739
|
// AI classes were previously re-exported from this entry point. Doing so anchored
|
|
9651
9740
|
// the ~80 KB AI chunk to the main bundle. As of v2.0, AI is loaded lazily via the
|
|
@@ -9658,5 +9747,5 @@ const consume = (name, range, opts) => wu.contracts.consume(name, range, opts);
|
|
|
9658
9747
|
//
|
|
9659
9748
|
// For runtime use, prefer `wu.ai.*` — it auto-loads the chunk on first method call.
|
|
9660
9749
|
|
|
9661
|
-
export { WuApp, WuCache, WuContracts, WuCore, WuErrorBoundary, WuEventBus, WuLifecycleHooks, WuLoadingStrategy, WuManifest, WuOverrides, WuPerformance, WuPluginSystem, WuPrefetch, WuProxySandbox, WuSandbox, WuStore, WuStyleBridge, app, clearOverrides, compareVersions, consume, createConditionalHook, createGuardHook, createPlugin, createSimpleHook, createTimedHook, createTransformHook, wu_default as default, define, destroy, emit, endMeasure, generatePerformanceReport, getOverrides, getState, hide, init, isHidden, mount, normalizeStyleMode, off, on, onStateChange, once, override, parseVersion, prefetch, prefetchAll, provide, removeOverride, satisfies, setState, show, startMeasure, store, syncStore, unmount, useHook, usePlugin, wu };
|
|
9750
|
+
export { WuApp, WuCache, WuContracts, WuCore, WuErrorBoundary, WuEventBus, WuLifecycleHooks, WuLoadingStrategy, WuManifest, WuOverrides, WuPerformance, WuPluginSystem, WuPrefetch, WuProxySandbox, WuSandbox, WuStore, WuStyleBridge, app, can, clearOverrides, compareVersions, consume, createConditionalHook, createGuardHook, createPlugin, createSimpleHook, createTimedHook, createTransformHook, wu_default as default, define, destroy, emit, endMeasure, generatePerformanceReport, getOverrides, getPrincipal, getState, hide, init, isHidden, mount, normalizeStyleMode, off, on, onStateChange, once, override, parseVersion, prefetch, prefetchAll, provide, removeOverride, satisfies, setPrincipal, setState, show, startMeasure, store, syncStore, unmount, useHook, usePlugin, wu };
|
|
9662
9751
|
//# sourceMappingURL=wu-framework.dev.js.map
|