@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,308 @@
|
|
|
1
|
+
import { Inject } from "../DI/decorators/inject.js";
|
|
2
|
+
import { Service } from "../DI/decorators/service.js";
|
|
3
|
+
import { State } from "../reactivity/decorators/state.js";
|
|
4
|
+
import { Effect } from "../reactivity/decorators/effect.js";
|
|
5
|
+
import { Computed } from "../reactivity/decorators/computed.js";
|
|
6
|
+
import { Trie } from "./trie.js";
|
|
7
|
+
import { PolicyEvaluator } from "./policy-evaluator.js";
|
|
8
|
+
import { reactiveContext } from "../reactivity/reactive-context.js";
|
|
9
|
+
var __create = Object.create;
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
13
|
+
var __typeError = (msg) => {
|
|
14
|
+
throw TypeError(msg);
|
|
15
|
+
};
|
|
16
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
17
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
18
|
+
var __decoratorStart = (base) => [, , , __create(null)];
|
|
19
|
+
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
20
|
+
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
|
|
21
|
+
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
|
|
22
|
+
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
|
|
23
|
+
var __runInitializers = (array, flags, self, value) => {
|
|
24
|
+
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);
|
|
25
|
+
return value;
|
|
26
|
+
};
|
|
27
|
+
var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
28
|
+
var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
|
|
29
|
+
var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
|
|
30
|
+
var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
|
|
31
|
+
var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
|
|
32
|
+
return __privateGet(this, extra);
|
|
33
|
+
}, set [name](x) {
|
|
34
|
+
return __privateSet(this, extra, x);
|
|
35
|
+
} }, name));
|
|
36
|
+
k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
|
|
37
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
38
|
+
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
|
|
39
|
+
if (k) {
|
|
40
|
+
ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
|
|
41
|
+
if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
|
|
42
|
+
if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
|
|
43
|
+
}
|
|
44
|
+
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;
|
|
45
|
+
if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
|
|
46
|
+
else if (typeof it !== "object" || it === null) __typeError("Object expected");
|
|
47
|
+
else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
|
|
48
|
+
}
|
|
49
|
+
return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
50
|
+
};
|
|
51
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
52
|
+
var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
|
|
53
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
54
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
55
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
56
|
+
var _syncRouteCandidates_dec, _syncQueryParams_dec, _syncRouteParams_dec, _$routeCandidates_dec, _$queryParams_dec, _$params_dec, _policyEvaluator_dec, _routeTrie_dec, _activePatterns_dec, _currentPath_dec, _search_dec, _pathname_dec, _Router_decorators, _init;
|
|
57
|
+
_Router_decorators = [Service], _pathname_dec = [State], _search_dec = [State], _currentPath_dec = [Computed], _activePatterns_dec = [Computed], _routeTrie_dec = [Inject(Trie)], _policyEvaluator_dec = [Inject(PolicyEvaluator)], _$params_dec = [State], _$queryParams_dec = [State], _$routeCandidates_dec = [State], _syncRouteParams_dec = [Effect], _syncQueryParams_dec = [Effect], _syncRouteCandidates_dec = [Effect];
|
|
58
|
+
class Router {
|
|
59
|
+
constructor() {
|
|
60
|
+
__runInitializers(_init, 5, this);
|
|
61
|
+
this.pathname = __runInitializers(_init, 8, this, ""), __runInitializers(_init, 11, this);
|
|
62
|
+
this.search = __runInitializers(_init, 12, this, ""), __runInitializers(_init, 15, this);
|
|
63
|
+
this.routeTrie = __runInitializers(_init, 16, this), __runInitializers(_init, 19, this);
|
|
64
|
+
this.policyEvaluator = __runInitializers(_init, 20, this), __runInitializers(_init, 23, this);
|
|
65
|
+
this.$params = __runInitializers(_init, 24, this, {}), __runInitializers(_init, 27, this);
|
|
66
|
+
this.$queryParams = __runInitializers(_init, 28, this, {}), __runInitializers(_init, 31, this);
|
|
67
|
+
this.$routeCandidates = __runInitializers(_init, 32, this, []), __runInitializers(_init, 35, this);
|
|
68
|
+
this.hasInitialized = false;
|
|
69
|
+
this.routesLoaded = false;
|
|
70
|
+
this.$routeCandidates = [];
|
|
71
|
+
}
|
|
72
|
+
get currentPath() {
|
|
73
|
+
return this.pathname;
|
|
74
|
+
}
|
|
75
|
+
get activePatterns() {
|
|
76
|
+
return this.$routeCandidates.map(
|
|
77
|
+
(candidates) => candidates.length > 0 ? candidates[0].path : ""
|
|
78
|
+
).filter((path) => path !== "");
|
|
79
|
+
}
|
|
80
|
+
async onBootstrap() {
|
|
81
|
+
if (this.hasInitialized) return;
|
|
82
|
+
if (!this.routesLoaded) {
|
|
83
|
+
await this.loadGeneratedRoutes();
|
|
84
|
+
}
|
|
85
|
+
this.hasInitialized = true;
|
|
86
|
+
window.addEventListener("popstate", () => {
|
|
87
|
+
this.pathname = window.location.pathname;
|
|
88
|
+
this.search = window.location.search;
|
|
89
|
+
});
|
|
90
|
+
this.pathname = window.location.pathname;
|
|
91
|
+
this.search = window.location.search;
|
|
92
|
+
}
|
|
93
|
+
syncRouteParams() {
|
|
94
|
+
const match = this.routeTrie.find(this.pathname);
|
|
95
|
+
const currentKeys = reactiveContext.untrack(() => Object.keys(this.$params));
|
|
96
|
+
if (match) {
|
|
97
|
+
const newParams = match.params;
|
|
98
|
+
for (const key of currentKeys) {
|
|
99
|
+
if (!(key in newParams)) {
|
|
100
|
+
delete this.$params[key];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
for (const key in newParams) {
|
|
104
|
+
this.$params[key] = newParams[key];
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
for (const key of currentKeys) {
|
|
108
|
+
delete this.$params[key];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
syncQueryParams() {
|
|
113
|
+
const searchParams = new URLSearchParams(this.search);
|
|
114
|
+
const currentKeys = reactiveContext.untrack(() => Object.keys(this.$queryParams));
|
|
115
|
+
for (const key of currentKeys) {
|
|
116
|
+
if (!searchParams.has(key)) {
|
|
117
|
+
delete this.$queryParams[key];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
searchParams.forEach((value, key) => {
|
|
121
|
+
this.$queryParams[key] = value;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
syncRouteCandidates() {
|
|
125
|
+
const match = this.routeTrie.find(this.pathname);
|
|
126
|
+
const maxDepth = this.routeTrie.maxDepth;
|
|
127
|
+
const currentLength = reactiveContext.untrack(() => this.$routeCandidates.length);
|
|
128
|
+
if (currentLength < maxDepth) {
|
|
129
|
+
for (let i = currentLength; i < maxDepth; i++) {
|
|
130
|
+
this.$routeCandidates.push([]);
|
|
131
|
+
}
|
|
132
|
+
} else if (currentLength > maxDepth) {
|
|
133
|
+
this.$routeCandidates.length = maxDepth;
|
|
134
|
+
}
|
|
135
|
+
if (match) {
|
|
136
|
+
const { candidatesByLevel } = match;
|
|
137
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
138
|
+
const newCandidates = candidatesByLevel[i] || [];
|
|
139
|
+
const currentCandidates = reactiveContext.untrack(() => this.$routeCandidates[i]);
|
|
140
|
+
if (!this.candidatesAreEqual(currentCandidates, newCandidates)) {
|
|
141
|
+
this.$routeCandidates[i] = newCandidates;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
146
|
+
const currentCandidates = reactiveContext.untrack(() => this.$routeCandidates[i]);
|
|
147
|
+
if (currentCandidates.length > 0) {
|
|
148
|
+
this.$routeCandidates[i] = [];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Compara dos arrays de candidatos para determinar si son iguales
|
|
155
|
+
* Usa comparación por id para determinar identidad
|
|
156
|
+
*/
|
|
157
|
+
candidatesAreEqual(a, b) {
|
|
158
|
+
if (a.length !== b.length) return false;
|
|
159
|
+
for (let i = 0; i < a.length; i++) {
|
|
160
|
+
if (a[i].id !== b[i].id) return false;
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Fuerza la re-evaluación de todos los route candidates
|
|
166
|
+
* recalculando los candidatos desde el Trie.
|
|
167
|
+
*
|
|
168
|
+
* Esto hace que todos los RouteView detecten el cambio y re-ejecuten
|
|
169
|
+
* sus Resources, incluyendo la evaluación de policies.
|
|
170
|
+
*
|
|
171
|
+
* Útil después de cambios de estado que afectan autorización (ej: OAuth login)
|
|
172
|
+
*/
|
|
173
|
+
revalidateRouteCandidates() {
|
|
174
|
+
console.log("[Router] Revalidating all route candidates");
|
|
175
|
+
const match = this.routeTrie.find(this.pathname);
|
|
176
|
+
const maxDepth = this.routeTrie.maxDepth;
|
|
177
|
+
if (match) {
|
|
178
|
+
const { candidatesByLevel } = match;
|
|
179
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
180
|
+
const newCandidates = candidatesByLevel[i] || [];
|
|
181
|
+
this.$routeCandidates[i] = [...newCandidates];
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
185
|
+
this.$routeCandidates[i] = [];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
navigate(to, options) {
|
|
190
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(to) || to.startsWith("//")) {
|
|
191
|
+
if (options?.external === "native" || options?.external === void 0) {
|
|
192
|
+
window.location.href = to;
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (options?.external === "block") {
|
|
196
|
+
console.warn(`[Router] External navigation blocked: ${to}`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const currentUrl = window.location.href;
|
|
201
|
+
const url = new URL(to, currentUrl);
|
|
202
|
+
const newPathname = url.pathname;
|
|
203
|
+
const newSearch = url.search;
|
|
204
|
+
const newHash = url.hash;
|
|
205
|
+
const pathnameChanged = this.pathname !== newPathname;
|
|
206
|
+
const searchChanged = this.search !== newSearch;
|
|
207
|
+
if (!pathnameChanged && !searchChanged && !options?.revalidate) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const fullPath = newPathname + newSearch + newHash;
|
|
211
|
+
const historyMethod = options?.replace ? "replaceState" : "pushState";
|
|
212
|
+
window.history[historyMethod](null, "", fullPath);
|
|
213
|
+
if (pathnameChanged) {
|
|
214
|
+
this.pathname = newPathname;
|
|
215
|
+
}
|
|
216
|
+
if (searchChanged) {
|
|
217
|
+
this.search = newSearch;
|
|
218
|
+
}
|
|
219
|
+
if (options?.revalidate) {
|
|
220
|
+
this.revalidateRouteCandidates();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Carga las rutas generadas por el plugin de Vite
|
|
225
|
+
* Intenta múltiples rutas posibles donde el archivo puede estar generado
|
|
226
|
+
*/
|
|
227
|
+
async loadGeneratedRoutes() {
|
|
228
|
+
const possiblePaths = [
|
|
229
|
+
"/app/router/generated-routes",
|
|
230
|
+
// Ruta más común según el plugin
|
|
231
|
+
"@/router/generated-routes",
|
|
232
|
+
// Usando alias @ si está configurado
|
|
233
|
+
"/src/router/generated-routes",
|
|
234
|
+
// Alternativa común
|
|
235
|
+
"/router/generated-routes",
|
|
236
|
+
// Si está en la raíz
|
|
237
|
+
"./app/router/generated-routes",
|
|
238
|
+
// Relativa (fallback)
|
|
239
|
+
"./src/router/generated-routes"
|
|
240
|
+
// Relativa (fallback)
|
|
241
|
+
];
|
|
242
|
+
let routes = null;
|
|
243
|
+
let lastError = null;
|
|
244
|
+
for (const routePath of possiblePaths) {
|
|
245
|
+
try {
|
|
246
|
+
const module = await import(
|
|
247
|
+
/* @vite-ignore */
|
|
248
|
+
routePath
|
|
249
|
+
);
|
|
250
|
+
routes = module.default || module.routes || null;
|
|
251
|
+
if (routes && Array.isArray(routes)) {
|
|
252
|
+
break;
|
|
253
|
+
} else {
|
|
254
|
+
console.log(`[Router.loadGeneratedRoutes] ⚠️ ${routePath} existe pero no exporta rutas válidas`);
|
|
255
|
+
}
|
|
256
|
+
} catch (error) {
|
|
257
|
+
lastError = error;
|
|
258
|
+
console.log(`[Router.loadGeneratedRoutes] ❌ Error en ${routePath}:`, error.message);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (!routes || !Array.isArray(routes)) {
|
|
263
|
+
console.warn("⚠️ Could not load generated routes. Make sure the route generator plugin is configured correctly.");
|
|
264
|
+
console.warn(" Tried paths:", possiblePaths);
|
|
265
|
+
if (lastError) {
|
|
266
|
+
console.warn(" Last error:", lastError.message);
|
|
267
|
+
}
|
|
268
|
+
console.warn(" Tip: Make sure generated-routes.ts exists and exports default an array of routes.");
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
this.registerGeneratedRoutes(routes);
|
|
272
|
+
this.routesLoaded = true;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Registra un array de rutas generadas en el Trie
|
|
276
|
+
* @param routes Array de rutas generadas por el plugin
|
|
277
|
+
*/
|
|
278
|
+
registerGeneratedRoutes(routes) {
|
|
279
|
+
for (const route of routes) {
|
|
280
|
+
this.routeTrie.insert(
|
|
281
|
+
route.id,
|
|
282
|
+
route.path,
|
|
283
|
+
route.loader,
|
|
284
|
+
route.metadata,
|
|
285
|
+
route.policies,
|
|
286
|
+
route.slot
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
_init = __decoratorStart();
|
|
292
|
+
__decorateElement(_init, 2, "currentPath", _currentPath_dec, Router);
|
|
293
|
+
__decorateElement(_init, 2, "activePatterns", _activePatterns_dec, Router);
|
|
294
|
+
__decorateElement(_init, 1, "syncRouteParams", _syncRouteParams_dec, Router);
|
|
295
|
+
__decorateElement(_init, 1, "syncQueryParams", _syncQueryParams_dec, Router);
|
|
296
|
+
__decorateElement(_init, 1, "syncRouteCandidates", _syncRouteCandidates_dec, Router);
|
|
297
|
+
__decorateElement(_init, 5, "pathname", _pathname_dec, Router);
|
|
298
|
+
__decorateElement(_init, 5, "search", _search_dec, Router);
|
|
299
|
+
__decorateElement(_init, 5, "routeTrie", _routeTrie_dec, Router);
|
|
300
|
+
__decorateElement(_init, 5, "policyEvaluator", _policyEvaluator_dec, Router);
|
|
301
|
+
__decorateElement(_init, 5, "$params", _$params_dec, Router);
|
|
302
|
+
__decorateElement(_init, 5, "$queryParams", _$queryParams_dec, Router);
|
|
303
|
+
__decorateElement(_init, 5, "$routeCandidates", _$routeCandidates_dec, Router);
|
|
304
|
+
Router = __decorateElement(_init, 0, "Router", _Router_decorators, Router);
|
|
305
|
+
__runInitializers(_init, 1, Router);
|
|
306
|
+
export {
|
|
307
|
+
Router
|
|
308
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static Analysis Module for Route Decorators
|
|
3
|
+
*
|
|
4
|
+
* Este módulo proporciona herramientas para analizar estáticamente
|
|
5
|
+
* decoradores @Route en archivos TypeScript y extraer información
|
|
6
|
+
* sobre las rutas de la aplicación.
|
|
7
|
+
*
|
|
8
|
+
* @module static-analysis
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
export { parseRouteDecorators, type ParsedRoute } from './parser';
|
|
12
|
+
export { scanDirectory, printScanSummary, type ScanResult, type ScanOptions } from './scanner';
|
|
13
|
+
/**
|
|
14
|
+
* @example Parser básico
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { parseRouteDecorators } from '@framework/router/static-analysis';
|
|
17
|
+
*
|
|
18
|
+
* const routes = parseRouteDecorators('./src/pages/products.ts');
|
|
19
|
+
* console.log(routes);
|
|
20
|
+
* // [
|
|
21
|
+
* // {
|
|
22
|
+
* // path: '/products',
|
|
23
|
+
* // className: 'ProductsPage',
|
|
24
|
+
* // filePath: './src/pages/products.ts',
|
|
25
|
+
* // raw: '@Route("/products")'
|
|
26
|
+
* // }
|
|
27
|
+
* // ]
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Scanner de directorios
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { scanDirectory } from '@framework/router/static-analysis';
|
|
33
|
+
*
|
|
34
|
+
* const result = await scanDirectory('./src/pages');
|
|
35
|
+
* console.log(`Found ${result.totalRoutes} routes in ${result.filesWithRoutes} files`);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ParsedRoute {
|
|
2
|
+
path: string;
|
|
3
|
+
className: string;
|
|
4
|
+
filePath: string;
|
|
5
|
+
metadata?: Record<string, any>;
|
|
6
|
+
policies?: string[];
|
|
7
|
+
slot?: string;
|
|
8
|
+
raw: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parser básico de decoradores @Route
|
|
12
|
+
* Lee un archivo TypeScript y detecta decoradores @Route
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseRouteDecorators(filePath: string): ParsedRoute[];
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
function parseRouteDecorators(filePath) {
|
|
3
|
+
const program = ts.createProgram([filePath], {
|
|
4
|
+
target: ts.ScriptTarget.ESNext,
|
|
5
|
+
module: ts.ModuleKind.ESNext
|
|
6
|
+
});
|
|
7
|
+
const sourceFile = program.getSourceFile(filePath);
|
|
8
|
+
if (!sourceFile) {
|
|
9
|
+
throw new Error(`Could not load source file: ${filePath}`);
|
|
10
|
+
}
|
|
11
|
+
const routes = [];
|
|
12
|
+
const sourceFileNonNull = sourceFile;
|
|
13
|
+
function visit(node) {
|
|
14
|
+
if (ts.isClassDeclaration(node)) {
|
|
15
|
+
const className = node.name?.getText(sourceFileNonNull) || "AnonymousClass";
|
|
16
|
+
let decorators;
|
|
17
|
+
if (ts.canHaveDecorators(node)) {
|
|
18
|
+
decorators = ts.getDecorators(node);
|
|
19
|
+
}
|
|
20
|
+
if (!decorators && node.decorators) {
|
|
21
|
+
decorators = node.decorators;
|
|
22
|
+
}
|
|
23
|
+
if (decorators && decorators.length > 0) {
|
|
24
|
+
decorators.forEach((decorator) => {
|
|
25
|
+
const text = decorator.getText(sourceFileNonNull);
|
|
26
|
+
if (text.includes("@Route") || text.includes("Route(")) {
|
|
27
|
+
const parsedRoute = parseRouteDecoratorExpression(decorator, sourceFileNonNull, className, filePath);
|
|
28
|
+
if (parsedRoute) {
|
|
29
|
+
routes.push(parsedRoute);
|
|
30
|
+
} else {
|
|
31
|
+
routes.push({
|
|
32
|
+
raw: text,
|
|
33
|
+
className,
|
|
34
|
+
filePath,
|
|
35
|
+
path: ""
|
|
36
|
+
// No pudimos extraer el path
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
ts.forEachChild(node, visit);
|
|
44
|
+
}
|
|
45
|
+
visit(sourceFileNonNull);
|
|
46
|
+
return routes;
|
|
47
|
+
}
|
|
48
|
+
function parseRouteDecoratorExpression(decorator, sourceFile, className, filePath) {
|
|
49
|
+
const expression = decorator.expression;
|
|
50
|
+
if (ts.isCallExpression(expression)) {
|
|
51
|
+
const args = expression.arguments;
|
|
52
|
+
if (args.length > 0) {
|
|
53
|
+
const pathArg = args[0];
|
|
54
|
+
if (ts.isStringLiteral(pathArg)) {
|
|
55
|
+
const path = pathArg.text;
|
|
56
|
+
const raw = decorator.getText(sourceFile);
|
|
57
|
+
const result = {
|
|
58
|
+
path,
|
|
59
|
+
className,
|
|
60
|
+
filePath,
|
|
61
|
+
raw
|
|
62
|
+
};
|
|
63
|
+
if (args.length > 1) {
|
|
64
|
+
const configArg = args[1];
|
|
65
|
+
if (ts.isObjectLiteralExpression(configArg)) {
|
|
66
|
+
const config = parseConfigObject(configArg, sourceFile);
|
|
67
|
+
if (config.metadata) {
|
|
68
|
+
result.metadata = config.metadata;
|
|
69
|
+
}
|
|
70
|
+
if (config.policies) {
|
|
71
|
+
result.policies = config.policies;
|
|
72
|
+
}
|
|
73
|
+
if (config.slot) {
|
|
74
|
+
result.slot = config.slot;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
function parseConfigObject(objectLiteral, sourceFile) {
|
|
85
|
+
const config = {};
|
|
86
|
+
objectLiteral.properties.forEach((prop) => {
|
|
87
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
88
|
+
const name = prop.name.getText(sourceFile);
|
|
89
|
+
if (name === "policies" && ts.isArrayLiteralExpression(prop.initializer)) {
|
|
90
|
+
config.policies = prop.initializer.elements.map((el) => el.getText(sourceFile)).filter(Boolean);
|
|
91
|
+
} else if (name === "metadata" && ts.isObjectLiteralExpression(prop.initializer)) {
|
|
92
|
+
config.metadata = parseMetadataObject(prop.initializer, sourceFile);
|
|
93
|
+
} else if (name === "slot" && ts.isStringLiteral(prop.initializer)) {
|
|
94
|
+
config.slot = prop.initializer.text;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
return config;
|
|
99
|
+
}
|
|
100
|
+
function parseMetadataObject(objectLiteral, sourceFile) {
|
|
101
|
+
const metadata = {};
|
|
102
|
+
objectLiteral.properties.forEach((prop) => {
|
|
103
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
104
|
+
const key = prop.name.getText(sourceFile);
|
|
105
|
+
const value = parseValue(prop.initializer, sourceFile);
|
|
106
|
+
metadata[key] = value;
|
|
107
|
+
} else if (ts.isShorthandPropertyAssignment(prop)) {
|
|
108
|
+
const key = prop.name.getText(sourceFile);
|
|
109
|
+
metadata[key] = key;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return metadata;
|
|
113
|
+
}
|
|
114
|
+
function parseValue(node, sourceFile) {
|
|
115
|
+
if (node.kind === ts.SyntaxKind.TrueKeyword) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
if (node.kind === ts.SyntaxKind.FalseKeyword) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
if (ts.isStringLiteral(node)) {
|
|
122
|
+
return node.text;
|
|
123
|
+
}
|
|
124
|
+
if (ts.isNumericLiteral(node)) {
|
|
125
|
+
const num = parseFloat(node.text);
|
|
126
|
+
return isNaN(num) ? node.text : num;
|
|
127
|
+
}
|
|
128
|
+
if (node.kind === ts.SyntaxKind.NullKeyword) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
if (node.kind === ts.SyntaxKind.UndefinedKeyword) {
|
|
132
|
+
return void 0;
|
|
133
|
+
}
|
|
134
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
135
|
+
return parseMetadataObject(node, sourceFile);
|
|
136
|
+
}
|
|
137
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
138
|
+
return node.elements.map((el) => parseValue(el, sourceFile));
|
|
139
|
+
}
|
|
140
|
+
if (ts.isTemplateExpression(node)) {
|
|
141
|
+
return node.getText(sourceFile);
|
|
142
|
+
}
|
|
143
|
+
return node.getText(sourceFile);
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
parseRouteDecorators
|
|
147
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ParsedRoute } from './parser';
|
|
2
|
+
export type { ParsedRoute };
|
|
3
|
+
/**
|
|
4
|
+
* Resultado del escaneo de directorios
|
|
5
|
+
*/
|
|
6
|
+
export interface ScanResult {
|
|
7
|
+
routes: ParsedRoute[];
|
|
8
|
+
filesScanned: number;
|
|
9
|
+
filesWithRoutes: number;
|
|
10
|
+
totalRoutes: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Opciones para el scanner
|
|
14
|
+
*/
|
|
15
|
+
export interface ScanOptions {
|
|
16
|
+
extensions?: string[];
|
|
17
|
+
exclude?: string[];
|
|
18
|
+
verbose?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Escanea recursivamente un directorio buscando archivos con decoradores @Route
|
|
22
|
+
*/
|
|
23
|
+
export declare function scanDirectory(dirPath: string, options?: ScanOptions): Promise<ScanResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Imprime un resumen bonito del escaneo
|
|
26
|
+
*/
|
|
27
|
+
export declare function printScanSummary(result: ScanResult): void;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { parseRouteDecorators } from "./parser.js";
|
|
4
|
+
const DEFAULT_OPTIONS = {
|
|
5
|
+
extensions: [".ts", ".tsx"],
|
|
6
|
+
exclude: ["node_modules", "dist", "build", ".git"],
|
|
7
|
+
verbose: false
|
|
8
|
+
};
|
|
9
|
+
async function scanDirectory(dirPath, options = {}) {
|
|
10
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
11
|
+
log(config, `
|
|
12
|
+
🔍 Scanning directory: ${dirPath}`);
|
|
13
|
+
const files = await getAllTypeScriptFiles(dirPath, config);
|
|
14
|
+
log(config, `📂 Found ${files.length} TypeScript files`);
|
|
15
|
+
const routes = await extractRoutesFromFiles(files, config);
|
|
16
|
+
const filesWithRoutes = new Set(routes.map((r) => r.filePath)).size;
|
|
17
|
+
return {
|
|
18
|
+
routes,
|
|
19
|
+
filesScanned: files.length,
|
|
20
|
+
filesWithRoutes,
|
|
21
|
+
totalRoutes: routes.length
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async function getAllTypeScriptFiles(dirPath, config) {
|
|
25
|
+
const files = [];
|
|
26
|
+
await traverseDirectory(dirPath, async (filePath) => {
|
|
27
|
+
if (isTypeScriptFile(filePath, config)) {
|
|
28
|
+
files.push(filePath);
|
|
29
|
+
}
|
|
30
|
+
}, config);
|
|
31
|
+
return files;
|
|
32
|
+
}
|
|
33
|
+
async function traverseDirectory(dirPath, onFile, config) {
|
|
34
|
+
try {
|
|
35
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
38
|
+
if (entry.isDirectory()) {
|
|
39
|
+
if (shouldExcludeDirectory(entry.name, config)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
await traverseDirectory(fullPath, onFile, config);
|
|
43
|
+
} else if (entry.isFile()) {
|
|
44
|
+
await onFile(fullPath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
log(config, `⚠️ Cannot read directory: ${dirPath}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function isTypeScriptFile(filePath, config) {
|
|
52
|
+
return config.extensions.some((ext) => filePath.endsWith(ext));
|
|
53
|
+
}
|
|
54
|
+
function shouldExcludeDirectory(dirName, config) {
|
|
55
|
+
return config.exclude.includes(dirName);
|
|
56
|
+
}
|
|
57
|
+
async function extractRoutesFromFiles(files, config) {
|
|
58
|
+
const allRoutes = [];
|
|
59
|
+
for (const filePath of files) {
|
|
60
|
+
const hasRoutes = await quickCheckForRouteDecorator(filePath);
|
|
61
|
+
if (!hasRoutes) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const routes = parseRouteDecorators(filePath);
|
|
66
|
+
if (routes.length > 0) {
|
|
67
|
+
log(config, ` ✓ ${path.basename(filePath)}: ${routes.length} route(s)`);
|
|
68
|
+
allRoutes.push(...routes);
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
log(config, ` ✗ Error parsing ${filePath}: ${error}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return allRoutes;
|
|
75
|
+
}
|
|
76
|
+
async function quickCheckForRouteDecorator(filePath) {
|
|
77
|
+
try {
|
|
78
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
79
|
+
return content.includes("@Route");
|
|
80
|
+
} catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function log(config, message) {
|
|
85
|
+
if (config.verbose) {
|
|
86
|
+
console.log(message);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
scanDirectory
|
|
91
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FindResult } from './trie.types';
|
|
2
|
+
import { Constructor } from '../DI/types';
|
|
3
|
+
export declare class Trie {
|
|
4
|
+
private readonly root;
|
|
5
|
+
private _maxDepth;
|
|
6
|
+
insert(id: string, path: string, loader: () => Promise<any>, metadata?: Record<string, any>, policies?: Constructor<any>[], slot?: string): void;
|
|
7
|
+
find(path: string): FindResult | null;
|
|
8
|
+
/**
|
|
9
|
+
* Retorna la profundidad máxima de rutas registradas en el Trie
|
|
10
|
+
* @returns Número de niveles (0 = solo root, 1 = un segmento, etc.)
|
|
11
|
+
*/
|
|
12
|
+
get maxDepth(): number;
|
|
13
|
+
private createNode;
|
|
14
|
+
}
|