@simplysm/solid 13.0.47 → 13.0.48
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 +37 -5
- package/dist/helpers/createAppStructure.d.ts.map +1 -1
- package/dist/helpers/createAppStructure.js +46 -0
- package/dist/helpers/createAppStructure.js.map +1 -1
- package/docs/hooks.md +43 -0
- package/package.json +3 -3
- package/src/helpers/createAppStructure.ts +99 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Accessor } from "solid-js";
|
|
2
1
|
import type { Component } from "solid-js";
|
|
2
|
+
import { type Accessor } from "solid-js";
|
|
3
3
|
import type { IconProps } from "@tabler/icons-solidjs";
|
|
4
4
|
export interface AppStructureGroupItem<TModule> {
|
|
5
5
|
code: string;
|
|
@@ -63,9 +63,41 @@ export interface AppStructure<TModule> {
|
|
|
63
63
|
flatPerms: AppFlatPerm<TModule>[];
|
|
64
64
|
getTitleChainByHref(href: string): string[];
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
type PermKey<TItem> = TItem extends {
|
|
67
|
+
code: infer C extends string;
|
|
68
|
+
} ? TItem extends {
|
|
69
|
+
children: any;
|
|
70
|
+
} ? C : TItem extends {
|
|
71
|
+
perms: any;
|
|
72
|
+
} | {
|
|
73
|
+
subPerms: any;
|
|
74
|
+
} ? C : never : never;
|
|
75
|
+
type InferLeafPerms<TItem> = (TItem extends {
|
|
76
|
+
perms: (infer P extends string)[];
|
|
77
|
+
} ? {
|
|
78
|
+
[K in P]: boolean;
|
|
79
|
+
} : unknown) & (TItem extends {
|
|
80
|
+
subPerms: (infer S)[];
|
|
81
|
+
} ? {
|
|
82
|
+
[K in S & {
|
|
83
|
+
code: string;
|
|
84
|
+
} as K["code"]]: K extends {
|
|
85
|
+
perms: (infer P extends string)[];
|
|
86
|
+
} ? {
|
|
87
|
+
[J in P]: boolean;
|
|
88
|
+
} : never;
|
|
89
|
+
} : unknown);
|
|
90
|
+
type InferPerms<TItems extends any[]> = {
|
|
91
|
+
[Item in TItems[number] as PermKey<Item>]: Item extends {
|
|
92
|
+
children: infer C extends any[];
|
|
93
|
+
} ? InferPerms<C> : InferLeafPerms<Item>;
|
|
94
|
+
};
|
|
95
|
+
export declare function createAppStructure<TModule, const TItems extends AppStructureItem<TModule>[]>(opts: {
|
|
96
|
+
items: TItems;
|
|
68
97
|
usableModules?: Accessor<TModule[] | undefined>;
|
|
69
|
-
permRecord?: Accessor<Record<string, boolean
|
|
70
|
-
}): AppStructure<TModule
|
|
98
|
+
permRecord?: Accessor<Record<string, boolean> | undefined>;
|
|
99
|
+
}): AppStructure<TModule> & {
|
|
100
|
+
perms: InferPerms<TItems>;
|
|
101
|
+
};
|
|
102
|
+
export {};
|
|
71
103
|
//# sourceMappingURL=createAppStructure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAppStructure.d.ts","sourceRoot":"","sources":["..\\..\\src\\helpers\\createAppStructure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
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;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY,CAAC,OAAO;IACnC,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IACnC,YAAY,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACnC,WAAW,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACjC,eAAe,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IACzC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1C,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;IAClC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC7C;AAID,KAAK,OAAO,CAAC,KAAK,IAAI,KAAK,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC,SAAS,MAAM,CAAA;CAAE,GAChE,KAAK,SAAS;IAAE,QAAQ,EAAE,GAAG,CAAA;CAAE,GAC7B,CAAC,GACD,KAAK,SAAS;IAAE,KAAK,EAAE,GAAG,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,GAAG,CAAA;CAAE,GAC9C,CAAC,GACD,KAAK,GACT,KAAK,CAAC;AAEV,KAAK,cAAc,CAAC,KAAK,IAAI,CAAC,KAAK,SAAS;IAC1C,KAAK,EAAE,CAAC,MAAM,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC;CACnC,GACG;KAAG,CAAC,IAAI,CAAC,GAAG,OAAO;CAAE,GACrB,OAAO,CAAC,GACV,CAAC,KAAK,SAAS;IAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAA;CAAE,GACpC;KACG,CAAC,IAAI,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS;QAClD,KAAK,EAAE,CAAC,MAAM,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC;KACnC,GACG;SAAG,CAAC,IAAI,CAAC,GAAG,OAAO;KAAE,GACrB,KAAK;CACV,GACD,OAAO,CAAC,CAAC;AAEf,KAAK,UAAU,CAAC,MAAM,SAAS,GAAG,EAAE,IAAI;KACrC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,SAAS;QACtD,QAAQ,EAAE,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;KACjC,GACG,UAAU,CAAC,CAAC,CAAC,GACb,cAAc,CAAC,IAAI,CAAC;CACzB,CAAC;AAiSF,wBAAgB,kBAAkB,CAChC,OAAO,EACP,KAAK,CAAC,MAAM,SAAS,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAChD,IAAI,EAAE;IACN,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;IAChD,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;CAC5D,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;CAAE,CA6DxD"}
|
|
@@ -140,6 +140,50 @@ function collectFlatPerms(items) {
|
|
|
140
140
|
}
|
|
141
141
|
return results;
|
|
142
142
|
}
|
|
143
|
+
function buildPermsObject(items, basePath, permRecord) {
|
|
144
|
+
const obj = {};
|
|
145
|
+
for (const item of items) {
|
|
146
|
+
const path = basePath + "/" + item.code;
|
|
147
|
+
if (isGroupItem(item)) {
|
|
148
|
+
const child = buildPermsObject(item.children, path, permRecord);
|
|
149
|
+
if (Object.keys(child).length > 0) {
|
|
150
|
+
obj[item.code] = child;
|
|
151
|
+
}
|
|
152
|
+
} else if (item.perms !== void 0 || item.subPerms !== void 0) {
|
|
153
|
+
const leaf = {};
|
|
154
|
+
if (item.perms !== void 0) {
|
|
155
|
+
for (const perm of item.perms) {
|
|
156
|
+
const permPath = path + "/" + perm;
|
|
157
|
+
Object.defineProperty(leaf, perm, {
|
|
158
|
+
get() {
|
|
159
|
+
var _a;
|
|
160
|
+
return ((_a = permRecord == null ? void 0 : permRecord()) == null ? void 0 : _a[permPath]) ?? false;
|
|
161
|
+
},
|
|
162
|
+
enumerable: true
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (item.subPerms !== void 0) {
|
|
167
|
+
for (const sub of item.subPerms) {
|
|
168
|
+
const subObj = {};
|
|
169
|
+
for (const p of sub.perms) {
|
|
170
|
+
const subPermPath = path + "/" + sub.code + "/" + p;
|
|
171
|
+
Object.defineProperty(subObj, p, {
|
|
172
|
+
get() {
|
|
173
|
+
var _a;
|
|
174
|
+
return ((_a = permRecord == null ? void 0 : permRecord()) == null ? void 0 : _a[subPermPath]) ?? false;
|
|
175
|
+
},
|
|
176
|
+
enumerable: true
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
leaf[sub.code] = subObj;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
obj[item.code] = leaf;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return obj;
|
|
186
|
+
}
|
|
143
187
|
function findItemChainByCodes(items, codes) {
|
|
144
188
|
const result = [];
|
|
145
189
|
let currentItems = items;
|
|
@@ -196,6 +240,7 @@ function createAppStructure(opts) {
|
|
|
196
240
|
});
|
|
197
241
|
return { usableRoutes, usableMenus, usableFlatMenus, usablePerms };
|
|
198
242
|
});
|
|
243
|
+
const permsObj = buildPermsObject(opts.items, "", opts.permRecord);
|
|
199
244
|
return {
|
|
200
245
|
items: opts.items,
|
|
201
246
|
usableRoutes: memos.usableRoutes,
|
|
@@ -203,6 +248,7 @@ function createAppStructure(opts) {
|
|
|
203
248
|
usableFlatMenus: memos.usableFlatMenus,
|
|
204
249
|
usablePerms: memos.usablePerms,
|
|
205
250
|
flatPerms,
|
|
251
|
+
perms: permsObj,
|
|
206
252
|
getTitleChainByHref(href) {
|
|
207
253
|
const codes = href.split("/").filter(Boolean);
|
|
208
254
|
return findItemChainByCodes(opts.items, codes).map((item) => item.title);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/helpers/createAppStructure.ts"],
|
|
4
|
-
"mappings": "
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/docs/hooks.md
CHANGED
|
@@ -288,6 +288,7 @@ interface AppStructure<TModule> {
|
|
|
288
288
|
usablePerms: Accessor<AppPerm<TModule>[]>; // reactive, filtered permission tree
|
|
289
289
|
flatPerms: AppFlatPerm<TModule>[]; // static, all perm entries (not reactive)
|
|
290
290
|
getTitleChainByHref(href: string): string[];
|
|
291
|
+
perms: InferPerms<TItems>; // typed permission accessor (getter-based reactive booleans)
|
|
291
292
|
}
|
|
292
293
|
|
|
293
294
|
interface AppRoute {
|
|
@@ -378,3 +379,45 @@ import { useLocation } from "@solidjs/router";
|
|
|
378
379
|
const location = useLocation();
|
|
379
380
|
const breadcrumb = () => appStructure.getTitleChainByHref(location.pathname);
|
|
380
381
|
```
|
|
382
|
+
|
|
383
|
+
#### perms
|
|
384
|
+
|
|
385
|
+
Typed permission accessor providing dot-notation access with TypeScript autocompletion and reactive boolean values. Built from the `permRecord` signal using `Object.defineProperty` getters.
|
|
386
|
+
|
|
387
|
+
**Important:** For type inference to work, pass items inline to `createAppStructure`. Declaring items as a separate variable with explicit `AppStructureItem[]` type annotation widens literal types, losing autocompletion.
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
const appStructure = createAppStructure({
|
|
391
|
+
items: [
|
|
392
|
+
{
|
|
393
|
+
code: "home",
|
|
394
|
+
title: "Home",
|
|
395
|
+
children: [
|
|
396
|
+
{
|
|
397
|
+
code: "user",
|
|
398
|
+
title: "User",
|
|
399
|
+
perms: ["use", "edit"],
|
|
400
|
+
subPerms: [
|
|
401
|
+
{ code: "auth", title: "Auth", perms: ["use"] },
|
|
402
|
+
],
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
},
|
|
406
|
+
],
|
|
407
|
+
permRecord: () => userPermissions(),
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
// Typed access with autocompletion:
|
|
411
|
+
appStructure.perms.home.user.use // boolean (reactive)
|
|
412
|
+
appStructure.perms.home.user.edit // boolean (reactive)
|
|
413
|
+
appStructure.perms.home.user.auth.use // boolean (reactive)
|
|
414
|
+
|
|
415
|
+
// Use in components:
|
|
416
|
+
<Show when={appStructure.perms.home.user.use}>
|
|
417
|
+
<UserPage />
|
|
418
|
+
</Show>
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
- Leaf items without `perms`/`subPerms` are excluded from the tree
|
|
422
|
+
- Groups with no permission-bearing descendants are excluded
|
|
423
|
+
- Returns `false` when `permRecord` is not provided or key is missing
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/solid",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.48",
|
|
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-
|
|
53
|
-
"@simplysm/core-
|
|
52
|
+
"@simplysm/core-common": "13.0.48",
|
|
53
|
+
"@simplysm/core-browser": "13.0.48"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@solidjs/testing-library": "^0.8.10"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Accessor, createMemo, createRoot } from "solid-js";
|
|
2
1
|
import type { Component } from "solid-js";
|
|
2
|
+
import { type Accessor, createMemo, createRoot } from "solid-js";
|
|
3
3
|
import type { IconProps } from "@tabler/icons-solidjs";
|
|
4
4
|
|
|
5
5
|
// ── 입력 타입 ──
|
|
@@ -80,6 +80,39 @@ export interface AppStructure<TModule> {
|
|
|
80
80
|
getTitleChainByHref(href: string): string[];
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
// ── Perms 타입 추론 ──
|
|
84
|
+
|
|
85
|
+
type PermKey<TItem> = TItem extends { code: infer C extends string }
|
|
86
|
+
? TItem extends { children: any }
|
|
87
|
+
? C
|
|
88
|
+
: TItem extends { perms: any } | { subPerms: any }
|
|
89
|
+
? C
|
|
90
|
+
: never
|
|
91
|
+
: never;
|
|
92
|
+
|
|
93
|
+
type InferLeafPerms<TItem> = (TItem extends {
|
|
94
|
+
perms: (infer P extends string)[];
|
|
95
|
+
}
|
|
96
|
+
? { [K in P]: boolean }
|
|
97
|
+
: unknown) &
|
|
98
|
+
(TItem extends { subPerms: (infer S)[] }
|
|
99
|
+
? {
|
|
100
|
+
[K in S & { code: string } as K["code"]]: K extends {
|
|
101
|
+
perms: (infer P extends string)[];
|
|
102
|
+
}
|
|
103
|
+
? { [J in P]: boolean }
|
|
104
|
+
: never;
|
|
105
|
+
}
|
|
106
|
+
: unknown);
|
|
107
|
+
|
|
108
|
+
type InferPerms<TItems extends any[]> = {
|
|
109
|
+
[Item in TItems[number] as PermKey<Item>]: Item extends {
|
|
110
|
+
children: infer C extends any[];
|
|
111
|
+
}
|
|
112
|
+
? InferPerms<C>
|
|
113
|
+
: InferLeafPerms<Item>;
|
|
114
|
+
};
|
|
115
|
+
|
|
83
116
|
// ── 내부 헬퍼 ──
|
|
84
117
|
|
|
85
118
|
function isGroupItem<TModule>(
|
|
@@ -112,8 +145,8 @@ function buildUsableRoutes<TModule>(
|
|
|
112
145
|
items: AppStructureItem<TModule>[],
|
|
113
146
|
routeBasePath: string,
|
|
114
147
|
permBasePath: string,
|
|
115
|
-
usableModules
|
|
116
|
-
permRecord
|
|
148
|
+
usableModules?: TModule[],
|
|
149
|
+
permRecord?: Record<string, boolean>,
|
|
117
150
|
): AppRoute[] {
|
|
118
151
|
const result: AppRoute[] = [];
|
|
119
152
|
|
|
@@ -293,6 +326,59 @@ function collectFlatPerms<TModule>(items: AppStructureItem<TModule>[]): AppFlatP
|
|
|
293
326
|
return results;
|
|
294
327
|
}
|
|
295
328
|
|
|
329
|
+
function buildPermsObject<TModule>(
|
|
330
|
+
items: AppStructureItem<TModule>[],
|
|
331
|
+
basePath: string,
|
|
332
|
+
permRecord?: Accessor<Record<string, boolean> | undefined>,
|
|
333
|
+
): Record<string, unknown> {
|
|
334
|
+
const obj: Record<string, unknown> = {};
|
|
335
|
+
|
|
336
|
+
for (const item of items) {
|
|
337
|
+
const path = basePath + "/" + item.code;
|
|
338
|
+
|
|
339
|
+
if (isGroupItem(item)) {
|
|
340
|
+
const child = buildPermsObject(item.children, path, permRecord);
|
|
341
|
+
if (Object.keys(child).length > 0) {
|
|
342
|
+
obj[item.code] = child;
|
|
343
|
+
}
|
|
344
|
+
} else if (item.perms !== undefined || item.subPerms !== undefined) {
|
|
345
|
+
const leaf: Record<string, unknown> = {};
|
|
346
|
+
|
|
347
|
+
if (item.perms !== undefined) {
|
|
348
|
+
for (const perm of item.perms) {
|
|
349
|
+
const permPath = path + "/" + perm;
|
|
350
|
+
Object.defineProperty(leaf, perm, {
|
|
351
|
+
get() {
|
|
352
|
+
return permRecord?.()?.[permPath] ?? false;
|
|
353
|
+
},
|
|
354
|
+
enumerable: true,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (item.subPerms !== undefined) {
|
|
360
|
+
for (const sub of item.subPerms) {
|
|
361
|
+
const subObj: Record<string, unknown> = {};
|
|
362
|
+
for (const p of sub.perms) {
|
|
363
|
+
const subPermPath = path + "/" + sub.code + "/" + p;
|
|
364
|
+
Object.defineProperty(subObj, p, {
|
|
365
|
+
get() {
|
|
366
|
+
return permRecord?.()?.[subPermPath] ?? false;
|
|
367
|
+
},
|
|
368
|
+
enumerable: true,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
leaf[sub.code] = subObj;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
obj[item.code] = leaf;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return obj;
|
|
380
|
+
}
|
|
381
|
+
|
|
296
382
|
// ── Info ──
|
|
297
383
|
|
|
298
384
|
function findItemChainByCodes<TModule>(
|
|
@@ -314,11 +400,14 @@ function findItemChainByCodes<TModule>(
|
|
|
314
400
|
|
|
315
401
|
// ── 메인 함수 ──
|
|
316
402
|
|
|
317
|
-
export function createAppStructure<
|
|
318
|
-
|
|
403
|
+
export function createAppStructure<
|
|
404
|
+
TModule,
|
|
405
|
+
const TItems extends AppStructureItem<TModule>[],
|
|
406
|
+
>(opts: {
|
|
407
|
+
items: TItems;
|
|
319
408
|
usableModules?: Accessor<TModule[] | undefined>;
|
|
320
|
-
permRecord?: Accessor<Record<string, boolean
|
|
321
|
-
}): AppStructure<TModule> {
|
|
409
|
+
permRecord?: Accessor<Record<string, boolean> | undefined>;
|
|
410
|
+
}): AppStructure<TModule> & { perms: InferPerms<TItems> } {
|
|
322
411
|
const flatPerms = collectFlatPerms(opts.items);
|
|
323
412
|
|
|
324
413
|
const memos = createRoot(() => {
|
|
@@ -364,6 +453,8 @@ export function createAppStructure<TModule>(opts: {
|
|
|
364
453
|
return { usableRoutes, usableMenus, usableFlatMenus, usablePerms };
|
|
365
454
|
});
|
|
366
455
|
|
|
456
|
+
const permsObj = buildPermsObject(opts.items, "", opts.permRecord);
|
|
457
|
+
|
|
367
458
|
return {
|
|
368
459
|
items: opts.items,
|
|
369
460
|
usableRoutes: memos.usableRoutes,
|
|
@@ -371,6 +462,7 @@ export function createAppStructure<TModule>(opts: {
|
|
|
371
462
|
usableFlatMenus: memos.usableFlatMenus,
|
|
372
463
|
usablePerms: memos.usablePerms,
|
|
373
464
|
flatPerms,
|
|
465
|
+
perms: permsObj as InferPerms<TItems>,
|
|
374
466
|
getTitleChainByHref(href: string): string[] {
|
|
375
467
|
const codes = href.split("/").filter(Boolean);
|
|
376
468
|
return findItemChainByCodes(opts.items, codes).map((item) => item.title);
|