@v-ibe/core 0.1.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/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/DI/__tests__/scoped-container-dependencies.test.d.ts +1 -0
- package/dist/DI/bootstrap.d.ts +18 -0
- package/dist/DI/decorators/inject.d.ts +37 -0
- package/dist/DI/decorators/inject.js +45 -0
- package/dist/DI/decorators/service.d.ts +24 -0
- package/dist/DI/decorators/service.js +13 -0
- package/dist/DI/di-container.d.ts +53 -0
- package/dist/DI/di-container.js +158 -0
- package/dist/DI/lifecycle.d.ts +37 -0
- package/dist/DI/lifecycle.js +6 -0
- package/dist/DI/scoped-container.d.ts +68 -0
- package/dist/DI/scoped-container.js +193 -0
- package/dist/DI/service-metadata.d.ts +32 -0
- package/dist/DI/service-metadata.js +31 -0
- package/dist/DI/types.d.ts +4 -0
- package/dist/behaviors/__tests__/behavior-system.test.d.ts +1 -0
- package/dist/behaviors/behavior-manager.d.ts +60 -0
- package/dist/behaviors/behavior-manager.js +131 -0
- package/dist/behaviors/behavior-registry.d.ts +68 -0
- package/dist/behaviors/behavior-registry.js +105 -0
- package/dist/behaviors/constants.d.ts +16 -0
- package/dist/behaviors/constants.js +8 -0
- package/dist/behaviors/decorators.d.ts +87 -0
- package/dist/behaviors/decorators.js +46 -0
- package/dist/behaviors/index.d.ts +4 -0
- package/dist/components/__tests__/host.test.d.ts +1 -0
- package/dist/components/app-tree.d.ts +49 -0
- package/dist/components/app-tree.js +122 -0
- package/dist/components/base-component.d.ts +85 -0
- package/dist/components/base-component.js +438 -0
- package/dist/components/decorators/component.d.ts +27 -0
- package/dist/components/decorators/component.js +47 -0
- package/dist/components/decorators/prop.d.ts +14 -0
- package/dist/components/decorators/prop.js +37 -0
- package/dist/components/types.d.ts +26 -0
- package/dist/core.d.ts +23 -0
- package/dist/core.js +8 -0
- package/dist/custom-components/__tests__/for.test.d.ts +1 -0
- package/dist/custom-components/__tests__/show.test.d.ts +1 -0
- package/dist/custom-components/for.d.ts +58 -0
- package/dist/custom-components/for.js +313 -0
- package/dist/custom-components/index.d.ts +2 -0
- package/dist/custom-components/show.d.ts +78 -0
- package/dist/custom-components/show.js +88 -0
- package/dist/data-management/cache/cache-invalidate.decorator.d.ts +35 -0
- package/dist/data-management/cache/cache-invalidate.decorator.js +21 -0
- package/dist/data-management/cache/cache-metadata.d.ts +15 -0
- package/dist/data-management/cache/cache-provider.interface.d.ts +67 -0
- package/dist/data-management/cache/cache-tags.decorator.d.ts +52 -0
- package/dist/data-management/cache/cache-tags.decorator.js +13 -0
- package/dist/data-management/cache/cache-update.decorator.d.ts +28 -0
- package/dist/data-management/cache/cache-update.decorator.js +21 -0
- package/dist/data-management/cache/cache.decorator.d.ts +28 -0
- package/dist/data-management/cache/cache.decorator.js +13 -0
- package/dist/data-management/cache/index.d.ts +11 -0
- package/dist/data-management/cache/local-storage-cache.d.ts +40 -0
- package/dist/data-management/cache/local-storage-cache.js +268 -0
- package/dist/data-management/cache/memory-cache.d.ts +37 -0
- package/dist/data-management/cache/memory-cache.js +149 -0
- package/dist/data-management/cache/session-storage-cache.d.ts +35 -0
- package/dist/data-management/cache/session-storage-cache.js +242 -0
- package/dist/data-management/cache/ttl.decorator.d.ts +31 -0
- package/dist/data-management/cache/ttl.decorator.js +34 -0
- package/dist/data-management/decorators/consume.d.ts +29 -0
- package/dist/data-management/decorators/consume.js +28 -0
- package/dist/data-management/decorators/id.d.ts +28 -0
- package/dist/data-management/decorators/id.js +19 -0
- package/dist/data-management/decorators/model.d.ts +48 -0
- package/dist/data-management/decorators/model.js +24 -0
- package/dist/data-management/decorators/prop.d.ts +43 -0
- package/dist/data-management/decorators/prop.js +32 -0
- package/dist/data-management/index.d.ts +13 -0
- package/dist/data-management/store/json-to-model.d.ts +45 -0
- package/dist/data-management/store/json-to-model.js +36 -0
- package/dist/data-management/store/store.d.ts +108 -0
- package/dist/data-management/store/store.js +207 -0
- package/dist/data-management/store/types.d.ts +53 -0
- package/dist/events-handler/decorators/emit.d.ts +29 -0
- package/dist/events-handler/decorators/emit.js +51 -0
- package/dist/events-handler/event-decorators.d.ts +1 -0
- package/dist/events-handler/event-emitter.service.d.ts +21 -0
- package/dist/events-handler/event-emitter.service.js +85 -0
- package/dist/events-handler/event-types.d.ts +12 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +121 -0
- package/dist/jsx/dynamic/__tests__/granular-array-renderer.test.d.ts +1 -0
- package/dist/jsx/dynamic/__tests__/jsx-array-rendering.test.d.ts +1 -0
- package/dist/jsx/dynamic/array-renderer.d.ts +2 -0
- package/dist/jsx/dynamic/array-renderer.js +133 -0
- package/dist/jsx/dynamic/child-renderer.d.ts +1 -0
- package/dist/jsx/dynamic/child-renderer.js +180 -0
- package/dist/jsx/dynamic/dom-utils.d.ts +5 -0
- package/dist/jsx/dynamic/dom-utils.js +22 -0
- package/dist/jsx/dynamic/granular-array-renderer.d.ts +16 -0
- package/dist/jsx/dynamic/granular-array-renderer.js +153 -0
- package/dist/jsx/dynamic/node-renderer.d.ts +2 -0
- package/dist/jsx/dynamic/props-handler.d.ts +3 -0
- package/dist/jsx/dynamic/props-handler.js +281 -0
- package/dist/jsx/dynamic/text-renderer.d.ts +2 -0
- package/dist/jsx/jsx-dev-runtime.d.ts +2 -0
- package/dist/jsx/jsx-runtime.d.ts +3 -0
- package/dist/jsx/types.d.ts +35 -0
- package/dist/jsx/types.js +4 -0
- package/dist/jsx-dev-runtime.d.ts +2 -0
- package/dist/jsx-dev-runtime.js +8 -0
- package/dist/jsx-runtime.d.ts +2 -0
- package/dist/jsx-runtime.js +11 -0
- package/dist/reactivity/__tests__/context-stack.test.d.ts +1 -0
- package/dist/reactivity/__tests__/nested-effects-untrack.test.d.ts +22 -0
- package/dist/reactivity/context-scope.d.ts +57 -0
- package/dist/reactivity/context-scope.js +35 -0
- package/dist/reactivity/decorators/__tests__/ctx-integration.test.d.ts +5 -0
- package/dist/reactivity/decorators/__tests__/ctx-loop.test.d.ts +10 -0
- package/dist/reactivity/decorators/__tests__/state-intelligent.test.d.ts +1 -0
- package/dist/reactivity/decorators/computed.d.ts +6 -0
- package/dist/reactivity/decorators/computed.js +17 -0
- package/dist/reactivity/decorators/create-event-decorator.d.ts +5 -0
- package/dist/reactivity/decorators/create-event-decorator.js +28 -0
- package/dist/reactivity/decorators/ctx.d.ts +9 -0
- package/dist/reactivity/decorators/ctx.js +91 -0
- package/dist/reactivity/decorators/effect.d.ts +9 -0
- package/dist/reactivity/decorators/effect.js +24 -0
- package/dist/reactivity/decorators/resource.d.ts +48 -0
- package/dist/reactivity/decorators/resource.js +20 -0
- package/dist/reactivity/decorators/state.d.ts +8 -0
- package/dist/reactivity/decorators/state.js +68 -0
- package/dist/reactivity/decorators/store.d.ts +6 -0
- package/dist/reactivity/decorators/store.js +25 -0
- package/dist/reactivity/phase-scheduler.d.ts +81 -0
- package/dist/reactivity/phase-scheduler.js +88 -0
- package/dist/reactivity/phase-scheduler.test.d.ts +1 -0
- package/dist/reactivity/reactive-cache.d.ts +21 -0
- package/dist/reactivity/reactive-cache.js +31 -0
- package/dist/reactivity/reactive-cache.test.d.ts +1 -0
- package/dist/reactivity/reactive-context.d.ts +152 -0
- package/dist/reactivity/reactive-context.js +184 -0
- package/dist/reactivity/signals/__tests__/composicion-automatica.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-1-estructura-basica.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-2-registro-subscribers.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-3-notificaciones-basicas.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-4-comparacion-valores.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-5-tracking-automatico.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-6-anti-glitch.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-7-objetos-anidados.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-8-observable-array-support.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite-shallow-tracking.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/effect.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-1-estructura-basica.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-2-metodos-mutadores.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-3-tracking-por-indice.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-4-tracking-length.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-5-tracking-mutation.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-6-metodos-no-mutadores.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-7-composicion-bidireccional.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-8-proxies.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-9-derived-cache-optimization.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/resource.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/signal.test.d.ts +1 -0
- package/dist/reactivity/signals/array-strategies.d.ts +120 -0
- package/dist/reactivity/signals/array-strategies.js +261 -0
- package/dist/reactivity/signals/composite.d.ts +89 -0
- package/dist/reactivity/signals/composite.js +145 -0
- package/dist/reactivity/signals/computed.d.ts +61 -0
- package/dist/reactivity/signals/computed.js +107 -0
- package/dist/reactivity/signals/computed.test.d.ts +1 -0
- package/dist/reactivity/signals/derived.d.ts +10 -0
- package/dist/reactivity/signals/derived.js +24 -0
- package/dist/reactivity/signals/effect.d.ts +27 -0
- package/dist/reactivity/signals/effect.js +46 -0
- package/dist/reactivity/signals/event.d.ts +9 -0
- package/dist/reactivity/signals/event.js +15 -0
- package/dist/reactivity/signals/reactive-array.d.ts +133 -0
- package/dist/reactivity/signals/reactive-array.js +490 -0
- package/dist/reactivity/signals/reactive-proxy.d.ts +54 -0
- package/dist/reactivity/signals/reactive-proxy.js +299 -0
- package/dist/reactivity/signals/reactive-tracking.test.d.ts +1 -0
- package/dist/reactivity/signals/resource.d.ts +9 -0
- package/dist/reactivity/signals/resource.js +58 -0
- package/dist/reactivity/signals/signal.d.ts +39 -0
- package/dist/reactivity/signals/signal.js +56 -0
- package/dist/reactivity/signals/subscription-management.test.d.ts +1 -0
- package/dist/reactivity/types.d.ts +12 -0
- package/dist/router/__tests__/link-behavior-active-class.test.d.ts +1 -0
- package/dist/router/__tests__/loop-detector.test.d.ts +1 -0
- package/dist/router/__tests__/params-container-resolution.test.d.ts +1 -0
- package/dist/router/__tests__/router-generated-routes.test.d.ts +1 -0
- package/dist/router/__tests__/router-params-granular.test.d.ts +1 -0
- package/dist/router/__tests__/router-params-simple.test.d.ts +1 -0
- package/dist/router/__tests__/router-query-params.test.d.ts +1 -0
- package/dist/router/__tests__/router-route-candidates.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-app-articles.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-debug.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-integration.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-this.test.d.ts +1 -0
- package/dist/router/decorators/base-policy.d.ts +141 -0
- package/dist/router/decorators/base-policy.js +63 -0
- package/dist/router/decorators/index.d.ts +6 -0
- package/dist/router/decorators/params.d.ts +31 -0
- package/dist/router/decorators/params.js +97 -0
- package/dist/router/decorators/route-metadata.d.ts +11 -0
- package/dist/router/decorators/route-metadata.js +23 -0
- package/dist/router/decorators/route.d.ts +39 -0
- package/dist/router/decorators/route.js +7 -0
- package/dist/router/link.behavior.d.ts +87 -0
- package/dist/router/link.behavior.js +227 -0
- package/dist/router/policy-evaluator.d.ts +81 -0
- package/dist/router/policy-evaluator.js +209 -0
- package/dist/router/route-view.d.ts +56 -0
- package/dist/router/route-view.js +156 -0
- package/dist/router/router.d.ts +67 -0
- package/dist/router/router.js +308 -0
- package/dist/router/static-analysis/index.d.ts +37 -0
- package/dist/router/static-analysis/parser.d.ts +14 -0
- package/dist/router/static-analysis/parser.js +147 -0
- package/dist/router/static-analysis/scanner.d.ts +27 -0
- package/dist/router/static-analysis/scanner.js +91 -0
- package/dist/router/trie.d.ts +14 -0
- package/dist/router/trie.js +126 -0
- package/dist/router/trie.types.d.ts +36 -0
- package/dist/styles/base-style-sheet.d.ts +96 -0
- package/dist/styles/base-style-sheet.js +149 -0
- package/dist/styles/decorators/factories.d.ts +76 -0
- package/dist/styles/decorators/factories.js +11 -0
- package/dist/styles/decorators/keyframes.d.ts +238 -0
- package/dist/styles/decorators/keyframes.js +79 -0
- package/dist/styles/decorators/rule.d.ts +177 -0
- package/dist/styles/decorators/rule.js +72 -0
- package/dist/styles/decorators/scope.d.ts +66 -0
- package/dist/styles/decorators/scope.js +17 -0
- package/dist/styles/decorators/style.d.ts +1 -0
- package/dist/styles/decorators/style.js +20 -0
- package/dist/styles/decorators/useStyles.d.ts +5 -0
- package/dist/styles/decorators/useStyles.js +29 -0
- package/dist/styles/global-styles-registry.d.ts +72 -0
- package/dist/styles/global-styles-registry.js +155 -0
- package/dist/types.d.ts +1 -0
- package/dist/vite-plugins/__tests__/jsx-control-flow-transform.test.d.ts +1 -0
- package/dist/vite-plugins/index.d.ts +4 -0
- package/dist/vite-plugins/index.js +10 -0
- package/dist/vite-plugins/jsx-contextual.d.ts +7 -0
- package/dist/vite-plugins/jsx-contextual.js +53 -0
- package/dist/vite-plugins/jsx-control-flow-transform.d.ts +60 -0
- package/dist/vite-plugins/jsx-control-flow-transform.js +180 -0
- package/dist/vite-plugins/jsx-signals.d.ts +2 -0
- package/dist/vite-plugins/jsx-signals.js +124 -0
- package/dist/vite-plugins/router/route-generator-plugin.d.ts +63 -0
- package/dist/vite-plugins/router/route-generator-plugin.js +310 -0
- package/package.json +85 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const POLICY_RULES = Symbol("policyRules");
|
|
2
|
+
function getPolicyRules(policyClass) {
|
|
3
|
+
return policyClass[POLICY_RULES] || [];
|
|
4
|
+
}
|
|
5
|
+
function addPolicyRule(target, propertyKey, descriptor, type) {
|
|
6
|
+
const constructor = target.constructor;
|
|
7
|
+
if (!constructor[POLICY_RULES]) {
|
|
8
|
+
constructor[POLICY_RULES] = [];
|
|
9
|
+
}
|
|
10
|
+
const rule = {
|
|
11
|
+
methodName: propertyKey,
|
|
12
|
+
handler: descriptor.value,
|
|
13
|
+
type
|
|
14
|
+
};
|
|
15
|
+
constructor[POLICY_RULES].push(rule);
|
|
16
|
+
}
|
|
17
|
+
function Allow() {
|
|
18
|
+
return function(target, context) {
|
|
19
|
+
context.addInitializer(function() {
|
|
20
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, context.name) || {
|
|
21
|
+
value: target
|
|
22
|
+
};
|
|
23
|
+
addPolicyRule(Object.getPrototypeOf(this), context.name, descriptor, "allow");
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function Block() {
|
|
28
|
+
return function(target, context) {
|
|
29
|
+
context.addInitializer(function() {
|
|
30
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, context.name) || {
|
|
31
|
+
value: target
|
|
32
|
+
};
|
|
33
|
+
addPolicyRule(Object.getPrototypeOf(this), context.name, descriptor, "block");
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function Redirect() {
|
|
38
|
+
return function(target, context) {
|
|
39
|
+
context.addInitializer(function() {
|
|
40
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, context.name) || {
|
|
41
|
+
value: target
|
|
42
|
+
};
|
|
43
|
+
addPolicyRule(Object.getPrototypeOf(this), context.name, descriptor, "redirect");
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function Skip() {
|
|
48
|
+
return function(target, context) {
|
|
49
|
+
context.addInitializer(function() {
|
|
50
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, context.name) || {
|
|
51
|
+
value: target
|
|
52
|
+
};
|
|
53
|
+
addPolicyRule(Object.getPrototypeOf(this), context.name, descriptor, "skip");
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
Allow,
|
|
59
|
+
Block,
|
|
60
|
+
Redirect,
|
|
61
|
+
Skip,
|
|
62
|
+
getPolicyRules
|
|
63
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Route } from './route';
|
|
2
|
+
export type { RouteConfig } from './route';
|
|
3
|
+
export { Param, Params, Query, QueryParams, getParamMetadata, getQueryParamMetadata } from './params';
|
|
4
|
+
export type { ParamMetadata, QueryParamMetadata } from './params';
|
|
5
|
+
export { Allow, Block, Redirect, Skip, getPolicyRules } from './base-policy';
|
|
6
|
+
export type { PolicyDecisionType, PolicyRule, PolicyDecision } from './base-policy';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Constructor } from '../../DI/types';
|
|
2
|
+
export interface ParamMetadata {
|
|
3
|
+
paramName: string;
|
|
4
|
+
propertyKey: string;
|
|
5
|
+
target: Constructor;
|
|
6
|
+
}
|
|
7
|
+
export interface QueryParamMetadata {
|
|
8
|
+
queryName: string;
|
|
9
|
+
propertyKey: string;
|
|
10
|
+
target: Constructor;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Decorator for individual route parameters
|
|
14
|
+
* @param paramName The name of the route parameter (e.g., 'id' for '/users/:id')
|
|
15
|
+
*/
|
|
16
|
+
export declare function Param(paramName: string): (_: undefined, context: ClassFieldDecoratorContext) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Decorator for all route parameters as an object
|
|
19
|
+
*/
|
|
20
|
+
export declare function Params(): (_: undefined, context: ClassFieldDecoratorContext) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Decorator for individual query parameters
|
|
23
|
+
* @param queryName The name of the query parameter (e.g., 'page' for '?page=1')
|
|
24
|
+
*/
|
|
25
|
+
export declare function Query<This extends object>(queryName: string): (_: undefined, context: ClassFieldDecoratorContext) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Decorator for all query parameters as an object
|
|
28
|
+
*/
|
|
29
|
+
export declare function QueryParams(): (_: undefined, context: ClassFieldDecoratorContext) => void;
|
|
30
|
+
export declare function getParamMetadata(target: Constructor): ParamMetadata[];
|
|
31
|
+
export declare function getQueryParamMetadata(target: Constructor): QueryParamMetadata[];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Router } from "../router.js";
|
|
2
|
+
const PARAM_METADATA_KEY = Symbol("paramMetadata");
|
|
3
|
+
const QUERY_PARAM_METADATA_KEY = Symbol("queryParamMetadata");
|
|
4
|
+
function Param(paramName) {
|
|
5
|
+
return function(_, context) {
|
|
6
|
+
if (context.kind !== "field") {
|
|
7
|
+
throw new Error("@Param can only be used on fields");
|
|
8
|
+
}
|
|
9
|
+
context.addInitializer(function() {
|
|
10
|
+
const ctor = this.constructor;
|
|
11
|
+
const metadata = {
|
|
12
|
+
paramName,
|
|
13
|
+
propertyKey: context.name,
|
|
14
|
+
target: ctor
|
|
15
|
+
};
|
|
16
|
+
if (!ctor[PARAM_METADATA_KEY]) {
|
|
17
|
+
ctor[PARAM_METADATA_KEY] = [];
|
|
18
|
+
}
|
|
19
|
+
ctor[PARAM_METADATA_KEY].push(metadata);
|
|
20
|
+
Object.defineProperty(this, context.name, {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
get() {
|
|
24
|
+
const router = this.__container.get(Router);
|
|
25
|
+
return router.$params[paramName] || null;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function Params() {
|
|
32
|
+
return function(_, context) {
|
|
33
|
+
if (context.kind !== "field") {
|
|
34
|
+
throw new Error("@Params can only be used on fields");
|
|
35
|
+
}
|
|
36
|
+
context.addInitializer(function() {
|
|
37
|
+
Object.defineProperty(this, context.name, {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
get() {
|
|
41
|
+
const router = this.__container.get(Router);
|
|
42
|
+
return router.$params;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function Query(queryName) {
|
|
49
|
+
return function(_, context) {
|
|
50
|
+
if (context.kind !== "field") {
|
|
51
|
+
throw new Error("@Query can only be used on fields");
|
|
52
|
+
}
|
|
53
|
+
context.addInitializer(function() {
|
|
54
|
+
const ctor = this.constructor;
|
|
55
|
+
const metadata = {
|
|
56
|
+
queryName,
|
|
57
|
+
propertyKey: context.name,
|
|
58
|
+
target: ctor
|
|
59
|
+
};
|
|
60
|
+
if (!ctor[QUERY_PARAM_METADATA_KEY]) {
|
|
61
|
+
ctor[QUERY_PARAM_METADATA_KEY] = [];
|
|
62
|
+
}
|
|
63
|
+
ctor[QUERY_PARAM_METADATA_KEY].push(metadata);
|
|
64
|
+
Object.defineProperty(this, context.name, {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
configurable: true,
|
|
67
|
+
get() {
|
|
68
|
+
const router = this.__container.get(Router);
|
|
69
|
+
return router.$queryParams[queryName] || null;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function QueryParams() {
|
|
76
|
+
return function(_, context) {
|
|
77
|
+
if (context.kind !== "field") {
|
|
78
|
+
throw new Error("@QueryParams can only be used on fields");
|
|
79
|
+
}
|
|
80
|
+
context.addInitializer(function() {
|
|
81
|
+
Object.defineProperty(this, context.name, {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
configurable: true,
|
|
84
|
+
get() {
|
|
85
|
+
const router = this.__container.get(Router);
|
|
86
|
+
return router.$queryParams;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
Param,
|
|
94
|
+
Params,
|
|
95
|
+
Query,
|
|
96
|
+
QueryParams
|
|
97
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decorador sobrecargado para inyectar metadata de la ruta.
|
|
3
|
+
*
|
|
4
|
+
* Uso sin parámetros: @RouteMetadata metadata!: Record<string, any>;
|
|
5
|
+
* Inyecta toda la metadata de la ruta.
|
|
6
|
+
*
|
|
7
|
+
* Uso con key: @RouteMetadata('role') role!: string;
|
|
8
|
+
* Inyecta solo el valor específico de la metadata.
|
|
9
|
+
*/
|
|
10
|
+
export declare function RouteMetadata(): (value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
11
|
+
export declare function RouteMetadata(key: string): (value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function RouteMetadata(key) {
|
|
2
|
+
return function(value, context) {
|
|
3
|
+
if (context.kind !== "field") {
|
|
4
|
+
throw new Error("@RouteMetadata can only be used on fields");
|
|
5
|
+
}
|
|
6
|
+
context.addInitializer(function() {
|
|
7
|
+
Object.defineProperty(this, context.name, {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
get() {
|
|
11
|
+
const metadata = this.__routeMetadata || {};
|
|
12
|
+
if (key !== void 0) {
|
|
13
|
+
return metadata[key];
|
|
14
|
+
}
|
|
15
|
+
return metadata;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
RouteMetadata
|
|
23
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Constructor } from '../../DI/types';
|
|
2
|
+
/**
|
|
3
|
+
* Configuración para el decorador @Route
|
|
4
|
+
*/
|
|
5
|
+
export interface RouteConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Metadata arbitraria que se puede acceder desde políticas
|
|
8
|
+
* a través del decorador @RouteMetadata
|
|
9
|
+
*/
|
|
10
|
+
metadata?: Record<string, any>;
|
|
11
|
+
/**
|
|
12
|
+
* Array de clases de políticas que deben estar decoradas con @Service.
|
|
13
|
+
* Las políticas se evalúan en orden antes de cargar el componente.
|
|
14
|
+
* Si alguna política redirige, la navegación actual se cancela.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* @Route('/admin', {
|
|
19
|
+
* metadata: { requiresAuth: true },
|
|
20
|
+
* policies: [AuthPolicy, AdminRolePolicy]
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
policies?: Constructor<any>[];
|
|
25
|
+
/**
|
|
26
|
+
* Nombre del slot donde se renderizará este componente.
|
|
27
|
+
* Permite renderizar múltiples componentes en paralelo para la misma ruta.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* @Route('/dashboard', {
|
|
32
|
+
* slot: '@main',
|
|
33
|
+
* policies: [AuthPolicy]
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
slot?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function Route(path: string, config?: RouteConfig): (target: any, context: ClassDecoratorContext) => void;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { BaseComponent } from '../components/base-component';
|
|
2
|
+
/**
|
|
3
|
+
* Link Behavior
|
|
4
|
+
*
|
|
5
|
+
* Convierte un <a> en un link de navegación SPA que usa el Router interno.
|
|
6
|
+
* También maneja la clase CSS activa basada en la ruta actual.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* // Navegación simple
|
|
11
|
+
* <a link href="/home">Home</a>
|
|
12
|
+
*
|
|
13
|
+
* // Con clase activa
|
|
14
|
+
* <a link href="/about" activeClass="active">About</a>
|
|
15
|
+
*
|
|
16
|
+
* // Con múltiples clases activas
|
|
17
|
+
* <a link href="/contact" activeClass="active font-bold">Contact</a>
|
|
18
|
+
*
|
|
19
|
+
* // Replace en lugar de push (no agrega al historial)
|
|
20
|
+
* <a link href="/login" replace>Login</a>
|
|
21
|
+
*
|
|
22
|
+
* // Manejo de links externos
|
|
23
|
+
* <a link href="https://docs.com" external="native">External Docs</a>
|
|
24
|
+
* <a link href="https://api.com" external="block">Blocked API</a>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class Link {
|
|
28
|
+
el: HTMLAnchorElement;
|
|
29
|
+
hostComponent?: BaseComponent;
|
|
30
|
+
link: boolean;
|
|
31
|
+
href: string;
|
|
32
|
+
activeClass?: string;
|
|
33
|
+
replace?: boolean;
|
|
34
|
+
external?: 'allow' | 'block' | 'native';
|
|
35
|
+
private router;
|
|
36
|
+
private clickHandler?;
|
|
37
|
+
onInit(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Computed que determina si el link está activo.
|
|
40
|
+
*
|
|
41
|
+
* Un link está activo si su href resuelto hace match con alguno de los patrones activos del router.
|
|
42
|
+
* Los patrones pueden contener variables como `:id`, por lo que necesitamos pattern matching real.
|
|
43
|
+
*
|
|
44
|
+
* Ejemplos:
|
|
45
|
+
* - href="/articles" hace match con pattern "/articles"
|
|
46
|
+
* - href="/articles/123" hace match con pattern "/articles/:id"
|
|
47
|
+
* - href="/dashboard/nested" hace match con patterns "/dashboard" y "/dashboard/nested"
|
|
48
|
+
*/
|
|
49
|
+
get isActive(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Verifica si un href hace match con un patrón de ruta.
|
|
52
|
+
*
|
|
53
|
+
* @param href - El href del link (ej: "/articles/123")
|
|
54
|
+
* @param pattern - El patrón de ruta (ej: "/articles/:id")
|
|
55
|
+
* @returns true si el href hace match con el patrón
|
|
56
|
+
*/
|
|
57
|
+
private matchPattern;
|
|
58
|
+
/**
|
|
59
|
+
* Effect que actualiza las clases CSS cuando cambia el estado activo del link.
|
|
60
|
+
*/
|
|
61
|
+
private updateActiveClass;
|
|
62
|
+
/**
|
|
63
|
+
* Resuelve un href siguiendo el estándar de frameworks modernos (React Router, Next.js, etc.)
|
|
64
|
+
*
|
|
65
|
+
* Comportamiento:
|
|
66
|
+
* - Rutas absolutas (empiezan con /): se usan tal cual → "/products" = "/products"
|
|
67
|
+
* - Rutas externas (con protocolo): se devuelven tal cual
|
|
68
|
+
* - Rutas relativas (no empiezan con /): se resuelven desde routeBasePath del componente host
|
|
69
|
+
* - routeBasePath="/store/:storeId" + params={storeId:"123"} + href="sales" = "/store/123/sales"
|
|
70
|
+
*
|
|
71
|
+
* @param href - El href original del prop
|
|
72
|
+
* @returns El href resuelto que se debe usar para navegación
|
|
73
|
+
*/
|
|
74
|
+
private resolveHref;
|
|
75
|
+
/**
|
|
76
|
+
* Reemplaza parámetros (:paramName) en un path con valores del router.$params
|
|
77
|
+
*
|
|
78
|
+
* @param path - Path con parámetros (ej: "/store/:storeId/products")
|
|
79
|
+
* @returns Path con parámetros resueltos (ej: "/store/123/products")
|
|
80
|
+
*/
|
|
81
|
+
private resolvePathParams;
|
|
82
|
+
/**
|
|
83
|
+
* Determina si un href es un link externo
|
|
84
|
+
*/
|
|
85
|
+
private isExternalLink;
|
|
86
|
+
onDestroy(): void;
|
|
87
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { Behavior, Host, ComponentHost } from "../behaviors/decorators.js";
|
|
2
|
+
import { Prop } from "../components/decorators/prop.js";
|
|
3
|
+
import { Inject } from "../DI/decorators/inject.js";
|
|
4
|
+
import { Router } from "./router.js";
|
|
5
|
+
import { Effect } from "../reactivity/decorators/effect.js";
|
|
6
|
+
import { Computed } from "../reactivity/decorators/computed.js";
|
|
7
|
+
var __create = Object.create;
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
11
|
+
var __typeError = (msg) => {
|
|
12
|
+
throw TypeError(msg);
|
|
13
|
+
};
|
|
14
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
15
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
16
|
+
var __decoratorStart = (base) => [, , , __create(null)];
|
|
17
|
+
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
18
|
+
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
|
|
19
|
+
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
|
|
20
|
+
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
|
|
21
|
+
var __runInitializers = (array, flags, self, value) => {
|
|
22
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
26
|
+
var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
|
|
27
|
+
var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
|
|
28
|
+
var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
|
|
29
|
+
var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
|
|
30
|
+
return __privateGet(this, extra);
|
|
31
|
+
}, set [name](x) {
|
|
32
|
+
return __privateSet(this, extra, x);
|
|
33
|
+
} }, name));
|
|
34
|
+
k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
|
|
35
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
36
|
+
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
|
|
37
|
+
if (k) {
|
|
38
|
+
ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
|
|
39
|
+
if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
|
|
40
|
+
if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
|
|
41
|
+
}
|
|
42
|
+
it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
|
|
43
|
+
if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
|
|
44
|
+
else if (typeof it !== "object" || it === null) __typeError("Object expected");
|
|
45
|
+
else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
|
|
46
|
+
}
|
|
47
|
+
return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
48
|
+
};
|
|
49
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
50
|
+
var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
|
|
51
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
52
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
53
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
54
|
+
var _updateActiveClass_dec, _isActive_dec, _router_dec, _external_dec, _replace_dec, _activeClass_dec, _href_dec, _link_dec, _hostComponent_dec, _el_dec, _Link_decorators, _init;
|
|
55
|
+
_Link_decorators = [Behavior], _el_dec = [Host], _hostComponent_dec = [ComponentHost], _link_dec = [Prop], _href_dec = [Prop], _activeClass_dec = [Prop], _replace_dec = [Prop], _external_dec = [Prop], _router_dec = [Inject(Router)], _isActive_dec = [Computed], _updateActiveClass_dec = [Effect];
|
|
56
|
+
class Link {
|
|
57
|
+
constructor() {
|
|
58
|
+
__runInitializers(_init, 5, this);
|
|
59
|
+
this.el = __runInitializers(_init, 8, this), __runInitializers(_init, 11, this);
|
|
60
|
+
this.hostComponent = __runInitializers(_init, 12, this), __runInitializers(_init, 15, this);
|
|
61
|
+
this.link = __runInitializers(_init, 16, this, true), __runInitializers(_init, 19, this);
|
|
62
|
+
this.href = __runInitializers(_init, 20, this, ""), __runInitializers(_init, 23, this);
|
|
63
|
+
this.activeClass = __runInitializers(_init, 24, this), __runInitializers(_init, 27, this);
|
|
64
|
+
this.replace = __runInitializers(_init, 28, this), __runInitializers(_init, 31, this);
|
|
65
|
+
this.external = __runInitializers(_init, 32, this), __runInitializers(_init, 35, this);
|
|
66
|
+
this.router = __runInitializers(_init, 36, this), __runInitializers(_init, 39, this);
|
|
67
|
+
this.clickHandler = void 0;
|
|
68
|
+
}
|
|
69
|
+
onInit() {
|
|
70
|
+
const resolvedHref = this.resolveHref(this.href);
|
|
71
|
+
this.el.href = resolvedHref;
|
|
72
|
+
this.clickHandler = (e) => {
|
|
73
|
+
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.defaultPrevented) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (this.el.target === "_blank") {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (this.isExternalLink(this.href)) {
|
|
80
|
+
if (this.external) {
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
this.router.navigate(this.href, { external: this.external });
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
this.router.navigate(resolvedHref, {
|
|
89
|
+
replace: this.replace
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
this.el.addEventListener("click", this.clickHandler);
|
|
93
|
+
if (this.activeClass) {
|
|
94
|
+
this.updateActiveClass();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
get isActive() {
|
|
98
|
+
const resolvedHref = this.resolveHref(this.href);
|
|
99
|
+
const normalizedHref = resolvedHref.replace(/\/$/, "") || "/";
|
|
100
|
+
return this.router.activePatterns.some((pattern) => {
|
|
101
|
+
const normalizedPattern = pattern.replace(/\/$/, "") || "/";
|
|
102
|
+
return this.matchPattern(normalizedHref, normalizedPattern);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Verifica si un href hace match con un patrón de ruta.
|
|
107
|
+
*
|
|
108
|
+
* @param href - El href del link (ej: "/articles/123")
|
|
109
|
+
* @param pattern - El patrón de ruta (ej: "/articles/:id")
|
|
110
|
+
* @returns true si el href hace match con el patrón
|
|
111
|
+
*/
|
|
112
|
+
matchPattern(href, pattern) {
|
|
113
|
+
if (href === pattern) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (!pattern.includes(":")) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
const regexPattern = pattern.split("/").map((segment) => {
|
|
120
|
+
if (segment.startsWith(":")) {
|
|
121
|
+
return "([^/]+)";
|
|
122
|
+
}
|
|
123
|
+
return segment;
|
|
124
|
+
}).join("/");
|
|
125
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
126
|
+
return regex.test(href);
|
|
127
|
+
}
|
|
128
|
+
updateActiveClass() {
|
|
129
|
+
if (!this.activeClass) return;
|
|
130
|
+
const isActive = this.isActive;
|
|
131
|
+
const classes = this.activeClass.split(" ").filter((cls) => cls.trim());
|
|
132
|
+
if (isActive) {
|
|
133
|
+
this.el.classList.add(...classes);
|
|
134
|
+
} else {
|
|
135
|
+
this.el.classList.remove(...classes);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Resuelve un href siguiendo el estándar de frameworks modernos (React Router, Next.js, etc.)
|
|
140
|
+
*
|
|
141
|
+
* Comportamiento:
|
|
142
|
+
* - Rutas absolutas (empiezan con /): se usan tal cual → "/products" = "/products"
|
|
143
|
+
* - Rutas externas (con protocolo): se devuelven tal cual
|
|
144
|
+
* - Rutas relativas (no empiezan con /): se resuelven desde routeBasePath del componente host
|
|
145
|
+
* - routeBasePath="/store/:storeId" + params={storeId:"123"} + href="sales" = "/store/123/sales"
|
|
146
|
+
*
|
|
147
|
+
* @param href - El href original del prop
|
|
148
|
+
* @returns El href resuelto que se debe usar para navegación
|
|
149
|
+
*/
|
|
150
|
+
resolveHref(href) {
|
|
151
|
+
if (this.isExternalLink(href)) {
|
|
152
|
+
return href;
|
|
153
|
+
}
|
|
154
|
+
if (href.startsWith("/")) {
|
|
155
|
+
return href;
|
|
156
|
+
}
|
|
157
|
+
const normalizedHref = href.startsWith("./") ? href.slice(2) : href;
|
|
158
|
+
let basePath = "/";
|
|
159
|
+
if (this.hostComponent && "routeBasePath" in this.hostComponent) {
|
|
160
|
+
basePath = this.hostComponent.routeBasePath;
|
|
161
|
+
}
|
|
162
|
+
if (!basePath || basePath === "/") {
|
|
163
|
+
const currentPathname = this.router.pathname;
|
|
164
|
+
const basePathname = currentPathname.endsWith("/") ? currentPathname : currentPathname + "/";
|
|
165
|
+
return basePathname + normalizedHref;
|
|
166
|
+
}
|
|
167
|
+
const resolvedBasePath = this.resolvePathParams(basePath);
|
|
168
|
+
const finalBasePath = resolvedBasePath.endsWith("/") ? resolvedBasePath : resolvedBasePath + "/";
|
|
169
|
+
return finalBasePath + normalizedHref;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Reemplaza parámetros (:paramName) en un path con valores del router.$params
|
|
173
|
+
*
|
|
174
|
+
* @param path - Path con parámetros (ej: "/store/:storeId/products")
|
|
175
|
+
* @returns Path con parámetros resueltos (ej: "/store/123/products")
|
|
176
|
+
*/
|
|
177
|
+
resolvePathParams(path) {
|
|
178
|
+
const segments = path.split("/");
|
|
179
|
+
const resolved = segments.map((segment) => {
|
|
180
|
+
if (segment.startsWith(":")) {
|
|
181
|
+
const paramName = segment.slice(1);
|
|
182
|
+
const paramValue = this.router.$params[paramName];
|
|
183
|
+
return paramValue || segment;
|
|
184
|
+
}
|
|
185
|
+
return segment;
|
|
186
|
+
});
|
|
187
|
+
return resolved.join("/");
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Determina si un href es un link externo
|
|
191
|
+
*/
|
|
192
|
+
isExternalLink(href) {
|
|
193
|
+
if (/^(https?:)?\/\//.test(href)) {
|
|
194
|
+
try {
|
|
195
|
+
const url = new URL(href, window.location.origin);
|
|
196
|
+
return url.origin !== window.location.origin;
|
|
197
|
+
} catch {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (/^[a-z]+:/i.test(href)) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
onDestroy() {
|
|
207
|
+
if (this.clickHandler) {
|
|
208
|
+
this.el.removeEventListener("click", this.clickHandler);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
_init = __decoratorStart();
|
|
213
|
+
__decorateElement(_init, 2, "isActive", _isActive_dec, Link);
|
|
214
|
+
__decorateElement(_init, 1, "updateActiveClass", _updateActiveClass_dec, Link);
|
|
215
|
+
__decorateElement(_init, 5, "el", _el_dec, Link);
|
|
216
|
+
__decorateElement(_init, 5, "hostComponent", _hostComponent_dec, Link);
|
|
217
|
+
__decorateElement(_init, 5, "link", _link_dec, Link);
|
|
218
|
+
__decorateElement(_init, 5, "href", _href_dec, Link);
|
|
219
|
+
__decorateElement(_init, 5, "activeClass", _activeClass_dec, Link);
|
|
220
|
+
__decorateElement(_init, 5, "replace", _replace_dec, Link);
|
|
221
|
+
__decorateElement(_init, 5, "external", _external_dec, Link);
|
|
222
|
+
__decorateElement(_init, 5, "router", _router_dec, Link);
|
|
223
|
+
Link = __decorateElement(_init, 0, "Link", _Link_decorators, Link);
|
|
224
|
+
__runInitializers(_init, 1, Link);
|
|
225
|
+
export {
|
|
226
|
+
Link
|
|
227
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { PolicyDecision, PolicyDecisionType } from './decorators/base-policy';
|
|
2
|
+
import { RouteCandidate } from './trie.types';
|
|
3
|
+
/**
|
|
4
|
+
* Servicio que evalúa políticas ejecutando sus reglas decoradas en orden.
|
|
5
|
+
*
|
|
6
|
+
* El evaluador implementa la siguiente semántica:
|
|
7
|
+
*
|
|
8
|
+
* - Para @Allow, @Block, @Redirect:
|
|
9
|
+
* - Si el método retorna false/undefined: continuar al siguiente método
|
|
10
|
+
* - Si el método retorna true: ejecutar la acción y detener evaluación
|
|
11
|
+
*
|
|
12
|
+
* - Para @Skip:
|
|
13
|
+
* - Si el método retorna false: continuar al siguiente método
|
|
14
|
+
* - Si el método retorna true: esta política completa no opina,
|
|
15
|
+
* señalar al router que pase a la siguiente política en la cadena
|
|
16
|
+
*
|
|
17
|
+
* Esta semántica permite composición limpia de políticas donde cada una
|
|
18
|
+
* puede explícitamente declinar opinar sobre ciertas navegaciones.
|
|
19
|
+
*/
|
|
20
|
+
export declare class PolicyEvaluator {
|
|
21
|
+
/**
|
|
22
|
+
* Evalúa una instancia de política ejecutando sus reglas decoradas en orden.
|
|
23
|
+
*
|
|
24
|
+
* @param policyInstance La instancia de la política a evaluar
|
|
25
|
+
* @param signal Optional AbortSignal para cancelar la evaluación
|
|
26
|
+
* @returns Una decisión sobre qué hacer con la navegación
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const decision = await evaluator.evaluate(authPolicyInstance);
|
|
31
|
+
*
|
|
32
|
+
* if (decision.type === 'skip') {
|
|
33
|
+
* // Esta política no opina, intentar la siguiente
|
|
34
|
+
* } else if (decision.type === 'allow') {
|
|
35
|
+
* // Permitir la navegación
|
|
36
|
+
* } else if (decision.type === 'block') {
|
|
37
|
+
* // Bloquear la navegación
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
evaluate(policyInstance: any, signal?: AbortSignal): Promise<PolicyDecision>;
|
|
42
|
+
/**
|
|
43
|
+
* Evalúa una cadena de políticas en orden hasta que una tome una decisión.
|
|
44
|
+
*
|
|
45
|
+
* Este método implementa la composición de políticas:
|
|
46
|
+
* - Si una política retorna 'skip' (o ninguna regla coincide), pasa a la siguiente
|
|
47
|
+
* - Si una política retorna 'allow', 'block', o 'redirect', se detiene y retorna esa decisión
|
|
48
|
+
* - Si todas las políticas hacen skip, retorna la decisión por defecto
|
|
49
|
+
*
|
|
50
|
+
* @param policyInstances Array de instancias de políticas a evaluar en orden
|
|
51
|
+
* @param defaultDecision La decisión a tomar si todas las políticas hacen skip (default: allow)
|
|
52
|
+
* @param signal Optional AbortSignal para cancelar la evaluación
|
|
53
|
+
* @returns La decisión tomada por la primera política que no hizo skip
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const decision = await evaluator.evaluateChain([
|
|
58
|
+
* authPolicyInstance,
|
|
59
|
+
* featureFlagPolicyInstance,
|
|
60
|
+
* rolePolicyInstance
|
|
61
|
+
* ]);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
evaluateChain(policyInstances: any[], defaultDecision?: PolicyDecisionType, signal?: AbortSignal): Promise<PolicyDecision>;
|
|
65
|
+
/**
|
|
66
|
+
* Evalúa una lista de candidatos y retorna el primero que pase las policies.
|
|
67
|
+
*
|
|
68
|
+
* Este método maneja:
|
|
69
|
+
* - Candidatos sin policies (permitir por defecto)
|
|
70
|
+
* - Instanciación de policies desde el DI container
|
|
71
|
+
* - Inyección de metadata
|
|
72
|
+
* - Evaluación secuencial hasta encontrar un allow
|
|
73
|
+
*
|
|
74
|
+
* @param candidates Lista de candidatos a evaluar
|
|
75
|
+
* @param signal Optional AbortSignal para cancelar
|
|
76
|
+
* @returns Decisión con el candidato ganador o block/redirect
|
|
77
|
+
*/
|
|
78
|
+
evaluateCandidates(candidates: readonly RouteCandidate[], signal?: AbortSignal): Promise<PolicyDecision & {
|
|
79
|
+
candidate?: RouteCandidate;
|
|
80
|
+
}>;
|
|
81
|
+
}
|