cabloy 5.1.153 → 5.1.155
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/.cabloy-version +1 -1
- package/.claude/scheduled_tasks.lock +1 -0
- package/.claude/skills/cabloy-spec-generation/scripts/generate-implementation-charts.mjs +46 -11
- package/.claude/skills/cabloy-spec-generation/scripts/generate-implementation-charts.test.mjs +13 -0
- package/CHANGELOG.md +19 -0
- package/package.json +1 -1
- package/repo-docs/backend/menu-guide.md +3 -2
- package/test-results/.last-run.json +2 -4
- package/vona/env/.env +8 -0
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/package.json +1 -2
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +40 -65
- package/vona/src/suite/a-home/modules/home-base/src/.metadata/index.ts +78 -72
- package/vona/src/suite/a-home/modules/home-base/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-home/modules/home-base/src/config/locale/en-us.ts +3 -0
- package/vona/src/suite/a-home/modules/home-base/src/config/locale/zh-cn.ts +3 -0
- package/vona/src/suite/a-home/modules/home-base/src/index.ts +1 -0
- package/vona/src/suite/a-home/modules/home-base/src/service/siteCatalog.ts +17 -10
- package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +5 -0
- package/vona/src/suite/a-home/modules/home-user/src/config/config.ts +36 -5
- package/vona/src/suite/a-home/modules/home-user/src/config/roles.ts +7 -2
- package/vona/src/suite/a-home/modules/home-user/src/entity/role.ts +3 -0
- package/vona/src/suite/a-home/modules/home-user/src/types/env.ts +11 -0
- package/vona/src/suite/a-home/modules/home-user/src/types/index.ts +1 -0
- package/vona/src/suite/a-home/modules/home-user/test/config.test.ts +65 -0
- package/vona/src/suite/a-home/modules/home-user/test/role.test.ts +14 -6
- package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/.metadata/index.ts +17 -2
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/bean/event.resolveMenuVisibility.ts +19 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/beanSsrSiteBase.ts +32 -16
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/index.ts +2 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/ssrMenuEligibility.ts +107 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/ssrMenuVisibility.ts +91 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssr.ts +30 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrMenu.ts +67 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/test/ssrMenuEligibility.test.ts +135 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/test/ssrMenuVisibility.test.ts +64 -0
- package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/const/index.ts +1 -0
- package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/const/site.ts +1 -0
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/role.ts +1 -0
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/pnpm-lock.yaml +1 -1
- package/zova/src/suite/a-home/modules/home-api/mock/passport.fake.ts +6 -6
- package/zova/src/suite/a-home/modules/home-base/src/lib/index.ts +1 -0
- package/zova/src/suite/a-home/modules/home-base/src/lib/roleSiteAdmission.ts +15 -0
- package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +3 -3
- package/zova/src/suite/a-home/modules/home-layoutadmin/src/model/menu.ts +4 -3
- package/zova/src/suite/a-home/modules/home-layoutweb/src/model/menu.ts +4 -3
- package/zova/src/suite/a-home/modules/home-passport/package.json +2 -1
- package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +2 -2
- package/zova/src/suite/a-home/modules/home-passport/test/lib/roleSiteAdmission.test.ts +23 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/lib/resourceRouteMeta.ts +9 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/routes.ts +4 -10
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/test/lib/routes.test.ts +37 -0
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/test-results/cabloy-basic-ATP-BASIC-SUM-58d8a-ry-states-and-Markdown-HTML/error-context.md +0 -195
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/meta.version.ts +0 -32
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/meta.version.test.ts +0 -44
package/.cabloy-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.1.
|
|
1
|
+
5.1.155
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"sessionId":"834e10b3-c7de-4e46-8255-347f58ac99c9","pid":21283,"procStart":"Tue Sep 1 21:20:05 2026","acquiredAt":1788301241462}
|
|
@@ -66,24 +66,46 @@ function escapeXml(value) {
|
|
|
66
66
|
return String(value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function
|
|
69
|
+
function chartTextWidth(value, fontSize) {
|
|
70
|
+
return [...String(value)].reduce((width, character) => {
|
|
71
|
+
const characterWidth = /[⺀-鿿가-豈-\ud800-\udfff]/.test(character)
|
|
72
|
+
? 1
|
|
73
|
+
: /[MW@#%&]/.test(character)
|
|
74
|
+
? 0.9
|
|
75
|
+
: /[A-Z0-9]/.test(character)
|
|
76
|
+
? 0.62
|
|
77
|
+
: /[ilI.,:;!'` ]/.test(character)
|
|
78
|
+
? 0.28
|
|
79
|
+
: 0.5;
|
|
80
|
+
return width + characterWidth * fontSize;
|
|
81
|
+
}, 0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function wrapChartText(value, maxWidth, measure = value => [...String(value)].length) {
|
|
70
85
|
const words = String(value).trim().replace(/\s+/g, ' ').split(' ');
|
|
71
86
|
const lines = [];
|
|
72
87
|
let line = '';
|
|
73
88
|
for (const word of words) {
|
|
74
89
|
const characters = [...word];
|
|
75
|
-
if (
|
|
90
|
+
if (measure(word) > maxWidth) {
|
|
76
91
|
if (line) {
|
|
77
92
|
lines.push(line);
|
|
78
93
|
line = '';
|
|
79
94
|
}
|
|
80
|
-
|
|
81
|
-
|
|
95
|
+
let chunk = ''; let chunkWidth = 0;
|
|
96
|
+
for (const character of characters) {
|
|
97
|
+
const characterWidth = measure(character);
|
|
98
|
+
if (chunk && chunkWidth + characterWidth > maxWidth) {
|
|
99
|
+
lines.push(chunk);
|
|
100
|
+
chunk = ''; chunkWidth = 0;
|
|
101
|
+
}
|
|
102
|
+
chunk += character; chunkWidth += characterWidth;
|
|
82
103
|
}
|
|
104
|
+
if (chunk) lines.push(chunk);
|
|
83
105
|
continue;
|
|
84
106
|
}
|
|
85
107
|
const candidate = line ? `${line} ${word}` : word;
|
|
86
|
-
if (
|
|
108
|
+
if (measure(candidate) > maxWidth) {
|
|
87
109
|
lines.push(line);
|
|
88
110
|
line = word;
|
|
89
111
|
} else {
|
|
@@ -229,6 +251,11 @@ function statusIcon(x, y, status) {
|
|
|
229
251
|
return `<circle cx="${x}" cy="${y}" r="5" fill="${STATUS_COLORS[status]}"/>`;
|
|
230
252
|
}
|
|
231
253
|
|
|
254
|
+
function renderChartTextLines(className, x, y, lines, lineHeight) {
|
|
255
|
+
if (lines.length === 1) return `<text class="${className}" x="${x}" y="${y}">${escapeXml(lines[0])}</text>`;
|
|
256
|
+
return `<text class="${className}" x="${x}" y="${y}">${lines.map((line, lineIndex) => `<tspan x="${x}" dy="${lineIndex ? lineHeight : 0}">${escapeXml(line)}</tspan>`).join('')}</text>`;
|
|
257
|
+
}
|
|
258
|
+
|
|
232
259
|
function svgDocument(title, desc, body, height, metadata) {
|
|
233
260
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
234
261
|
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="${height}" viewBox="0 0 1600 ${height}" role="img" aria-labelledby="chart-title chart-desc">
|
|
@@ -243,25 +270,33 @@ function svgDocument(title, desc, body, height, metadata) {
|
|
|
243
270
|
|
|
244
271
|
export function renderGantt(model, suiteName) {
|
|
245
272
|
const { copy: t, tasks, reviewed, language } = model;
|
|
246
|
-
const phaseX = 72; const wbsX = 265; const workX = 405; const dependencyX =
|
|
273
|
+
const phaseX = 72; const wbsX = 265; const workX = 405; const dependencyX = 680; const statusX = 900;
|
|
247
274
|
const plotX = 980; const plotW = 520; const rowY = 270; const rowH = 34; const phaseLineH = 12;
|
|
275
|
+
const workMaxWidth = dependencyX - workX - 10;
|
|
276
|
+
const dependencyMaxWidth = statusX - dependencyX - 12;
|
|
248
277
|
let nextY = rowY;
|
|
249
278
|
const layout = tasks.map((task, index) => {
|
|
250
279
|
const phaseStart = index === 0 || tasks[index - 1].phase.number !== task.phase.number;
|
|
251
280
|
const descriptionLines = phaseStart ? wrapChartText(task.phase.title, 30) : [];
|
|
281
|
+
const workLines = wrapChartText(task.title, workMaxWidth, value => chartTextWidth(value, 10));
|
|
282
|
+
const dependencyLines = wrapChartText(task.dependency, dependencyMaxWidth, value => chartTextWidth(value, 9));
|
|
283
|
+
const contentLines = Math.max(workLines.length, dependencyLines.length);
|
|
284
|
+
const taskRowH = Math.max(rowH, contentLines * phaseLineH + 22);
|
|
252
285
|
const phaseLabelY = phaseStart ? nextY : undefined;
|
|
253
286
|
const y = phaseStart ? nextY + 23 + descriptionLines.length * phaseLineH : nextY;
|
|
254
|
-
|
|
255
|
-
|
|
287
|
+
const separatorY = y + Math.max(14, contentLines * phaseLineH + 2);
|
|
288
|
+
nextY = y + taskRowH;
|
|
289
|
+
return { task, index, y, separatorY, phaseLabelY, descriptionLines, workLines, dependencyLines };
|
|
256
290
|
});
|
|
257
|
-
const contentBottom = layout.at(-1)?.
|
|
291
|
+
const contentBottom = layout.at(-1)?.separatorY ?? rowY;
|
|
258
292
|
const footerY = Math.max(772, contentBottom + 80);
|
|
259
293
|
const height = Math.max(850, footerY + 78);
|
|
260
|
-
const rows = layout.map(({ task, index, y, phaseLabelY, descriptionLines }) => {
|
|
294
|
+
const rows = layout.map(({ task, index, y, separatorY, phaseLabelY, descriptionLines, workLines, dependencyLines }) => {
|
|
261
295
|
const barX = plotX + (index / Math.max(tasks.length, 1)) * (plotW - 90);
|
|
262
296
|
const barW = task.status === 'verified' ? 58 : 42;
|
|
263
297
|
const phaseHeader = phaseLabelY === undefined ? '' : `<text class="phase" x="${phaseX}" y="${phaseLabelY}">${escapeXml(`${t.phase} ${task.phase.number}`)}</text>${descriptionLines.map((line, lineIndex) => `<text class="small" x="${phaseX}" y="${phaseLabelY + 13 + lineIndex * phaseLineH}">${escapeXml(line)}</text>`).join('')}`;
|
|
264
|
-
|
|
298
|
+
const dependencyText = renderChartTextLines('small', dependencyX, y, dependencyLines, phaseLineH);
|
|
299
|
+
return `<g class="row" tabindex="0" aria-label="${escapeXml(`${task.id}: ${task.title}; ${statusLabel(task.status, language)}`)}"><title>${escapeXml(`${task.id}: ${task.title}; dependencies: ${task.dependency}; ${statusLabel(task.status, language)}`)}</title><line class="grid" x1="72" y1="${separatorY}" x2="1500" y2="${separatorY}"/>${phaseHeader}<text class="num" x="${wbsX}" y="${y}">${escapeXml(task.id)}</text>${renderChartTextLines('task', workX, y, workLines, phaseLineH)}${dependencyText}${statusIcon(statusX + 5, y - 4, task.status)}<text class="small" x="${statusX + 17}" y="${y}">${escapeXml(statusLabel(task.status, language))}</text><rect x="${barX.toFixed(1)}" y="${y - 15}" width="${barW}" height="18" rx="4" fill="${STATUS_COLORS[task.status]}"/></g>`;
|
|
265
300
|
}).join('\n');
|
|
266
301
|
const completed = new Set(tasks.filter(task => task.status === 'verified').map(task => task.id));
|
|
267
302
|
const dependencyIds = task => [...task.dependency.matchAll(/\bWBS-(?:[A-Za-z0-9]+-)*[A-Za-z0-9]+(?:-\*)?/g)].flatMap(match => {
|
package/.claude/skills/cabloy-spec-generation/scripts/generate-implementation-charts.test.mjs
CHANGED
|
@@ -131,6 +131,19 @@ test('renders a phase description directly beneath its phase label', async t =>
|
|
|
131
131
|
assert.doesNotMatch(gantt, /y="432">Delivery<\/text>/);
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
+
test('widens and wraps the Dependencies column without covering status', async t => {
|
|
135
|
+
const directory = await fixture({
|
|
136
|
+
'pdp-wbs.md': files['pdp-wbs.md'].replace(
|
|
137
|
+
'Dependencies: `WBS-10-01`.',
|
|
138
|
+
'Dependencies: `WBS-10-01`, `WBS-10-01`, `WBS-10-01`, `WBS-10-01`.',
|
|
139
|
+
),
|
|
140
|
+
});
|
|
141
|
+
t.after(() => removeFixture(directory));
|
|
142
|
+
const gantt = (await generateCharts(directory)).artifacts.get('implementation-gantt.svg');
|
|
143
|
+
assert.match(gantt, /<text class="small" x="680" y="246">Dependencies<\/text>/);
|
|
144
|
+
assert.match(gantt, /<text class="small" x="680" y="\d+"><tspan x="680" dy="0">[^<]+<\/tspan><tspan x="680" dy="12">[^<]+<\/tspan><\/text><circle cx="905" cy="\d+"/);
|
|
145
|
+
});
|
|
146
|
+
|
|
134
147
|
test('selects Chinese chart copy from a Chinese README', () => {
|
|
135
148
|
const model = createChartModel({
|
|
136
149
|
readme: '# 示例内部规划\n\n这是中文规划记录。\n',
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.1.155
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Add support for REST resource keys.
|
|
8
|
+
|
|
9
|
+
## 5.1.154
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- Add home user functionality.
|
|
14
|
+
- Add commerce role site support.
|
|
15
|
+
- Add role site support.
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
- Fix the menu guide.
|
|
20
|
+
- Correct Gantt chart render width.
|
|
21
|
+
|
|
3
22
|
## 5.1.153
|
|
4
23
|
|
|
5
24
|
### Features
|
package/package.json
CHANGED
|
@@ -70,8 +70,9 @@ In the current repo implementation, the out-of-the-box menu controller is public
|
|
|
70
70
|
})
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
- Omit `roles
|
|
74
|
-
-
|
|
73
|
+
- Omit `roles` to make an item visible to anonymous and authenticated callers.
|
|
74
|
+
- Use `roles: []` when an item has no static role visibility and is intended to be disclosed only through dynamic Role-menu configuration.
|
|
75
|
+
- A nonempty `roles` array is visible when the current Passport has at least one matching role name; it can also be disclosed through dynamic Role-menu configuration.
|
|
75
76
|
- `roles` is server-only declaration metadata. It is filtered out before the API response and is not part of `IMenuItem`, OpenAPI, or generated frontend clients.
|
|
76
77
|
- This controls navigation disclosure only. It never grants access to a page, controller action, API, or resource; those boundaries retain their own route and Passport/permission guards. For the fullstack pattern that pairs an Admin `presetResource` entry with independently authorized Admin APIs and separately scoped Web self-service APIs, see [Admin Resource and Web Self-Service](/fullstack/admin-resource-and-web-self-service).
|
|
77
78
|
|
package/vona/env/.env
CHANGED
|
@@ -84,6 +84,14 @@ REDIS_DEFAULT_PORT = 6379
|
|
|
84
84
|
REDIS_DEFAULT_PASSWORD =
|
|
85
85
|
REDIS_DEFAULT_DB = 0
|
|
86
86
|
|
|
87
|
+
# home user
|
|
88
|
+
|
|
89
|
+
HOME_USER_PASSWORD_DEFAULT_ADMIN = 123456
|
|
90
|
+
HOME_USER_DISABLE_BOOTSTRAP_SYSTEM_ADMIN = false
|
|
91
|
+
HOME_USER_DISABLE_USER_ADMIN = false
|
|
92
|
+
HOME_USER_BUILTIN_ROLE_REGISTERED_USER_SITE_IDS = *
|
|
93
|
+
HOME_USER_BUILTIN_ROLE_SYSTEM_ADMIN_SITE_IDS = *
|
|
94
|
+
|
|
87
95
|
# payment
|
|
88
96
|
|
|
89
97
|
PAY_MOCK_DEFAULT_CREDENTIAL = pay-mock-dev-credential
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.89",
|
|
4
4
|
"gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
|
|
5
5
|
"description": "Vona is an intuitive, elegant and powerful Node.js framework for rapidly developing enterprise applications of any size",
|
|
6
6
|
"keywords": [
|
|
@@ -1,71 +1,6 @@
|
|
|
1
1
|
// eslint-disable
|
|
2
2
|
import type { TypeSymbolKeyFieldsMore } from 'vona-module-a-orm';
|
|
3
3
|
import type { TypeEntityOptionsFields,TypeControllerOptionsActions } from 'vona-module-a-openapi';
|
|
4
|
-
/** service: begin */
|
|
5
|
-
export * from '../service/operator.ts';
|
|
6
|
-
|
|
7
|
-
import 'vona-module-a-bean';
|
|
8
|
-
declare module 'vona-module-a-bean' {
|
|
9
|
-
|
|
10
|
-
export interface IServiceRecord {
|
|
11
|
-
'commerce-siteadmin:operator': never;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
declare module 'vona-module-commerce-siteadmin' {
|
|
17
|
-
|
|
18
|
-
export interface ServiceOperator {
|
|
19
|
-
/** @internal */
|
|
20
|
-
get scope(): ScopeModuleCommerceSiteadmin;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface ServiceOperator {
|
|
24
|
-
get $beanFullName(): 'commerce-siteadmin.service.operator';
|
|
25
|
-
get $onionName(): 'commerce-siteadmin:operator';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/** service: end */
|
|
29
|
-
/** service: begin */
|
|
30
|
-
import type { ServiceOperator } from '../service/operator.ts';
|
|
31
|
-
export interface IModuleService {
|
|
32
|
-
'operator': ServiceOperator;
|
|
33
|
-
}
|
|
34
|
-
/** service: end */
|
|
35
|
-
/** service: begin */
|
|
36
|
-
|
|
37
|
-
import 'vona';
|
|
38
|
-
declare module 'vona' {
|
|
39
|
-
export interface IBeanRecordGeneral {
|
|
40
|
-
'commerce-siteadmin.service.operator': ServiceOperator;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/** service: end */
|
|
44
|
-
/** meta: begin */
|
|
45
|
-
export * from '../bean/meta.version.ts';
|
|
46
|
-
|
|
47
|
-
import 'vona-module-a-meta';
|
|
48
|
-
declare module 'vona-module-a-meta' {
|
|
49
|
-
|
|
50
|
-
export interface IMetaRecord {
|
|
51
|
-
'commerce-siteadmin:version': never;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
declare module 'vona-module-commerce-siteadmin' {
|
|
57
|
-
|
|
58
|
-
export interface MetaVersion {
|
|
59
|
-
/** @internal */
|
|
60
|
-
get scope(): ScopeModuleCommerceSiteadmin;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface MetaVersion {
|
|
64
|
-
get $beanFullName(): 'commerce-siteadmin.meta.version';
|
|
65
|
-
get $onionName(): 'commerce-siteadmin:version';
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
/** meta: end */
|
|
69
4
|
/** dto: begin */
|
|
70
5
|
export * from '../dto/operatorContext.ts';
|
|
71
6
|
import type { IDtoOptionsOperatorContext } from '../dto/operatorContext.ts';
|
|
@@ -140,6 +75,46 @@ import 'vona-module-a-openapi';
|
|
|
140
75
|
}
|
|
141
76
|
|
|
142
77
|
/** controller: end */
|
|
78
|
+
/** service: begin */
|
|
79
|
+
export * from '../service/operator.ts';
|
|
80
|
+
|
|
81
|
+
import 'vona-module-a-bean';
|
|
82
|
+
declare module 'vona-module-a-bean' {
|
|
83
|
+
|
|
84
|
+
export interface IServiceRecord {
|
|
85
|
+
'commerce-siteadmin:operator': never;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
declare module 'vona-module-commerce-siteadmin' {
|
|
91
|
+
|
|
92
|
+
export interface ServiceOperator {
|
|
93
|
+
/** @internal */
|
|
94
|
+
get scope(): ScopeModuleCommerceSiteadmin;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ServiceOperator {
|
|
98
|
+
get $beanFullName(): 'commerce-siteadmin.service.operator';
|
|
99
|
+
get $onionName(): 'commerce-siteadmin:operator';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** service: end */
|
|
103
|
+
/** service: begin */
|
|
104
|
+
import type { ServiceOperator } from '../service/operator.ts';
|
|
105
|
+
export interface IModuleService {
|
|
106
|
+
'operator': ServiceOperator;
|
|
107
|
+
}
|
|
108
|
+
/** service: end */
|
|
109
|
+
/** service: begin */
|
|
110
|
+
|
|
111
|
+
import 'vona';
|
|
112
|
+
declare module 'vona' {
|
|
113
|
+
export interface IBeanRecordGeneral {
|
|
114
|
+
'commerce-siteadmin.service.operator': ServiceOperator;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** service: end */
|
|
143
118
|
/** ssrSite: begin */
|
|
144
119
|
export * from '../bean/ssrSite.commerceAdmin.ts';
|
|
145
120
|
import type { ISsrSiteOptionsCommerceAdmin } from '../bean/ssrSite.commerceAdmin.ts';
|
|
@@ -1,76 +1,6 @@
|
|
|
1
1
|
// eslint-disable
|
|
2
2
|
import type { TypeSymbolKeyFieldsMore } from 'vona-module-a-orm';
|
|
3
3
|
import type { TypeEntityOptionsFields,TypeControllerOptionsActions } from 'vona-module-a-openapi';
|
|
4
|
-
/** service: begin */
|
|
5
|
-
export * from '../service/menu.ts';
|
|
6
|
-
export * from '../service/permission.ts';
|
|
7
|
-
export * from '../service/siteCatalog.ts';
|
|
8
|
-
|
|
9
|
-
import 'vona-module-a-bean';
|
|
10
|
-
declare module 'vona-module-a-bean' {
|
|
11
|
-
|
|
12
|
-
export interface IServiceRecord {
|
|
13
|
-
'home-base:menu': never;
|
|
14
|
-
'home-base:permission': never;
|
|
15
|
-
'home-base:siteCatalog': never;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
declare module 'vona-module-home-base' {
|
|
21
|
-
|
|
22
|
-
export interface ServiceMenu {
|
|
23
|
-
/** @internal */
|
|
24
|
-
get scope(): ScopeModuleHomeBase;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ServiceMenu {
|
|
28
|
-
get $beanFullName(): 'home-base.service.menu';
|
|
29
|
-
get $onionName(): 'home-base:menu';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface ServicePermission {
|
|
33
|
-
/** @internal */
|
|
34
|
-
get scope(): ScopeModuleHomeBase;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface ServicePermission {
|
|
38
|
-
get $beanFullName(): 'home-base.service.permission';
|
|
39
|
-
get $onionName(): 'home-base:permission';
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface ServiceSiteCatalog {
|
|
43
|
-
/** @internal */
|
|
44
|
-
get scope(): ScopeModuleHomeBase;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface ServiceSiteCatalog {
|
|
48
|
-
get $beanFullName(): 'home-base.service.siteCatalog';
|
|
49
|
-
get $onionName(): 'home-base:siteCatalog';
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/** service: end */
|
|
53
|
-
/** service: begin */
|
|
54
|
-
import type { ServiceMenu } from '../service/menu.ts';
|
|
55
|
-
import type { ServicePermission } from '../service/permission.ts';
|
|
56
|
-
import type { ServiceSiteCatalog } from '../service/siteCatalog.ts';
|
|
57
|
-
export interface IModuleService {
|
|
58
|
-
'menu': ServiceMenu;
|
|
59
|
-
'permission': ServicePermission;
|
|
60
|
-
'siteCatalog': ServiceSiteCatalog;
|
|
61
|
-
}
|
|
62
|
-
/** service: end */
|
|
63
|
-
/** service: begin */
|
|
64
|
-
|
|
65
|
-
import 'vona';
|
|
66
|
-
declare module 'vona' {
|
|
67
|
-
export interface IBeanRecordGeneral {
|
|
68
|
-
'home-base.service.menu': ServiceMenu;
|
|
69
|
-
'home-base.service.permission': ServicePermission;
|
|
70
|
-
'home-base.service.siteCatalog': ServiceSiteCatalog;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
/** service: end */
|
|
74
4
|
/** dto: begin */
|
|
75
5
|
export * from '../dto/siteCatalogSelectRes.ts';
|
|
76
6
|
export * from '../dto/siteCatalogSelectResItem.ts';
|
|
@@ -195,11 +125,84 @@ import 'vona-module-a-openapi';
|
|
|
195
125
|
}
|
|
196
126
|
|
|
197
127
|
/** controller: end */
|
|
128
|
+
/** service: begin */
|
|
129
|
+
export * from '../service/menu.ts';
|
|
130
|
+
export * from '../service/permission.ts';
|
|
131
|
+
export * from '../service/siteCatalog.ts';
|
|
132
|
+
|
|
133
|
+
import 'vona-module-a-bean';
|
|
134
|
+
declare module 'vona-module-a-bean' {
|
|
135
|
+
|
|
136
|
+
export interface IServiceRecord {
|
|
137
|
+
'home-base:menu': never;
|
|
138
|
+
'home-base:permission': never;
|
|
139
|
+
'home-base:siteCatalog': never;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
declare module 'vona-module-home-base' {
|
|
145
|
+
|
|
146
|
+
export interface ServiceMenu {
|
|
147
|
+
/** @internal */
|
|
148
|
+
get scope(): ScopeModuleHomeBase;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface ServiceMenu {
|
|
152
|
+
get $beanFullName(): 'home-base.service.menu';
|
|
153
|
+
get $onionName(): 'home-base:menu';
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface ServicePermission {
|
|
157
|
+
/** @internal */
|
|
158
|
+
get scope(): ScopeModuleHomeBase;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface ServicePermission {
|
|
162
|
+
get $beanFullName(): 'home-base.service.permission';
|
|
163
|
+
get $onionName(): 'home-base:permission';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface ServiceSiteCatalog {
|
|
167
|
+
/** @internal */
|
|
168
|
+
get scope(): ScopeModuleHomeBase;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface ServiceSiteCatalog {
|
|
172
|
+
get $beanFullName(): 'home-base.service.siteCatalog';
|
|
173
|
+
get $onionName(): 'home-base:siteCatalog';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/** service: end */
|
|
177
|
+
/** service: begin */
|
|
178
|
+
import type { ServiceMenu } from '../service/menu.ts';
|
|
179
|
+
import type { ServicePermission } from '../service/permission.ts';
|
|
180
|
+
import type { ServiceSiteCatalog } from '../service/siteCatalog.ts';
|
|
181
|
+
export interface IModuleService {
|
|
182
|
+
'menu': ServiceMenu;
|
|
183
|
+
'permission': ServicePermission;
|
|
184
|
+
'siteCatalog': ServiceSiteCatalog;
|
|
185
|
+
}
|
|
186
|
+
/** service: end */
|
|
187
|
+
/** service: begin */
|
|
188
|
+
|
|
189
|
+
import 'vona';
|
|
190
|
+
declare module 'vona' {
|
|
191
|
+
export interface IBeanRecordGeneral {
|
|
192
|
+
'home-base.service.menu': ServiceMenu;
|
|
193
|
+
'home-base.service.permission': ServicePermission;
|
|
194
|
+
'home-base.service.siteCatalog': ServiceSiteCatalog;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** service: end */
|
|
198
|
+
/** locale: begin */
|
|
199
|
+
import { locales } from './locales.ts';
|
|
200
|
+
/** locale: end */
|
|
198
201
|
/** main: begin */
|
|
199
202
|
export * from '../main.ts';
|
|
200
203
|
/** main: end */
|
|
201
204
|
/** scope: begin */
|
|
202
|
-
import { BeanScopeBase, type BeanScopeUtil } from 'vona';
|
|
205
|
+
import { BeanScopeBase, type BeanScopeUtil, type TypeModuleLocales, type TypeLocaleBase } from 'vona';
|
|
203
206
|
import { Scope } from 'vona-module-a-bean';
|
|
204
207
|
|
|
205
208
|
@Scope()
|
|
@@ -207,6 +210,7 @@ export class ScopeModuleHomeBase extends BeanScopeBase {}
|
|
|
207
210
|
|
|
208
211
|
export interface ScopeModuleHomeBase {
|
|
209
212
|
util: BeanScopeUtil;
|
|
213
|
+
locale: TypeModuleLocales<(typeof locales)[TypeLocaleBase]>;
|
|
210
214
|
service: IModuleService;
|
|
211
215
|
}
|
|
212
216
|
|
|
@@ -222,7 +226,9 @@ declare module 'vona' {
|
|
|
222
226
|
|
|
223
227
|
|
|
224
228
|
|
|
225
|
-
|
|
229
|
+
export interface IBeanScopeLocale {
|
|
230
|
+
'home-base': (typeof locales)[TypeLocaleBase];
|
|
231
|
+
}
|
|
226
232
|
|
|
227
233
|
|
|
228
234
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TypeLocaleBase } from 'vona';
|
|
2
|
+
|
|
3
|
+
import { $makeLocaleMagic } from 'vona';
|
|
4
|
+
|
|
5
|
+
import locale_en_us from '../config/locale/en-us.ts';
|
|
6
|
+
import locale_zh_cn from '../config/locale/zh-cn.ts';
|
|
7
|
+
|
|
8
|
+
export const locales = {
|
|
9
|
+
'en-us': locale_en_us,
|
|
10
|
+
'zh-cn': locale_zh_cn,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function $locale<K extends keyof (typeof locales)[TypeLocaleBase]>(
|
|
14
|
+
key: K,
|
|
15
|
+
...args: any[]
|
|
16
|
+
): any {
|
|
17
|
+
return $makeLocaleMagic(`home-base::${key}`, ...args);
|
|
18
|
+
}
|
|
@@ -2,22 +2,29 @@ import type { IDecoratorSsrSiteOptions } from 'vona-module-a-ssr';
|
|
|
2
2
|
|
|
3
3
|
import { BeanBase } from 'vona';
|
|
4
4
|
import { Service } from 'vona-module-a-bean';
|
|
5
|
+
import { roleSiteIdAll } from 'vona-module-a-openapiutils';
|
|
5
6
|
|
|
6
7
|
import type { DtoSiteCatalogSelectRes } from '../dto/siteCatalogSelectRes.ts';
|
|
7
8
|
|
|
8
9
|
@Service()
|
|
9
10
|
export class ServiceSiteCatalog extends BeanBase {
|
|
10
11
|
async select(): Promise<DtoSiteCatalogSelectRes> {
|
|
11
|
-
const list =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
const list = [
|
|
13
|
+
{
|
|
14
|
+
siteId: roleSiteIdAll,
|
|
15
|
+
title: this.scope.locale.SiteAll(),
|
|
16
|
+
},
|
|
17
|
+
...this.app
|
|
18
|
+
.scope('a-ssr')
|
|
19
|
+
.service.ssr.getSitesEnabled()
|
|
20
|
+
.map(site => {
|
|
21
|
+
const options = site.beanOptions.options as IDecoratorSsrSiteOptions;
|
|
22
|
+
return {
|
|
23
|
+
siteId: String(options.siteId),
|
|
24
|
+
title: this.app.meta.text.locale(this.ctx.locale, options.title),
|
|
25
|
+
};
|
|
26
|
+
}),
|
|
27
|
+
];
|
|
21
28
|
return {
|
|
22
29
|
list,
|
|
23
30
|
total: String(list.length),
|
|
@@ -21,6 +21,10 @@ export class MetaVersion extends BeanBase implements IMetaVersionUpdate, IMetaVe
|
|
|
21
21
|
table.string(entityRole.title, 255).comment(entityRole.$comment.title);
|
|
22
22
|
table.json(entityRole.titleLocales).comment(entityRole.$comment.titleLocales);
|
|
23
23
|
table.json(entityRole.siteIds).comment(entityRole.$comment.siteIds);
|
|
24
|
+
table
|
|
25
|
+
.boolean(entityRole.builtin)
|
|
26
|
+
.defaultTo(entityRole.$default.builtin)
|
|
27
|
+
.comment(entityRole.$comment.builtin);
|
|
24
28
|
});
|
|
25
29
|
// homeUser
|
|
26
30
|
const entityUser = this.scope.entity.user;
|
|
@@ -62,6 +66,7 @@ export class MetaVersion extends BeanBase implements IMetaVersionUpdate, IMetaVe
|
|
|
62
66
|
title: role.title,
|
|
63
67
|
titleLocales: role.titleLocales ?? {},
|
|
64
68
|
siteIds: role.siteIds,
|
|
69
|
+
builtin: role.builtin,
|
|
65
70
|
});
|
|
66
71
|
}
|
|
67
72
|
// user: admin
|