@simplysm/solid 13.0.49 → 13.0.51
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/dist/helpers/createAppStructure.d.ts +8 -3
- package/dist/helpers/createAppStructure.d.ts.map +1 -1
- package/dist/helpers/createAppStructure.js +71 -33
- package/dist/helpers/createAppStructure.js.map +1 -1
- package/docs/hooks.md +30 -17
- package/package.json +3 -3
- package/src/helpers/createAppStructure.ts +90 -36
|
@@ -45,10 +45,14 @@ export interface AppFlatPerm<TModule = string> {
|
|
|
45
45
|
titleChain: string[];
|
|
46
46
|
code: string;
|
|
47
47
|
modulesChain: TModule[][];
|
|
48
|
+
requiredModulesChain: TModule[][];
|
|
48
49
|
}
|
|
49
|
-
export interface AppRoute {
|
|
50
|
+
export interface AppRoute<TModule = string> {
|
|
50
51
|
path: string;
|
|
51
52
|
component: Component;
|
|
53
|
+
permCode?: string;
|
|
54
|
+
modulesChain: TModule[][];
|
|
55
|
+
requiredModulesChain: TModule[][];
|
|
52
56
|
}
|
|
53
57
|
export interface AppFlatMenu {
|
|
54
58
|
titleChain: string[];
|
|
@@ -56,11 +60,12 @@ export interface AppFlatMenu {
|
|
|
56
60
|
}
|
|
57
61
|
export interface AppStructure<TModule> {
|
|
58
62
|
items: AppStructureItem<TModule>[];
|
|
59
|
-
|
|
63
|
+
allRoutes: AppRoute<TModule>[];
|
|
60
64
|
usableMenus: Accessor<AppMenu[]>;
|
|
61
65
|
usableFlatMenus: Accessor<AppFlatMenu[]>;
|
|
62
66
|
usablePerms: Accessor<AppPerm<TModule>[]>;
|
|
63
|
-
|
|
67
|
+
allFlatPerms: AppFlatPerm<TModule>[];
|
|
68
|
+
checkRouteAccess(route: AppRoute<TModule>): boolean;
|
|
64
69
|
getTitleChainByHref(href: string): string[];
|
|
65
70
|
}
|
|
66
71
|
type PermKey<TItem> = TItem extends {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAppStructure.d.ts","sourceRoot":"","sources":["..\\..\\src\\helpers\\createAppStructure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,KAAK,QAAQ,EAA0B,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIvD,MAAM,WAAW,qBAAqB,CAAC,OAAO;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB,CAAC,OAAO;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAChC,qBAAqB,CAAC,OAAO,CAAC,GAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAElC,MAAM,WAAW,mBAAmB,CAAC,OAAO;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,KAAK,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;CAC3B;AAID,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,OAAO,CAAC,OAAO,GAAG,MAAM;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW,CAAC,OAAO,GAAG,MAAM;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"createAppStructure.d.ts","sourceRoot":"","sources":["..\\..\\src\\helpers\\createAppStructure.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,21 +12,32 @@ function checkModules(modules, requiredModules, usableModules) {
|
|
|
12
12
|
}
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
|
-
function
|
|
15
|
+
function buildAllRoutes(items, routeBasePath, permBasePath, modulesChain, requiredModulesChain) {
|
|
16
16
|
var _a;
|
|
17
17
|
const result = [];
|
|
18
18
|
for (const item of items) {
|
|
19
|
-
|
|
19
|
+
const currModulesChain = item.modules ? [...modulesChain, item.modules] : modulesChain;
|
|
20
|
+
const currRequiredModulesChain = item.requiredModules ? [...requiredModulesChain, item.requiredModules] : requiredModulesChain;
|
|
20
21
|
const routePath = routeBasePath + "/" + item.code;
|
|
21
22
|
const permPath = permBasePath + "/" + item.code;
|
|
22
23
|
if (isGroupItem(item)) {
|
|
23
24
|
result.push(
|
|
24
|
-
...
|
|
25
|
+
...buildAllRoutes(
|
|
26
|
+
item.children,
|
|
27
|
+
routePath,
|
|
28
|
+
permPath,
|
|
29
|
+
currModulesChain,
|
|
30
|
+
currRequiredModulesChain
|
|
31
|
+
)
|
|
25
32
|
);
|
|
26
33
|
} else if (item.component !== void 0) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
result.push({
|
|
35
|
+
path: routePath,
|
|
36
|
+
component: item.component,
|
|
37
|
+
permCode: ((_a = item.perms) == null ? void 0 : _a.includes("use")) ? permPath + "/use" : void 0,
|
|
38
|
+
modulesChain: currModulesChain,
|
|
39
|
+
requiredModulesChain: currRequiredModulesChain
|
|
40
|
+
});
|
|
30
41
|
}
|
|
31
42
|
}
|
|
32
43
|
return result;
|
|
@@ -98,20 +109,23 @@ function collectFlatPerms(items) {
|
|
|
98
109
|
item,
|
|
99
110
|
titleChain: [],
|
|
100
111
|
codePath: "",
|
|
101
|
-
modulesChain: []
|
|
112
|
+
modulesChain: [],
|
|
113
|
+
requiredModulesChain: []
|
|
102
114
|
}));
|
|
103
115
|
while (queue.length > 0) {
|
|
104
|
-
const { item, titleChain, codePath, modulesChain } = queue.shift();
|
|
116
|
+
const { item, titleChain, codePath, modulesChain, requiredModulesChain } = queue.shift();
|
|
105
117
|
const currTitleChain = [...titleChain, item.title];
|
|
106
118
|
const currCodePath = codePath + "/" + item.code;
|
|
107
119
|
const currModulesChain = item.modules ? [...modulesChain, item.modules] : modulesChain;
|
|
120
|
+
const currRequiredModulesChain = item.requiredModules ? [...requiredModulesChain, item.requiredModules] : requiredModulesChain;
|
|
108
121
|
if (isGroupItem(item)) {
|
|
109
122
|
for (const child of item.children) {
|
|
110
123
|
queue.push({
|
|
111
124
|
item: child,
|
|
112
125
|
titleChain: currTitleChain,
|
|
113
126
|
codePath: currCodePath,
|
|
114
|
-
modulesChain: currModulesChain
|
|
127
|
+
modulesChain: currModulesChain,
|
|
128
|
+
requiredModulesChain: currRequiredModulesChain
|
|
115
129
|
});
|
|
116
130
|
}
|
|
117
131
|
} else {
|
|
@@ -120,18 +134,21 @@ function collectFlatPerms(items) {
|
|
|
120
134
|
results.push({
|
|
121
135
|
titleChain: currTitleChain,
|
|
122
136
|
code: currCodePath + "/" + perm,
|
|
123
|
-
modulesChain: currModulesChain
|
|
137
|
+
modulesChain: currModulesChain,
|
|
138
|
+
requiredModulesChain: currRequiredModulesChain
|
|
124
139
|
});
|
|
125
140
|
}
|
|
126
141
|
}
|
|
127
142
|
if (item.subPerms) {
|
|
128
143
|
for (const subPerm of item.subPerms) {
|
|
129
144
|
const subModulesChain = subPerm.modules ? [...currModulesChain, subPerm.modules] : currModulesChain;
|
|
145
|
+
const subRequiredModulesChain = subPerm.requiredModules ? [...currRequiredModulesChain, subPerm.requiredModules] : currRequiredModulesChain;
|
|
130
146
|
for (const perm of subPerm.perms) {
|
|
131
147
|
results.push({
|
|
132
148
|
titleChain: currTitleChain,
|
|
133
149
|
code: currCodePath + "/" + subPerm.code + "/" + perm,
|
|
134
|
-
modulesChain: subModulesChain
|
|
150
|
+
modulesChain: subModulesChain,
|
|
151
|
+
requiredModulesChain: subRequiredModulesChain
|
|
135
152
|
});
|
|
136
153
|
}
|
|
137
154
|
}
|
|
@@ -196,26 +213,24 @@ function findItemChainByCodes(items, codes) {
|
|
|
196
213
|
return result;
|
|
197
214
|
}
|
|
198
215
|
function createAppStructure(opts) {
|
|
199
|
-
const
|
|
216
|
+
const allFlatPerms = collectFlatPerms(opts.items);
|
|
217
|
+
const allRoutes = [];
|
|
218
|
+
for (const top of opts.items) {
|
|
219
|
+
if (isGroupItem(top)) {
|
|
220
|
+
const topModulesChain = top.modules ? [top.modules] : [];
|
|
221
|
+
const topRequiredModulesChain = top.requiredModules ? [top.requiredModules] : [];
|
|
222
|
+
allRoutes.push(
|
|
223
|
+
...buildAllRoutes(
|
|
224
|
+
top.children,
|
|
225
|
+
"",
|
|
226
|
+
"/" + top.code,
|
|
227
|
+
topModulesChain,
|
|
228
|
+
topRequiredModulesChain
|
|
229
|
+
)
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
200
233
|
const memos = createRoot(() => {
|
|
201
|
-
const usableRoutes = createMemo(() => {
|
|
202
|
-
var _a, _b;
|
|
203
|
-
const routes = [];
|
|
204
|
-
for (const top of opts.items) {
|
|
205
|
-
if (isGroupItem(top)) {
|
|
206
|
-
routes.push(
|
|
207
|
-
...buildUsableRoutes(
|
|
208
|
-
top.children,
|
|
209
|
-
"",
|
|
210
|
-
"/" + top.code,
|
|
211
|
-
(_a = opts.usableModules) == null ? void 0 : _a.call(opts),
|
|
212
|
-
(_b = opts.permRecord) == null ? void 0 : _b.call(opts)
|
|
213
|
-
)
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return routes;
|
|
218
|
-
});
|
|
219
234
|
const usableMenus = createMemo(() => {
|
|
220
235
|
var _a, _b;
|
|
221
236
|
const menus = [];
|
|
@@ -238,16 +253,39 @@ function createAppStructure(opts) {
|
|
|
238
253
|
var _a;
|
|
239
254
|
return buildPerms(opts.items, "", (_a = opts.usableModules) == null ? void 0 : _a.call(opts));
|
|
240
255
|
});
|
|
241
|
-
return {
|
|
256
|
+
return { usableMenus, usableFlatMenus, usablePerms };
|
|
242
257
|
});
|
|
243
258
|
const permsObj = buildPermsObject(opts.items, "", opts.permRecord);
|
|
244
259
|
return {
|
|
245
260
|
items: opts.items,
|
|
246
|
-
|
|
261
|
+
allRoutes,
|
|
247
262
|
usableMenus: memos.usableMenus,
|
|
248
263
|
usableFlatMenus: memos.usableFlatMenus,
|
|
249
264
|
usablePerms: memos.usablePerms,
|
|
250
|
-
|
|
265
|
+
allFlatPerms,
|
|
266
|
+
checkRouteAccess(route) {
|
|
267
|
+
var _a, _b;
|
|
268
|
+
const usableModules = (_a = opts.usableModules) == null ? void 0 : _a.call(opts);
|
|
269
|
+
if (usableModules !== void 0) {
|
|
270
|
+
for (const modules of route.modulesChain) {
|
|
271
|
+
if (modules.length > 0 && !modules.some((m) => usableModules.includes(m))) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
for (const modules of route.requiredModulesChain) {
|
|
276
|
+
if (modules.length > 0 && !modules.every((m) => usableModules.includes(m))) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (route.permCode !== void 0) {
|
|
282
|
+
const permRecord = (_b = opts.permRecord) == null ? void 0 : _b.call(opts);
|
|
283
|
+
if (permRecord !== void 0) {
|
|
284
|
+
return permRecord[route.permCode] ?? false;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return true;
|
|
288
|
+
},
|
|
251
289
|
perms: permsObj,
|
|
252
290
|
getTitleChainByHref(href) {
|
|
253
291
|
const codes = href.split("/").filter(Boolean);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/helpers/createAppStructure.ts"],
|
|
4
|
-
"mappings": "AACA,SAAwB,YAAY,kBAAkB;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/docs/hooks.md
CHANGED
|
@@ -241,11 +241,12 @@ const structure = createAppStructure({
|
|
|
241
241
|
permRecord: () => userPermissions(), // optional: Record<string, boolean> permission state
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
-
// structure.
|
|
245
|
-
// structure.usableMenus()
|
|
246
|
-
// structure.usableFlatMenus()
|
|
247
|
-
// structure.usablePerms()
|
|
248
|
-
// structure.
|
|
244
|
+
// structure.allRoutes -- AppRoute[] - all routes with permCode + module info (static)
|
|
245
|
+
// structure.usableMenus() -- Accessor<AppMenu[]> - filtered menu array for Sidebar.Menu
|
|
246
|
+
// structure.usableFlatMenus() -- Accessor<AppFlatMenu[]> - flat filtered menu list
|
|
247
|
+
// structure.usablePerms() -- Accessor<AppPerm[]> - filtered permission tree
|
|
248
|
+
// structure.allFlatPerms -- AppFlatPerm[] - all flat perm entries (static)
|
|
249
|
+
// structure.checkRouteAccess(r) -- boolean - check if route is accessible
|
|
249
250
|
```
|
|
250
251
|
|
|
251
252
|
**Routing integration with `@solidjs/router`:**
|
|
@@ -253,7 +254,6 @@ const structure = createAppStructure({
|
|
|
253
254
|
```tsx
|
|
254
255
|
import { render } from "solid-js/web";
|
|
255
256
|
import { HashRouter, Navigate, Route } from "@solidjs/router";
|
|
256
|
-
import { For } from "solid-js";
|
|
257
257
|
import { appStructure } from "./appStructure";
|
|
258
258
|
|
|
259
259
|
render(
|
|
@@ -262,9 +262,17 @@ render(
|
|
|
262
262
|
<Route path="/" component={App}>
|
|
263
263
|
<Route path="/home" component={Home}>
|
|
264
264
|
<Route path="/" component={() => <Navigate href="/home/main" />} />
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
{appStructure.allRoutes.map((r) => (
|
|
266
|
+
<Route
|
|
267
|
+
path={r.path}
|
|
268
|
+
component={() => {
|
|
269
|
+
if (!appStructure.checkRouteAccess(r)) {
|
|
270
|
+
return <Navigate href="/login" />;
|
|
271
|
+
}
|
|
272
|
+
return <r.component />;
|
|
273
|
+
}}
|
|
274
|
+
/>
|
|
275
|
+
))}
|
|
268
276
|
<Route path="/*" component={NotFoundPage} />
|
|
269
277
|
</Route>
|
|
270
278
|
<Route path="/" component={() => <Navigate href="/home" />} />
|
|
@@ -275,25 +283,29 @@ render(
|
|
|
275
283
|
);
|
|
276
284
|
```
|
|
277
285
|
|
|
278
|
-
|
|
286
|
+
`allRoutes` is a static (non-reactive) array containing all routes with `permCode` and module chain information. Use `checkRouteAccess(route)` to reactively verify access based on `permRecord` and `usableModules` signals.
|
|
279
287
|
|
|
280
288
|
**AppStructure return type:**
|
|
281
289
|
|
|
282
290
|
```typescript
|
|
283
291
|
interface AppStructure<TModule> {
|
|
284
292
|
items: AppStructureItem<TModule>[];
|
|
285
|
-
|
|
286
|
-
usableMenus: Accessor<AppMenu[]>;
|
|
287
|
-
usableFlatMenus: Accessor<AppFlatMenu[]>;
|
|
288
|
-
usablePerms: Accessor<AppPerm<TModule>[]>;
|
|
289
|
-
|
|
293
|
+
allRoutes: AppRoute<TModule>[]; // static, all routes with perm/module info
|
|
294
|
+
usableMenus: Accessor<AppMenu[]>; // reactive, filtered by modules + permRecord
|
|
295
|
+
usableFlatMenus: Accessor<AppFlatMenu[]>; // reactive, flat version of usableMenus
|
|
296
|
+
usablePerms: Accessor<AppPerm<TModule>[]>; // reactive, filtered permission tree
|
|
297
|
+
allFlatPerms: AppFlatPerm<TModule>[]; // static, all perm entries (not reactive)
|
|
298
|
+
checkRouteAccess(route: AppRoute<TModule>): boolean; // reactive access check
|
|
290
299
|
getTitleChainByHref(href: string): string[];
|
|
291
|
-
perms: InferPerms<TItems>;
|
|
300
|
+
perms: InferPerms<TItems>; // typed permission accessor (getter-based reactive booleans)
|
|
292
301
|
}
|
|
293
302
|
|
|
294
|
-
interface AppRoute {
|
|
303
|
+
interface AppRoute<TModule = string> {
|
|
295
304
|
path: string;
|
|
296
305
|
component: Component;
|
|
306
|
+
permCode?: string;
|
|
307
|
+
modulesChain: TModule[][];
|
|
308
|
+
requiredModulesChain: TModule[][];
|
|
297
309
|
}
|
|
298
310
|
|
|
299
311
|
interface AppMenu {
|
|
@@ -320,6 +332,7 @@ interface AppFlatPerm<TModule = string> {
|
|
|
320
332
|
titleChain: string[];
|
|
321
333
|
code: string;
|
|
322
334
|
modulesChain: TModule[][];
|
|
335
|
+
requiredModulesChain: TModule[][];
|
|
323
336
|
}
|
|
324
337
|
```
|
|
325
338
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/solid",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.51",
|
|
4
4
|
"description": "심플리즘 패키지 - SolidJS 라이브러리",
|
|
5
5
|
"author": "김석래",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"solid-tiptap": "^0.8.0",
|
|
50
50
|
"tailwind-merge": "^3.5.0",
|
|
51
51
|
"tailwindcss": "^3.4.19",
|
|
52
|
-
"@simplysm/core-browser": "13.0.
|
|
53
|
-
"@simplysm/core-common": "13.0.
|
|
52
|
+
"@simplysm/core-browser": "13.0.51",
|
|
53
|
+
"@simplysm/core-common": "13.0.51"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@solidjs/testing-library": "^0.8.10"
|
|
@@ -58,11 +58,15 @@ export interface AppFlatPerm<TModule = string> {
|
|
|
58
58
|
titleChain: string[];
|
|
59
59
|
code: string;
|
|
60
60
|
modulesChain: TModule[][];
|
|
61
|
+
requiredModulesChain: TModule[][];
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
export interface AppRoute {
|
|
64
|
+
export interface AppRoute<TModule = string> {
|
|
64
65
|
path: string;
|
|
65
66
|
component: Component;
|
|
67
|
+
permCode?: string;
|
|
68
|
+
modulesChain: TModule[][];
|
|
69
|
+
requiredModulesChain: TModule[][];
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
export interface AppFlatMenu {
|
|
@@ -72,11 +76,12 @@ export interface AppFlatMenu {
|
|
|
72
76
|
|
|
73
77
|
export interface AppStructure<TModule> {
|
|
74
78
|
items: AppStructureItem<TModule>[];
|
|
75
|
-
|
|
79
|
+
allRoutes: AppRoute<TModule>[];
|
|
76
80
|
usableMenus: Accessor<AppMenu[]>;
|
|
77
81
|
usableFlatMenus: Accessor<AppFlatMenu[]>;
|
|
78
82
|
usablePerms: Accessor<AppPerm<TModule>[]>;
|
|
79
|
-
|
|
83
|
+
allFlatPerms: AppFlatPerm<TModule>[];
|
|
84
|
+
checkRouteAccess(route: AppRoute<TModule>): boolean;
|
|
80
85
|
getTitleChainByHref(href: string): string[];
|
|
81
86
|
}
|
|
82
87
|
|
|
@@ -141,29 +146,44 @@ function checkModules<TModule>(
|
|
|
141
146
|
|
|
142
147
|
// ── Routes ──
|
|
143
148
|
|
|
144
|
-
function
|
|
149
|
+
function buildAllRoutes<TModule>(
|
|
145
150
|
items: AppStructureItem<TModule>[],
|
|
146
151
|
routeBasePath: string,
|
|
147
152
|
permBasePath: string,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
): AppRoute[] {
|
|
151
|
-
const result: AppRoute[] = [];
|
|
153
|
+
modulesChain: TModule[][],
|
|
154
|
+
requiredModulesChain: TModule[][],
|
|
155
|
+
): AppRoute<TModule>[] {
|
|
156
|
+
const result: AppRoute<TModule>[] = [];
|
|
152
157
|
|
|
153
158
|
for (const item of items) {
|
|
154
|
-
|
|
159
|
+
const currModulesChain: TModule[][] = item.modules
|
|
160
|
+
? [...modulesChain, item.modules]
|
|
161
|
+
: modulesChain;
|
|
162
|
+
const currRequiredModulesChain: TModule[][] = item.requiredModules
|
|
163
|
+
? [...requiredModulesChain, item.requiredModules]
|
|
164
|
+
: requiredModulesChain;
|
|
155
165
|
|
|
156
166
|
const routePath = routeBasePath + "/" + item.code;
|
|
157
167
|
const permPath = permBasePath + "/" + item.code;
|
|
158
168
|
|
|
159
169
|
if (isGroupItem(item)) {
|
|
160
170
|
result.push(
|
|
161
|
-
...
|
|
171
|
+
...buildAllRoutes(
|
|
172
|
+
item.children,
|
|
173
|
+
routePath,
|
|
174
|
+
permPath,
|
|
175
|
+
currModulesChain,
|
|
176
|
+
currRequiredModulesChain,
|
|
177
|
+
),
|
|
162
178
|
);
|
|
163
179
|
} else if (item.component !== undefined) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
180
|
+
result.push({
|
|
181
|
+
path: routePath,
|
|
182
|
+
component: item.component,
|
|
183
|
+
permCode: item.perms?.includes("use") ? permPath + "/use" : undefined,
|
|
184
|
+
modulesChain: currModulesChain,
|
|
185
|
+
requiredModulesChain: currRequiredModulesChain,
|
|
186
|
+
});
|
|
167
187
|
}
|
|
168
188
|
}
|
|
169
189
|
|
|
@@ -267,6 +287,7 @@ function collectFlatPerms<TModule>(items: AppStructureItem<TModule>[]): AppFlatP
|
|
|
267
287
|
titleChain: string[];
|
|
268
288
|
codePath: string;
|
|
269
289
|
modulesChain: TModule[][];
|
|
290
|
+
requiredModulesChain: TModule[][];
|
|
270
291
|
}
|
|
271
292
|
|
|
272
293
|
const queue: QueueItem[] = items.map((item) => ({
|
|
@@ -274,16 +295,20 @@ function collectFlatPerms<TModule>(items: AppStructureItem<TModule>[]): AppFlatP
|
|
|
274
295
|
titleChain: [],
|
|
275
296
|
codePath: "",
|
|
276
297
|
modulesChain: [],
|
|
298
|
+
requiredModulesChain: [],
|
|
277
299
|
}));
|
|
278
300
|
|
|
279
301
|
while (queue.length > 0) {
|
|
280
|
-
const { item, titleChain, codePath, modulesChain } = queue.shift()!;
|
|
302
|
+
const { item, titleChain, codePath, modulesChain, requiredModulesChain } = queue.shift()!;
|
|
281
303
|
|
|
282
304
|
const currTitleChain = [...titleChain, item.title];
|
|
283
305
|
const currCodePath = codePath + "/" + item.code;
|
|
284
306
|
const currModulesChain: TModule[][] = item.modules
|
|
285
307
|
? [...modulesChain, item.modules]
|
|
286
308
|
: modulesChain;
|
|
309
|
+
const currRequiredModulesChain: TModule[][] = item.requiredModules
|
|
310
|
+
? [...requiredModulesChain, item.requiredModules]
|
|
311
|
+
: requiredModulesChain;
|
|
287
312
|
|
|
288
313
|
if (isGroupItem(item)) {
|
|
289
314
|
for (const child of item.children) {
|
|
@@ -292,6 +317,7 @@ function collectFlatPerms<TModule>(items: AppStructureItem<TModule>[]): AppFlatP
|
|
|
292
317
|
titleChain: currTitleChain,
|
|
293
318
|
codePath: currCodePath,
|
|
294
319
|
modulesChain: currModulesChain,
|
|
320
|
+
requiredModulesChain: currRequiredModulesChain,
|
|
295
321
|
});
|
|
296
322
|
}
|
|
297
323
|
} else {
|
|
@@ -301,6 +327,7 @@ function collectFlatPerms<TModule>(items: AppStructureItem<TModule>[]): AppFlatP
|
|
|
301
327
|
titleChain: currTitleChain,
|
|
302
328
|
code: currCodePath + "/" + perm,
|
|
303
329
|
modulesChain: currModulesChain,
|
|
330
|
+
requiredModulesChain: currRequiredModulesChain,
|
|
304
331
|
});
|
|
305
332
|
}
|
|
306
333
|
}
|
|
@@ -310,12 +337,16 @@ function collectFlatPerms<TModule>(items: AppStructureItem<TModule>[]): AppFlatP
|
|
|
310
337
|
const subModulesChain: TModule[][] = subPerm.modules
|
|
311
338
|
? [...currModulesChain, subPerm.modules]
|
|
312
339
|
: currModulesChain;
|
|
340
|
+
const subRequiredModulesChain: TModule[][] = subPerm.requiredModules
|
|
341
|
+
? [...currRequiredModulesChain, subPerm.requiredModules]
|
|
342
|
+
: currRequiredModulesChain;
|
|
313
343
|
|
|
314
344
|
for (const perm of subPerm.perms) {
|
|
315
345
|
results.push({
|
|
316
346
|
titleChain: currTitleChain,
|
|
317
347
|
code: currCodePath + "/" + subPerm.code + "/" + perm,
|
|
318
348
|
modulesChain: subModulesChain,
|
|
349
|
+
requiredModulesChain: subRequiredModulesChain,
|
|
319
350
|
});
|
|
320
351
|
}
|
|
321
352
|
}
|
|
@@ -408,27 +439,26 @@ export function createAppStructure<
|
|
|
408
439
|
usableModules?: Accessor<TModule[] | undefined>;
|
|
409
440
|
permRecord?: Accessor<Record<string, boolean> | undefined>;
|
|
410
441
|
}): AppStructure<TModule> & { perms: InferPerms<TItems> } {
|
|
411
|
-
const
|
|
442
|
+
const allFlatPerms = collectFlatPerms(opts.items);
|
|
443
|
+
|
|
444
|
+
const allRoutes: AppRoute<TModule>[] = [];
|
|
445
|
+
for (const top of opts.items) {
|
|
446
|
+
if (isGroupItem(top)) {
|
|
447
|
+
const topModulesChain: TModule[][] = top.modules ? [top.modules] : [];
|
|
448
|
+
const topRequiredModulesChain: TModule[][] = top.requiredModules ? [top.requiredModules] : [];
|
|
449
|
+
allRoutes.push(
|
|
450
|
+
...buildAllRoutes(
|
|
451
|
+
top.children,
|
|
452
|
+
"",
|
|
453
|
+
"/" + top.code,
|
|
454
|
+
topModulesChain,
|
|
455
|
+
topRequiredModulesChain,
|
|
456
|
+
),
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
412
460
|
|
|
413
461
|
const memos = createRoot(() => {
|
|
414
|
-
const usableRoutes = createMemo(() => {
|
|
415
|
-
const routes: AppRoute[] = [];
|
|
416
|
-
for (const top of opts.items) {
|
|
417
|
-
if (isGroupItem(top)) {
|
|
418
|
-
routes.push(
|
|
419
|
-
...buildUsableRoutes(
|
|
420
|
-
top.children,
|
|
421
|
-
"",
|
|
422
|
-
"/" + top.code,
|
|
423
|
-
opts.usableModules?.(),
|
|
424
|
-
opts.permRecord?.(),
|
|
425
|
-
),
|
|
426
|
-
);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
return routes;
|
|
430
|
-
});
|
|
431
|
-
|
|
432
462
|
const usableMenus = createMemo(() => {
|
|
433
463
|
const menus: AppMenu[] = [];
|
|
434
464
|
for (const top of opts.items) {
|
|
@@ -450,18 +480,42 @@ export function createAppStructure<
|
|
|
450
480
|
|
|
451
481
|
const usablePerms = createMemo(() => buildPerms(opts.items, "", opts.usableModules?.()));
|
|
452
482
|
|
|
453
|
-
return {
|
|
483
|
+
return { usableMenus, usableFlatMenus, usablePerms };
|
|
454
484
|
});
|
|
455
485
|
|
|
456
486
|
const permsObj = buildPermsObject(opts.items, "", opts.permRecord);
|
|
457
487
|
|
|
458
488
|
return {
|
|
459
489
|
items: opts.items,
|
|
460
|
-
|
|
490
|
+
allRoutes,
|
|
461
491
|
usableMenus: memos.usableMenus,
|
|
462
492
|
usableFlatMenus: memos.usableFlatMenus,
|
|
463
493
|
usablePerms: memos.usablePerms,
|
|
464
|
-
|
|
494
|
+
allFlatPerms,
|
|
495
|
+
checkRouteAccess(route: AppRoute<TModule>): boolean {
|
|
496
|
+
const usableModules = opts.usableModules?.();
|
|
497
|
+
if (usableModules !== undefined) {
|
|
498
|
+
for (const modules of route.modulesChain) {
|
|
499
|
+
if (modules.length > 0 && !modules.some((m) => usableModules.includes(m))) {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
for (const modules of route.requiredModulesChain) {
|
|
504
|
+
if (modules.length > 0 && !modules.every((m) => usableModules.includes(m))) {
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (route.permCode !== undefined) {
|
|
511
|
+
const permRecord = opts.permRecord?.();
|
|
512
|
+
if (permRecord !== undefined) {
|
|
513
|
+
return permRecord[route.permCode] ?? false;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
return true;
|
|
518
|
+
},
|
|
465
519
|
perms: permsObj as InferPerms<TItems>,
|
|
466
520
|
getTitleChainByHref(href: string): string[] {
|
|
467
521
|
const codes = href.split("/").filter(Boolean);
|