zova-module-a-router 5.0.50 → 5.0.52

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-router",
3
- "version": "5.0.50",
3
+ "version": "5.0.52",
4
4
  "title": "a-router",
5
5
  "zovaModule": {
6
6
  "capabilities": {
@@ -40,5 +40,5 @@
40
40
  "dependencies": {
41
41
  "vue-router": "^4.3.2"
42
42
  },
43
- "gitHead": "66d4ffd9d942d46cfa9ee486742ca44a91bd7814"
43
+ "gitHead": "20d5666c9835e208eb0ab4c4f09f658d314795f4"
44
44
  }
@@ -2,6 +2,7 @@ import { Bean, BeanBase, Cast, IModule, IPageNameRecord, IPagePathRecord, TypeEv
2
2
  import { Router } from 'vue-router';
3
3
  import * as ModuleInfo from '@cabloy/module-info';
4
4
  import { IModuleRoute, IModuleRouteComponent } from '../types.js';
5
+ import { getRealRouteName } from '../utils.js';
5
6
 
6
7
  const SymbolRouter = Symbol('SymbolRouter');
7
8
 
@@ -21,21 +22,26 @@ export class BeanRouter extends BeanBase {
21
22
  }
22
23
 
23
24
  protected async __init__(router?: Router) {
24
- if (!router) {
25
+ if (router) {
26
+ this[SymbolRouter] = router;
27
+ } else {
25
28
  // app router
26
29
  router = this.bean.inject('a-router:appRouter');
27
30
  if (!router) {
28
31
  throw new Error('Should provide router');
29
32
  }
33
+ this[SymbolRouter] = router;
34
+ // provide
30
35
  this.app.vue.provide('a-router:router', this);
31
36
  this.bean.provide('a-router:router', this);
37
+ // config.routes
38
+ this._loadConfigRoutes();
32
39
  // event
33
40
  this.eventRouterGuards = this.app.meta.event.on('a-router:routerGuards', async (context, next) => {
34
41
  this._routerGuards(context.data);
35
42
  await next();
36
43
  });
37
44
  }
38
- this[SymbolRouter] = router;
39
45
  }
40
46
 
41
47
  protected __dispose__() {
@@ -102,24 +108,42 @@ export class BeanRouter extends BeanBase {
102
108
 
103
109
  private _routerGuards(router: BeanRouter) {
104
110
  router.beforeEach(async to => {
105
- // fullPath
106
- const fullPath = to.fullPath;
107
- // module info
108
- const moduleInfo = ModuleInfo.parseInfo(fullPath);
109
- if (!moduleInfo) {
110
- // donothing
111
- return;
111
+ // match path
112
+ let match = to.matched.find(item => item.aliasOf);
113
+ if (match) {
114
+ match = match.aliasOf;
115
+ } else {
116
+ match = to.matched[to.matched.length - 1];
117
+ // alias
118
+ const configRoute = this._findConfigRoute(match?.name, match?.path);
119
+ const alias = configRoute?.alias;
120
+ if (alias) {
121
+ // force load module
122
+ const resLoadModule = await this._forceLoadModule(match?.name, match?.path);
123
+ if (resLoadModule && resLoadModule !== true) return resLoadModule;
124
+ if (resLoadModule === false) return to.fullPath;
125
+ if (this.getRealRouteName(match?.name)) {
126
+ // @ts-ignore ignore
127
+ const routeAlias = this.resolveName(`$alias:${match?.name}`, {
128
+ params: to.params,
129
+ query: to.query,
130
+ });
131
+ return routeAlias.startsWith('/__alias__') ? routeAlias.substring('/__alias__'.length) : routeAlias;
132
+ } else {
133
+ return {
134
+ path: Array.isArray(alias) ? alias[0] : alias,
135
+ params: to.params,
136
+ query: to.query,
137
+ };
138
+ }
139
+ }
112
140
  }
113
- const moduleName = moduleInfo.relativeName;
114
- // check if exists
115
- if (!this.app.meta.module.exists(moduleName)) return '/404';
116
- // check if loaded
117
- const module = this.app.meta.module.get(moduleName, false);
118
- if (module) return;
119
- // use module
120
- await this.app.meta.module.use(moduleName);
141
+ // force load module
142
+ const resLoadModule = await this._forceLoadModule(match?.name, match?.path);
143
+ if (resLoadModule === true) return;
144
+ if (resLoadModule) return resLoadModule;
121
145
  // redirect again
122
- return fullPath;
146
+ return to.fullPath;
123
147
  });
124
148
  }
125
149
 
@@ -132,31 +156,46 @@ export class BeanRouter extends BeanBase {
132
156
  }
133
157
 
134
158
  private _registerRoute(module: IModule, route: IModuleRoute) {
135
- // meta
136
- const meta = route.meta;
159
+ // path
160
+ let path: string | undefined;
161
+ if (route.path) {
162
+ if (route.meta?.absolute === true) {
163
+ path = route.path;
164
+ } else {
165
+ path = `/${module.info.pid}/${module.info.name}/${route.path}`;
166
+ }
167
+ }
137
168
  // name
138
169
  let name: string | undefined;
139
170
  if (route.name) {
140
- if (meta?.absolute === true) {
171
+ if (route.meta?.absolute === true) {
141
172
  name = String(route.name);
142
173
  } else {
143
174
  name = `${module.info.relativeName}:${String(route.name)}`;
144
175
  }
145
176
  }
146
- // path
147
- let path: string | undefined;
148
- if (route.path) {
149
- if (meta?.absolute === true) {
150
- path = route.path;
151
- } else {
152
- path = `/${module.info.pid}/${module.info.name}/${route.path}`;
153
- }
177
+ // config route
178
+ const configRoute = name ? this.app.config.routes.name[name] : this.app.config.routes.path[path!];
179
+ if (configRoute) {
180
+ route = this.app.meta.util.extend({}, route, configRoute);
154
181
  }
182
+ // name alias
183
+ if (name && configRoute?.alias) {
184
+ // add extra route
185
+ this.router.addRoute({ name: `$alias:${name}`, path: `/__alias__${configRoute?.alias}`, redirect: '' });
186
+ }
187
+ // name
188
+ if (!name) {
189
+ name = `$:${path}`;
190
+ }
191
+ // meta
192
+ const meta = route.meta;
155
193
  // component
156
194
  const component = route.component;
157
195
  // layout / routeData
158
196
  let layout = meta?.layout;
159
197
  let routeData;
198
+ let routeNameParent;
160
199
  if (layout === false) {
161
200
  routeData = { ...route, name, path, component, meta };
162
201
  } else {
@@ -165,13 +204,74 @@ export class BeanRouter extends BeanBase {
165
204
  } else if (layout === 'empty') {
166
205
  layout = this.app.config.layout.component.empty;
167
206
  }
207
+ routeNameParent = `$:${name}`;
168
208
  routeData = {
209
+ name: routeNameParent,
169
210
  path,
170
211
  component: this.createAsyncComponent(layout as any),
171
212
  children: [{ ...route, name, path: '', component, meta }],
172
213
  };
173
214
  }
215
+ // force delete
216
+ if (this.router.hasRoute(routeNameParent)) {
217
+ this.router.removeRoute(routeNameParent);
218
+ }
219
+ if (this.router.hasRoute(name)) {
220
+ this.router.removeRoute(name);
221
+ }
174
222
  // add
175
223
  this.router.addRoute(routeData);
176
224
  }
225
+
226
+ private _loadConfigRoutes() {
227
+ const routesPath = this.app.config.routes.path;
228
+ for (const key in routesPath) {
229
+ const route = routesPath[key];
230
+ this._loadConfigRoute({ ...route, path: key, name: `$:${key}` });
231
+ }
232
+ const routesName = this.app.config.routes.name;
233
+ for (const key in routesName) {
234
+ const route = routesName[key];
235
+ this._loadConfigRoute({ ...route, path: route.path || route.alias, name: key });
236
+ }
237
+ }
238
+
239
+ private _loadConfigRoute(route: IModuleRoute) {
240
+ this.router.addRoute(route);
241
+ }
242
+
243
+ private _findConfigRoute(
244
+ name: string | symbol | null | undefined,
245
+ path: string | undefined,
246
+ ): IModuleRoute | undefined {
247
+ name = this.getRealRouteName(name);
248
+ return name ? this.app.config.routes.name[name] : this.app.config.routes.path[path!];
249
+ }
250
+
251
+ getRealRouteName(name?: string | symbol | null): string | undefined {
252
+ return getRealRouteName(name);
253
+ }
254
+
255
+ private async _forceLoadModule(
256
+ name: string | symbol | null | undefined,
257
+ path: string | undefined,
258
+ ): Promise<string | boolean | undefined> {
259
+ const nameOrPath = this.getRealRouteName(name) || path;
260
+ // module info
261
+ const moduleInfo = ModuleInfo.parseInfo(ModuleInfo.parseName(nameOrPath));
262
+ if (!moduleInfo) {
263
+ // donothing
264
+ return true;
265
+ }
266
+ const moduleName = moduleInfo.relativeName;
267
+ // check if exists
268
+ if (!this.app.meta.module.exists(moduleName)) return '/404';
269
+ // check if loaded
270
+ const module = this.app.meta.module.get(moduleName, false);
271
+ if (module) return true;
272
+ // use module
273
+ await this.app.meta.module.use(moduleName);
274
+ // means need load
275
+ return false;
276
+ }
177
277
  }
package/src/monkey.ts CHANGED
@@ -16,6 +16,7 @@ import { useRoute } from 'vue-router';
16
16
  import { BeanRouter } from './bean/bean.router.js';
17
17
  import { ScopeModule, __ThisModule__ } from './resource/this.js';
18
18
  import { markRaw } from 'vue';
19
+ import { getRealRouteName } from './utils.js';
19
20
 
20
21
  export class Monkey extends BeanSimple implements IMonkeySystem, IMonkeyModule, IMonkeyController {
21
22
  private _moduleSelf: IModule;
@@ -78,15 +79,20 @@ export class Monkey extends BeanSimple implements IMonkeySystem, IMonkeyModule,
78
79
  if (!(controller instanceof BeanControllerPageBase)) return;
79
80
  const route = controllerData.context.route;
80
81
  if (!route) return;
81
- const schemaKey = String(route.name || route.path);
82
+ const routeName = getRealRouteName(route.name);
83
+ const schemaKey = routeName || String(route.path);
82
84
  let schemas: TypePageSchema | undefined;
83
85
  const moduleInfo = ModuleInfo.parseInfo(ModuleInfo.parseName(schemaKey));
84
86
  if (!moduleInfo) {
85
87
  // do nothing
86
88
  return;
87
89
  }
90
+ if (!this.app.meta.module.exists(moduleInfo.relativeName)) {
91
+ // do nothing
92
+ return;
93
+ }
88
94
  const module = this.app.meta.module.get(moduleInfo.relativeName)!;
89
- if (route.name) {
95
+ if (routeName) {
90
96
  schemas = module.resource.pageNameSchemas?.[schemaKey];
91
97
  } else {
92
98
  schemas = module.resource.pagePathSchemas?.[schemaKey];
package/src/types.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { IComponentLayoutRecord, TypePageSchemas } from 'zova';
1
+ // @ts-ignore ignore
2
+ import { IComponentLayoutRecord, IPageNameRecord, IPagePathRecord, TypePageSchemas } from 'zova';
2
3
  import { RouteComponent, RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router';
3
4
  import { BeanRouter } from './bean/bean.router.js';
4
5
 
@@ -36,4 +37,9 @@ declare module 'zova' {
36
37
  pagePathSchemas?: TypePageSchemas;
37
38
  pageNameSchemas?: TypePageSchemas;
38
39
  }
40
+
41
+ export interface ZovaConfigRoutes {
42
+ path: Record<keyof IPagePathRecord, IModuleRoute>;
43
+ name: Record<keyof IPageNameRecord, IModuleRoute>;
44
+ }
39
45
  }
package/src/utils.ts ADDED
@@ -0,0 +1,6 @@
1
+ export function getRealRouteName(name?: string | symbol | null): string | undefined {
2
+ if (!name) return undefined;
3
+ name = String(name);
4
+ if (name.startsWith('$:')) return undefined;
5
+ return name;
6
+ }