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 +21 -0
- package/package.json +41 -0
- package/src/bean/store.router.ts +164 -0
- package/src/bean/virtual.router.ts +22 -0
- package/src/component/.gitkeep +0 -0
- package/src/config/config.ts +5 -0
- package/src/config/constants.ts +1 -0
- package/src/config/errors.ts +1 -0
- package/src/config/index.ts +4 -0
- package/src/config/locale/en-us.ts +1 -0
- package/src/config/locale/zh-cn.ts +1 -0
- package/src/config/locales.ts +7 -0
- package/src/index.ts +7 -0
- package/src/monkey.ts +85 -0
- package/src/page/.gitkeep +0 -0
- package/src/resource/beans.ts +9 -0
- package/src/resource/components.ts +1 -0
- package/src/resource/events.ts +12 -0
- package/src/resource/index.ts +5 -0
- package/src/resource/injects.ts +10 -0
- package/src/resource/scope.ts +30 -0
- package/src/resource/this.ts +4 -0
- package/src/routes.ts +3 -0
- package/src/types.ts +35 -0
- package/src/typings.ts +1 -0
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 @@
|
|
|
1
|
+
export const constants = null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export enum Errors {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
package/src/index.ts
ADDED
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,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
|
+
}
|
package/src/routes.ts
ADDED
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 {};
|