zova-module-a-router 5.0.27

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016-present Zova
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "zova-module-a-router",
3
+ "version": "5.0.27",
4
+ "title": "a-router",
5
+ "cabloyModule": {
6
+ "capabilities": {
7
+ "monkey": true
8
+ }
9
+ },
10
+ "type": "module",
11
+ "exports": {
12
+ ".": {
13
+ "types": [
14
+ "./src/index.ts",
15
+ "./dist/index.d.ts"
16
+ ],
17
+ "import": "./src/index.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./*": "./*"
21
+ },
22
+ "description": "router",
23
+ "keywords": [
24
+ "Zova Module"
25
+ ],
26
+ "author": "zhennann",
27
+ "license": "MIT",
28
+ "files": [
29
+ "dist",
30
+ "src"
31
+ ],
32
+ "scripts": {
33
+ "clean": "tsc -b --clean",
34
+ "tsc:publish": "npm run clean && tsc -b",
35
+ "prepublishOnly": "npm run tsc:publish"
36
+ },
37
+ "dependencies": {
38
+ "vue-router": "^4.3.2"
39
+ },
40
+ "gitHead": "e452293f92ba46b87ab8d1bb19d4e507cb8a4654"
41
+ }
@@ -0,0 +1,164 @@
1
+ import { BeanBase, Cast, IModule, IPageNameRecord, IPagePathRecord, Store, TypeEventOff } from 'zova';
2
+ import { Router } from 'vue-router';
3
+ import * as ModuleInfo from '@cabloy/module-info';
4
+ import { IModuleRoute, IModuleRouteComponent } from '../types.js';
5
+
6
+ const SymbolRouter = Symbol('SymbolRouter');
7
+
8
+ export type StoreRouterLike = StoreRouter & Router;
9
+
10
+ @Store()
11
+ export class StoreRouter extends BeanBase {
12
+ [SymbolRouter]: Router;
13
+ eventRouterGuards: TypeEventOff;
14
+
15
+ get router(): Router {
16
+ return this[SymbolRouter];
17
+ }
18
+
19
+ protected __get__(prop) {
20
+ return this[SymbolRouter] && this[SymbolRouter][prop];
21
+ }
22
+
23
+ protected async __init__(router?: Router) {
24
+ if (!router) {
25
+ // app router
26
+ router = this.bean.inject('a-router:appRouter');
27
+ if (!router) {
28
+ throw new Error('Should provide router');
29
+ }
30
+ this.bean.provide('a-router:router', Cast<StoreRouterLike>(this));
31
+ // event
32
+ this.eventRouterGuards = this.app.meta.event.on('a-router:routerGuards', async (context, next) => {
33
+ this._routerGuards(context.data);
34
+ await next();
35
+ });
36
+ }
37
+ this[SymbolRouter] = router;
38
+ }
39
+
40
+ protected __dispose__() {
41
+ if (this.eventRouterGuards) {
42
+ this.eventRouterGuards();
43
+ }
44
+ }
45
+
46
+ public createAsyncComponent(component: string | IModuleRouteComponent) {
47
+ if (typeof component !== 'string') return component;
48
+ return this.app.meta.component.createAsyncComponent(component);
49
+ }
50
+
51
+ public resolveName<K extends keyof IPageNameRecord>(name: K, options?: IPageNameRecord[K]): string {
52
+ const params = Cast(options)?.params;
53
+ const query = Cast(options)?.query;
54
+ return this._resolveNameOrPath(query, query => {
55
+ const route = this[SymbolRouter].resolve({ name, params, query });
56
+ return route.fullPath;
57
+ });
58
+ }
59
+
60
+ public resolvePath<K extends keyof IPagePathRecord>(path: K, query?: IPagePathRecord[K]): string {
61
+ return this._resolveNameOrPath(query, query => {
62
+ const route = this[SymbolRouter].resolve({ path, query });
63
+ return route.fullPath;
64
+ });
65
+ }
66
+
67
+ private _resolveNameOrPath(query, fn) {
68
+ const query1 = {};
69
+ const query2: any = [];
70
+ if (query) {
71
+ for (const key in query) {
72
+ const value = query[key];
73
+ if (value && typeof value === 'object') {
74
+ query2.push([key, value]);
75
+ } else {
76
+ query1[key] = value;
77
+ }
78
+ }
79
+ }
80
+ // resolve
81
+ const fullPath = fn(query1);
82
+ // query2
83
+ const query2str = query2
84
+ .map(([key, value]) => {
85
+ return `${encodeURIComponent(key)}=${encodeURIComponent(JSON.stringify(value))}`;
86
+ })
87
+ .join('&');
88
+ // join
89
+ if (!query2str) return fullPath;
90
+ const join = Object.keys(query1).length > 0 ? '&' : '?';
91
+ return `${fullPath}${join}${query2str}`;
92
+ }
93
+
94
+ private _routerGuards(router: StoreRouterLike) {
95
+ router.beforeEach(async to => {
96
+ // fullPath
97
+ const fullPath = to.fullPath;
98
+ // module info
99
+ const moduleInfo = ModuleInfo.parseInfo(fullPath);
100
+ if (!moduleInfo) {
101
+ // donothing
102
+ return;
103
+ }
104
+ const module = this.app.meta.module.get(moduleInfo.relativeName);
105
+ if (module) return;
106
+ // use module
107
+ await this.app.meta.module.use(fullPath);
108
+ // redirect again
109
+ return fullPath;
110
+ });
111
+ }
112
+
113
+ /** @internal */
114
+ public _registerRoutes(module: IModule) {
115
+ if (!module.resource.routes) return null;
116
+ for (const route of module.resource.routes) {
117
+ this._registerRoute(module, route);
118
+ }
119
+ }
120
+
121
+ private _registerRoute(module: IModule, route: IModuleRoute) {
122
+ // meta
123
+ const meta = route.meta;
124
+ // name
125
+ let name: string | undefined;
126
+ if (route.name) {
127
+ if (meta?.absolute === true) {
128
+ name = String(route.name);
129
+ } else {
130
+ name = `${module.info.relativeName}:${String(route.name)}`;
131
+ }
132
+ }
133
+ // path
134
+ let path: string | undefined;
135
+ if (route.path) {
136
+ if (meta?.absolute === true) {
137
+ path = route.path;
138
+ } else {
139
+ path = `/${module.info.pid}/${module.info.name}/${route.path}`;
140
+ }
141
+ }
142
+ // component
143
+ const component = route.component;
144
+ // layout / routeData
145
+ let layout = meta?.layout;
146
+ let routeData;
147
+ if (layout === false) {
148
+ routeData = { ...route, name, path, component, meta };
149
+ } else {
150
+ if (layout === undefined || layout === 'default') {
151
+ layout = this.app.config.layout.component.default;
152
+ } else if (layout === 'empty') {
153
+ layout = this.app.config.layout.component.empty;
154
+ }
155
+ routeData = {
156
+ path,
157
+ component: this.createAsyncComponent(layout as any),
158
+ children: [{ ...route, name, path: '', component, meta }],
159
+ };
160
+ }
161
+ // add
162
+ this.router.addRoute(routeData);
163
+ }
164
+ }
@@ -0,0 +1,22 @@
1
+ import { BeanBase, TypeEventOff, Virtual } from 'zova';
2
+ import { StoreRouterLike } from './store.router.js';
3
+
4
+ @Virtual()
5
+ export class BeanRouterBase<TScopeModule = unknown> extends BeanBase<TScopeModule> {
6
+ private _eventRouterGuards: TypeEventOff;
7
+
8
+ protected async __init__() {
9
+ this._eventRouterGuards = this.app.meta.event.on('a-router:routerGuards', async (context, next) => {
10
+ this.onRouterGuards(context.data);
11
+ await next();
12
+ });
13
+ }
14
+
15
+ protected __dispose__() {
16
+ if (this._eventRouterGuards) {
17
+ this._eventRouterGuards();
18
+ }
19
+ }
20
+
21
+ protected onRouterGuards(_router: StoreRouterLike) {}
22
+ }
File without changes
@@ -0,0 +1,5 @@
1
+ import { ZovaApplication } from 'zova';
2
+
3
+ export const config = (_app: ZovaApplication) => {
4
+ return {};
5
+ };
@@ -0,0 +1 @@
1
+ export const constants = null;
@@ -0,0 +1 @@
1
+ export enum Errors {}
@@ -0,0 +1,4 @@
1
+ export * from './locales.js';
2
+ export * from './errors.js';
3
+ export * from './config.js';
4
+ export * from './constants.js';
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1,7 @@
1
+ import en_us from './locale/en-us.js';
2
+ import zh_cn from './locale/zh-cn.js';
3
+
4
+ export const locales = {
5
+ 'en-us': en_us,
6
+ 'zh-cn': zh_cn,
7
+ };
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './config/index.js';
2
+ export * from './resource/index.js';
3
+ export * from './routes.js';
4
+ export * from './types.js';
5
+ export * from './monkey.js';
6
+
7
+ import './typings.js';
package/src/monkey.ts ADDED
@@ -0,0 +1,85 @@
1
+ import {
2
+ BeanBase,
3
+ BeanContainerLike,
4
+ BeanControllerPageBase,
5
+ BeanSimple,
6
+ IModule,
7
+ IMonkeyModule,
8
+ IMonkeyController,
9
+ IMonkeySystem,
10
+ IControllerData,
11
+ TypePageSchema,
12
+ useComputed,
13
+ } from 'zova';
14
+ import * as ModuleInfo from '@cabloy/module-info';
15
+ import { useRoute } from 'vue-router';
16
+ import { StoreRouterLike } from './bean/store.router.js';
17
+
18
+ export class Monkey extends BeanSimple implements IMonkeySystem, IMonkeyModule, IMonkeyController {
19
+ private _storeRouter: StoreRouterLike;
20
+ private _moduleSelf: IModule;
21
+
22
+ constructor(moduleSelf: IModule) {
23
+ super();
24
+ this._moduleSelf = moduleSelf;
25
+ }
26
+
27
+ async getStoreRouter() {
28
+ if (!this._storeRouter) {
29
+ this._storeRouter = (await this.bean._getBean('a-router.store.router', false)) as StoreRouterLike;
30
+ }
31
+ return this._storeRouter;
32
+ }
33
+
34
+ async appInitialize() {}
35
+ async appInitialized() {
36
+ // emit event
37
+ const router = this.bean.inject('a-router:router');
38
+ await this.app.meta.event.emit('a-router:routerGuards', router);
39
+ }
40
+ async beanInit(bean: BeanContainerLike, beanInstance: BeanBase) {
41
+ bean.defineProperty(beanInstance, '$router', {
42
+ enumerable: false,
43
+ configurable: true,
44
+ get() {
45
+ return bean.inject('a-router:router');
46
+ },
47
+ });
48
+ }
49
+ async beanInited(_bean: BeanContainerLike, _beanInstance: BeanBase) {}
50
+ beanDispose(_bean: BeanContainerLike, _beanInstance: BeanBase) {}
51
+ beanDisposed(_bean: BeanContainerLike, _beanInstance: BeanBase) {}
52
+ async moduleLoading(module: IModule) {
53
+ if (this._moduleSelf === module) return;
54
+ const storeRouter = await this.getStoreRouter();
55
+ storeRouter._registerRoutes(module);
56
+ }
57
+ async moduleLoaded(_module: IModule) {}
58
+ async configLoaded(_module: IModule, _config) {}
59
+ controllerDataPrepare(controllerData: IControllerData) {
60
+ controllerData.context.route = useRoute();
61
+ }
62
+ controllerDataInit(controllerData: IControllerData, controller: BeanBase) {
63
+ // only for controller page
64
+ if (controller instanceof BeanControllerPageBase) {
65
+ const route = controllerData.context.route;
66
+ const schemaKey = String(route.name || route.path);
67
+ let schemas: TypePageSchema | undefined;
68
+ const moduleName = ModuleInfo.parseName(schemaKey)!;
69
+ const module = this.app.meta.module.get(moduleName)!;
70
+ if (route.name) {
71
+ schemas = module.resource.pageNameSchemas?.[schemaKey];
72
+ } else {
73
+ schemas = module.resource.pagePathSchemas?.[schemaKey];
74
+ }
75
+ controller.$params = useComputed(() => {
76
+ if (!schemas?.params) throw new Error(`page params schema not found: ${schemaKey}`);
77
+ return schemas.params.parse(route.params);
78
+ });
79
+ controller.$query = useComputed(() => {
80
+ if (!schemas?.query) throw new Error(`page query schema not found: ${schemaKey}`);
81
+ return schemas.query.parse(route.query);
82
+ });
83
+ }
84
+ }
85
+ }
File without changes
@@ -0,0 +1,9 @@
1
+ export * from '../bean/store.router.js';
2
+ export * from '../bean/virtual.router.js';
3
+ import { StoreRouter } from '../bean/store.router.js';
4
+ import 'zova';
5
+ declare module 'zova' {
6
+ export interface IBeanRecord {
7
+ 'a-router.store.router': StoreRouter;
8
+ }
9
+ }
@@ -0,0 +1 @@
1
+ export const components = {};
@@ -0,0 +1,12 @@
1
+ import { StoreRouterLike } from './beans.js';
2
+
3
+ import 'zova';
4
+ declare module 'zova' {
5
+ export interface IEventRecord {
6
+ 'a-router:routerGuards': StoreRouterLike;
7
+ }
8
+
9
+ export interface IEventResultRecord {
10
+ 'a-router:routerGuards': void;
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ export * from './scope.js';
2
+ export * from './beans.js';
3
+ export * from './components.js';
4
+ export * from './events.js';
5
+ export * from './injects.js';
@@ -0,0 +1,10 @@
1
+ import { Router } from 'vue-router';
2
+ import { StoreRouterLike } from '../bean/store.router.js';
3
+
4
+ import 'zova';
5
+ declare module 'zova' {
6
+ export interface IInjectRecord {
7
+ 'a-router:appRouter': Router;
8
+ 'a-router:router': StoreRouterLike;
9
+ }
10
+ }
@@ -0,0 +1,30 @@
1
+ import { BeanScopeBase, Scope, TypeLocaleBase, TypeModuleResource } from 'zova';
2
+ import { config, Errors, locales, constants } from '../config/index.js';
3
+ import { components } from './components.js';
4
+
5
+ @Scope()
6
+ export class ScopeModuleARouter extends BeanScopeBase {}
7
+
8
+ export interface ScopeModuleARouter
9
+ extends TypeModuleResource<
10
+ typeof components,
11
+ typeof config,
12
+ typeof Errors,
13
+ (typeof locales)[TypeLocaleBase],
14
+ typeof constants
15
+ > {}
16
+
17
+ import 'zova';
18
+ declare module 'zova' {
19
+ export interface IBeanScopeRecord {
20
+ 'a-router': ScopeModuleARouter;
21
+ }
22
+
23
+ export interface IBeanScopeConfig {
24
+ 'a-router': ReturnType<typeof config>;
25
+ }
26
+
27
+ export interface IBeanScopeLocale {
28
+ 'a-router': (typeof locales)[TypeLocaleBase];
29
+ }
30
+ }
@@ -0,0 +1,4 @@
1
+ export const __ThisModule__ = 'a-router';
2
+ export type __ThisModuleType__ = typeof __ThisModule__;
3
+
4
+ export { ScopeModuleARouter as ScopeModule } from './scope.js';
package/src/routes.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { IModuleRoute } from 'zova-module-a-router';
2
+
3
+ export const routes: IModuleRoute[] = [];
package/src/types.ts ADDED
@@ -0,0 +1,35 @@
1
+ import { TypePageSchemas } from 'zova';
2
+ import { RouteComponent, RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router';
3
+ import { StoreRouterLike } from './bean/store.router.js';
4
+
5
+ export type Lazy<T> = () => Promise<T>;
6
+ export type IModuleRouteComponent = RouteComponent | Lazy<RouteComponent>;
7
+ export type IModuleRoute = RouteRecordRaw;
8
+
9
+ import 'vue-router';
10
+ declare module 'vue-router' {
11
+ interface RouteMeta {
12
+ absolute?: boolean;
13
+ layout?: 'empty' | 'default' | false | string | IModuleRouteComponent;
14
+ requiresAuth?: boolean;
15
+ }
16
+ }
17
+
18
+ declare module 'zova' {
19
+ export interface BeanBase {
20
+ $router: StoreRouterLike;
21
+ }
22
+
23
+ export interface IModuleResource {
24
+ routes: IModuleRoute[];
25
+ }
26
+
27
+ export interface IControllerDataContext {
28
+ route: RouteLocationNormalizedLoaded;
29
+ }
30
+
31
+ export interface IModuleResource {
32
+ pagePathSchemas?: TypePageSchemas;
33
+ pageNameSchemas?: TypePageSchemas;
34
+ }
35
+ }
package/src/typings.ts ADDED
@@ -0,0 +1 @@
1
+ export {};