cabloy 5.1.179 → 5.1.181
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 -1
- package/CHANGELOG.md +25 -0
- package/package.json +1 -1
- package/repo-docs/.vitepress/config.mjs +1 -0
- package/repo-docs/backend/controller-aop-guide.md +1 -1
- package/repo-docs/backend/demonstration-mode-guide.md +130 -0
- package/repo-docs/frontend/page-meta-guide.md +91 -13
- package/repo-docs/frontend/router-view-hosts-guide.md +37 -0
- package/repo-docs/fullstack/framework-performance.md +3 -3
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/controller/{{resourceName}}.ts_ +7 -7
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/test/{{resourceName}}.test.ts_ +93 -39
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/snippets/3-en-us.ts +1 -1
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/snippets/4-zh-cn.ts +1 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +1965 -2204
- package/vona/pnpm-workspace.yaml +1 -1
- package/vona/src/suite/a-demo/modules/demo-demonstration/package.json +55 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/.metadata/index.ts +68 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/.metadata/this.ts +2 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/bean/guard.demonstration.ts +68 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/config/errors.ts +6 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/config/locale/en-us.ts +3 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/config/locale/zh-cn.ts +3 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/index.ts +3 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/src/types/index.ts +8 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/test/guardDemonstration.test.ts +121 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/tsconfig.build.json +11 -0
- package/vona/src/suite/a-demo/modules/demo-demonstration/tsconfig.json +7 -0
- package/vona/src/suite/a-demo/package.json +2 -1
- package/vona/src/suite/a-demo/tsconfig.json +3 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +9 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +9 -0
- package/vona/src/suite/a-training/modules/training-student/src/controller/student.ts +19 -17
- package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +47 -27
- package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/bean.rbacScope.ts +13 -7
- package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/test/rbacScopeCurrent.test.ts +28 -0
- package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/packages-utils/zova-jsx/package.json +2 -2
- package/zova/packages-zova/zova/package.json +3 -3
- package/zova/packages-zova/zova-core/package.json +1 -1
- package/zova/packages-zova/zova-core/src/bean/type.ts +1 -0
- package/zova/packages-zova/zova-core/src/composables/useController.ts +1 -1
- package/zova/pnpm-lock.yaml +7 -7
- package/zova/src/suite/a-home/modules/home-indexadmin/src/page/dashboard/controller.tsx +26 -7
- package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/lib/const.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkey.ts +39 -2
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/index.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/pageHost.ts +9 -0
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +2 -0
- package/zova/src/suite-vendor/a-zova/modules/a-router/test/lib/pageHost.test.ts +53 -0
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +3 -3
- /package/vona/patches/{zova-core@5.1.91.patch → zova-core@5.1.92.patch} +0 -0
|
@@ -1,12 +1,74 @@
|
|
|
1
1
|
import type { Dto<%=argv.resourceNameCapitalize%>Create, Dto<%=argv.resourceNameCapitalize%>SelectRes, Dto<%=argv.resourceNameCapitalize%>Update, Entity<%=argv.resourceNameCapitalize%> } from 'vona-module-<%=argv.moduleInfo.relativeName%>';
|
|
2
|
+
|
|
2
3
|
import assert from 'node:assert';
|
|
3
4
|
import { describe, it } from 'node:test';
|
|
5
|
+
import { appMetadata } from 'vona';
|
|
4
6
|
import { app } from 'vona-mock';
|
|
7
|
+
import { SymbolOpenApiOptions } from 'vona-module-a-openapiutils';
|
|
8
|
+
|
|
9
|
+
describe('<%=argv.resourceName%>.test.ts', { concurrency: false }, () => {
|
|
10
|
+
it('action:<%=argv.resourceName%>:openapiMetadata', async () => {
|
|
11
|
+
await app.bean.executor.mockCtx(async () => {
|
|
12
|
+
const controllerBeanFullName = '<%=argv.moduleInfo.relativeName%>.controller.<%=argv.resourceName%>';
|
|
13
|
+
const controller = app.bean.onion.controller
|
|
14
|
+
.getOnionsEnabledCached()
|
|
15
|
+
.find(item => item.beanOptions.beanFullName === controllerBeanFullName)
|
|
16
|
+
?.beanOptions.beanClass;
|
|
17
|
+
if (!controller) throw new Error(`${controllerBeanFullName} not found`);
|
|
18
|
+
|
|
19
|
+
const controllerMetadata = appMetadata.getMetadata<any>(
|
|
20
|
+
SymbolOpenApiOptions,
|
|
21
|
+
controller,
|
|
22
|
+
);
|
|
23
|
+
assert.equal(
|
|
24
|
+
controllerMetadata?.summary?.toString(),
|
|
25
|
+
'<%=argv.moduleInfo.relativeName%>::<%=argv.resourceNameCapitalize%>Controller',
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const expectedSummaries = {
|
|
29
|
+
create: ['post', '<%=argv.moduleActionPathRaw%>', 'Create <%=argv.resourceNameCapitalize%>'],
|
|
30
|
+
select: ['get', '<%=argv.moduleActionPathRaw%>', 'Query <%=argv.resourceNameCapitalize%> List'],
|
|
31
|
+
view: ['get', '<%=argv.moduleActionPathRaw%>/{id}', 'View <%=argv.resourceNameCapitalize%>'],
|
|
32
|
+
update: ['patch', '<%=argv.moduleActionPathRaw%>/{id}', 'Update <%=argv.resourceNameCapitalize%>'],
|
|
33
|
+
delete: ['delete', '<%=argv.moduleActionPathRaw%>/{id}', 'Delete <%=argv.resourceNameCapitalize%>'],
|
|
34
|
+
deleteBulk: ['post', '<%=argv.moduleActionPathRaw%>/bulk/delete', 'Bulk Delete <%=argv.resourceNameCapitalize%>'],
|
|
35
|
+
} as const;
|
|
36
|
+
for (const [action, [method, path, summary]] of Object.entries(expectedSummaries)) {
|
|
37
|
+
const apiJson = await app.bean.openapi.generateJsonOfControllerAction(
|
|
38
|
+
controller,
|
|
39
|
+
action,
|
|
40
|
+
'V31',
|
|
41
|
+
);
|
|
42
|
+
const operation = (apiJson.paths as any)?.[path]?.[method];
|
|
43
|
+
assert.ok(operation, `${action} operation is missing`);
|
|
44
|
+
assert.equal(operation.summary?.toJSON(), summary);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('action:<%=argv.resourceName%>:rbacCatalog', async () => {
|
|
50
|
+
await app.bean.executor.mockCtx(async () => {
|
|
51
|
+
const controllerBeanFullName = '<%=argv.moduleInfo.relativeName%>.controller.<%=argv.resourceName%>';
|
|
52
|
+
const catalog = app.bean.rbacCatalog.getCatalog();
|
|
53
|
+
const expectedInherits = {
|
|
54
|
+
create: undefined,
|
|
55
|
+
select: undefined,
|
|
56
|
+
view: undefined,
|
|
57
|
+
update: undefined,
|
|
58
|
+
delete: undefined,
|
|
59
|
+
deleteBulk: `${controllerBeanFullName}#delete`,
|
|
60
|
+
} as const;
|
|
61
|
+
for (const [action, actionInheritKey] of Object.entries(expectedInherits)) {
|
|
62
|
+
const descriptor = catalog.get(`${controllerBeanFullName}#${action}`);
|
|
63
|
+
assert.ok(descriptor, `${action} RBAC action is missing`);
|
|
64
|
+
assert.equal(descriptor.actionInheritKey, actionInheritKey);
|
|
65
|
+
assert.equal(descriptor.options.dataScope, undefined);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
5
69
|
|
|
6
|
-
describe('<%=argv.resourceName%>.test.ts', () => {
|
|
7
70
|
it('action:<%=argv.resourceName%>', async () => {
|
|
8
71
|
await app.bean.executor.mockCtx(async () => {
|
|
9
|
-
// data
|
|
10
72
|
const data: Dto<%=argv.resourceNameCapitalize%>Create = {
|
|
11
73
|
name: '__Tom__',
|
|
12
74
|
description: 'This is a test',
|
|
@@ -15,48 +77,40 @@ describe('<%=argv.resourceName%>.test.ts', () => {
|
|
|
15
77
|
name: '__TomNew__',
|
|
16
78
|
description: 'This is a test',
|
|
17
79
|
};
|
|
18
|
-
|
|
80
|
+
let <%=argv.resourceName%>Id: Entity<%=argv.resourceNameCapitalize%>['id'] | undefined;
|
|
81
|
+
// sign in as an unrestricted test identity
|
|
19
82
|
await app.bean.passport.signinMock();
|
|
20
83
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
84
|
+
// create
|
|
85
|
+
<%=argv.resourceName%>Id = await app.bean.executor.performAction('post', '<%=argv.moduleActionPathRaw%>', { body: data });
|
|
86
|
+
assert.equal(!!<%=argv.resourceName%>Id, true);
|
|
87
|
+
// findMany
|
|
88
|
+
const selectRes: Dto<%=argv.resourceNameCapitalize%>SelectRes = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>');
|
|
89
|
+
assert.equal(selectRes.list.findIndex(item => item.name === data.name) > -1, true);
|
|
90
|
+
// update
|
|
91
|
+
const updateRes = await app.bean.executor.performAction('patch', '<%=argv.moduleActionPathRaw%>/:id', {
|
|
92
|
+
params: { id: <%=argv.resourceName%>Id },
|
|
93
|
+
body: dataUpdate,
|
|
94
|
+
});
|
|
95
|
+
assert.equal(updateRes, null);
|
|
96
|
+
// findOne
|
|
97
|
+
let <%=argv.resourceName%>: Entity<%=argv.resourceNameCapitalize%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>Id } });
|
|
98
|
+
assert.equal(<%=argv.resourceName%>.name, dataUpdate.name);
|
|
99
|
+
// delete
|
|
100
|
+
const deleteRes = await app.bean.executor.performAction('delete', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
|
|
101
|
+
assert.equal(deleteRes, null);
|
|
102
|
+
// findOne
|
|
103
|
+
<%=argv.resourceName%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
|
|
104
|
+
assert.equal(<%=argv.resourceName%>, undefined);
|
|
32
105
|
} finally {
|
|
106
|
+
if (<%=argv.resourceName%>Id) {
|
|
107
|
+
await app.scope('<%=argv.moduleInfo.relativeName%>').model.<%=argv.resourceName%>.deleteById(
|
|
108
|
+
<%=argv.resourceName%>Id,
|
|
109
|
+
{ disableDeleted: true },
|
|
110
|
+
);
|
|
111
|
+
}
|
|
33
112
|
await app.bean.passport.signout();
|
|
34
113
|
}
|
|
35
|
-
// login as system admin
|
|
36
|
-
await app.bean.passport.signinMock();
|
|
37
|
-
// create
|
|
38
|
-
const <%=argv.resourceName%>Id = await app.bean.executor.performAction('post', '<%=argv.moduleActionPathRaw%>', { body: data });
|
|
39
|
-
assert.equal(!!<%=argv.resourceName%>Id, true);
|
|
40
|
-
// findMany
|
|
41
|
-
const selectRes: Dto<%=argv.resourceNameCapitalize%>SelectRes = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>');
|
|
42
|
-
assert.equal(selectRes.list.findIndex(item => item.name === data.name) > -1, true);
|
|
43
|
-
// update
|
|
44
|
-
const updateRes = await app.bean.executor.performAction('patch', '<%=argv.moduleActionPathRaw%>/:id', {
|
|
45
|
-
params: { id: <%=argv.resourceName%>Id },
|
|
46
|
-
body: dataUpdate,
|
|
47
|
-
});
|
|
48
|
-
assert.equal(updateRes, null);
|
|
49
|
-
// findOne
|
|
50
|
-
let <%=argv.resourceName%>: Entity<%=argv.resourceNameCapitalize%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>Id } });
|
|
51
|
-
assert.equal(<%=argv.resourceName%>.name, dataUpdate.name);
|
|
52
|
-
// delete
|
|
53
|
-
const deleteRes = await app.bean.executor.performAction('delete', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
|
|
54
|
-
assert.equal(deleteRes, null);
|
|
55
|
-
// findOne
|
|
56
|
-
<%=argv.resourceName%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
|
|
57
|
-
assert.equal(<%=argv.resourceName%>, undefined);
|
|
58
|
-
// logout
|
|
59
|
-
await app.bean.passport.signout();
|
|
60
114
|
});
|
|
61
115
|
});
|
|
62
116
|
});
|
|
@@ -9,7 +9,6 @@ const __resources = {
|
|
|
9
9
|
Name: 'Name',
|
|
10
10
|
Description: 'Description',
|
|
11
11
|
Operations: 'Operations',
|
|
12
|
-
BulkDelete: 'Bulk Delete',
|
|
13
12
|
};
|
|
14
13
|
|
|
15
14
|
declare module '@cabloy/cli' {
|
|
@@ -40,6 +39,7 @@ export default metadataCustomSnippet({
|
|
|
40
39
|
[`${resource}View`]: `View ${resource}`,
|
|
41
40
|
[`${resource}Update`]: `Update ${resource}`,
|
|
42
41
|
[`${resource}Delete`]: `Delete ${resource}`,
|
|
42
|
+
[`${resource}DeleteBulk`]: `Bulk Delete ${resource}`,
|
|
43
43
|
};
|
|
44
44
|
return locale_transform({ ast, argv, resources });
|
|
45
45
|
},
|
|
@@ -7,7 +7,6 @@ const __resources = {
|
|
|
7
7
|
Name: '名称',
|
|
8
8
|
Description: '描述',
|
|
9
9
|
Operations: '操作',
|
|
10
|
-
BulkDelete: '批量删除',
|
|
11
10
|
};
|
|
12
11
|
|
|
13
12
|
export default metadataCustomSnippet({
|
|
@@ -23,6 +22,7 @@ export default metadataCustomSnippet({
|
|
|
23
22
|
[`${resource}View`]: `查看${resource}`,
|
|
24
23
|
[`${resource}Update`]: `更新${resource}`,
|
|
25
24
|
[`${resource}Delete`]: `删除${resource}`,
|
|
25
|
+
[`${resource}DeleteBulk`]: `批量删除${resource}`,
|
|
26
26
|
};
|
|
27
27
|
return locale_transform({ ast, argv, resources });
|
|
28
28
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.95",
|
|
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": [
|