cabloy 5.1.158 → 5.1.160
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/skills/cabloy-contract-loop/SKILL.md +24 -7
- package/.claude/skills/cabloy-contract-loop/evals/evals.json +12 -0
- package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +28 -0
- package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +19 -2
- package/.claude/skills/cabloy-resource-field-update/SKILL.md +18 -0
- package/.claude/skills/cabloy-zova-source-reading/SKILL.md +14 -0
- package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +10 -0
- package/.github/workflows/docs-pages.yml +18 -2
- package/CHANGELOG.md +31 -0
- package/package.json +2 -1
- package/repo-docs/.vitepress/config.mjs +45 -4
- package/repo-docs/.vitepress/theme/components/GitHubRepositoriesNav.vue +255 -0
- package/repo-docs/.vitepress/theme/custom.css +21 -0
- package/repo-docs/.vitepress/theme/index.js +7 -1
- package/repo-docs/backend/department-management.md +98 -0
- package/repo-docs/backend/menu-authorization.md +124 -0
- package/repo-docs/backend/rbac-authorization.md +117 -0
- package/repo-docs/backend/resource-field-update.md +49 -2
- package/repo-docs/backend/role-management.md +92 -0
- package/repo-docs/backend/shared-rbac-architecture.md +339 -0
- package/repo-docs/backend/user-management.md +92 -0
- package/repo-docs/blogs/index.md +2 -0
- package/repo-docs/frontend/form-layout-guide.md +6 -6
- package/repo-docs/frontend/model-resource-owner-pattern.md +2 -0
- package/repo-docs/frontend/page-guide.md +12 -0
- package/repo-docs/frontend/page-meta-guide.md +27 -0
- package/repo-docs/frontend/permission-formscene-action-visibility-guide.md +5 -3
- package/repo-docs/frontend/ssr-architecture-overview.md +4 -0
- package/repo-docs/frontend/ssr-build-deploy-guide.md +1 -1
- package/repo-docs/frontend/table-action-visibility-permission-flow-guide.md +2 -0
- package/repo-docs/frontend/table-guide.md +75 -22
- package/repo-docs/frontend/table-resource-crud-cookbook.md +25 -4
- package/repo-docs/frontend/zova-form-source-reading-map.md +2 -2
- package/repo-docs/frontend/zova-form-under-the-hood.md +1 -1
- package/repo-docs/frontend/zova-reactivity-under-the-hood.md +65 -9
- package/repo-docs/frontend/zova-table-source-reading-map.md +54 -19
- package/repo-docs/frontend/zova-table-under-the-hood.md +70 -39
- package/repo-docs/fullstack/contract-loop-playbook.md +2 -0
- package/repo-docs/fullstack/ssr-site-and-flavor-setup.md +198 -0
- package/repo-docs/fullstack/vona-zova-integration.md +2 -0
- package/repo-e2e/docs/playwright.config.ts +37 -0
- package/repo-e2e/docs/specs/blogs-index.spec.ts +180 -0
- package/repo-e2e/docs/specs/github-repositories-nav.spec.ts +69 -0
- package/repo-e2e/docs/test-results/.last-run.json +4 -0
- package/repo-e2e/specs/cabloy-basic.spec.ts +136 -2
- package/test-results/.last-run.json +20 -2
- package/test-results/a-commerce-ATP-ADDR-01-aut-11dea-ss-through-Web-self-service/error-context.md +238 -0
- package/test-results/a-commerce-ATP-SPC-01-Coup-ef380-mantic-Admin-field-controls/error-context.md +240 -0
- package/test-results/a-commerce-ATP-SPC-02-Cate-9f120-on-and-publication-controls/error-context.md +238 -0
- package/test-results/a-commerce-ATP-SPC-02-Prod-5f92a-on-and-publication-controls/error-context.md +238 -0
- package/test-results/a-commerce-ATP-SPC-02-SKU--2e61e-ency-and-lifecycle-controls/error-context.md +238 -0
- package/test-results/a-commerce-ATP-SPC-04-Stoc-fa895--readonly-and-mutation-free/error-context.md +235 -0
- package/test-results/a-commerce-ATP-SPC-05-syst-fb406-e-without-mutation-controls/error-context.md +238 -0
- package/test-results/a-commerce-Commerce-sessio-4e963-ie-selects-raw-server-theme/error-context.md +226 -0
- package/test-results/a-commerce-Commerce-theme--062fe--without-hydration-mismatch/error-context.md +229 -0
- package/test-results/a-commerce-PayPal-browser--8672c-t-or-open-an-awaiting-order/error-context.md +238 -0
- package/test-results/a-commerce-Payment-callbac-f56c2--reconciles-after-hydration/error-context.md +238 -0
- package/test-results/a-commerce-Payment-cancell-3fc74-ified-provider-confirmation/error-context.md +238 -0
- package/test-results/a-commerce-Phase-50-60-aut-71d61--observes-operator-shipment/error-context.md +238 -0
- package/test-results/a-commerce-Phase-60-custom-407cd-ecutes-a-whole-order-refund/error-context.md +238 -0
- package/test-results/cabloy-basic-ATP-BASIC-TAB-e7253-and-pins-configured-columns/error-context.md +240 -0
- package/test-results/markdown-ATP-SPC-02-Produc-9d5c2-link-toolbar-edits-Markdown/error-context.md +211 -0
- package/test-results/markdown-ATP-SPC-02-Produc-9d6ea-t-editor-and-saves-Markdown/error-context.md +238 -0
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/entity/{{resourceName}}.tsx_ +1 -1
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/entity/{{resourceName}}.tsx_ +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 +79 -52
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +3 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +3 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productCreate.tsx +2 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productUpdate.tsx +2 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productView.tsx +2 -0
- package/vona/src/suite/a-training/modules/training-record/src/dto/recordCreate.tsx +1 -0
- package/vona/src/suite/a-training/modules/training-record/src/dto/recordSelectReq.tsx +3 -7
- package/vona/src/suite/a-training/modules/training-record/src/dto/recordUpdate.tsx +1 -0
- package/vona/src/suite/a-training/modules/training-record/src/dto/recordView.tsx +1 -0
- package/vona/src/suite/a-training/modules/training-record/src/entity/record.tsx +8 -0
- package/vona/src/suite/a-training/modules/training-record/test/record.test.ts +51 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +3 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +3 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +1 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +1 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +1 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +1 -0
- package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +10 -1
- package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +99 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
- 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/modules/a-web/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-web/src/bean/pipe.filter.ts +85 -57
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/packages-cli/cli/package.json +2 -2
- package/zova/packages-cli/cli-set-front/cli/templates/rest/render.ts +2 -0
- package/zova/packages-cli/cli-set-front/cli/templates/rest/rest.ts +13 -3
- package/zova/packages-cli/cli-set-front/package.json +1 -1
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +16 -16
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +31 -11
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controller.tsx +3 -0
- package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx +1 -1
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/table/render.tsx +68 -8
- 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/model/resource.ts +4 -0
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-form/src/lib/formLayout.ts +0 -6
- package/zova/src/suite-vendor/a-zova/modules/a-form/test/lib/formLayout.test.ts +16 -9
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +4 -0
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +13 -2
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/schema.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +50 -0
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx +60 -7
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/types/table.ts +6 -4
- package/zova/src/suite-vendor/a-zova/package.json +4 -4
|
@@ -22,6 +22,7 @@ const studentContentField = $makeSchema(
|
|
|
22
22
|
export interface IDtoOptionsStudentView extends IDecoratorDtoOptions<'_descriptionMarkdown'> {}
|
|
23
23
|
|
|
24
24
|
@Dto<IDtoOptionsStudentView>({
|
|
25
|
+
openapi: { title: $locale('ViewStudent') },
|
|
25
26
|
blocks: [
|
|
26
27
|
ZovaRender.block('basic-pageentry:blockPageEntry', {
|
|
27
28
|
blocks: [
|
|
@@ -19,11 +19,12 @@ export interface IEntityOptionsStudent extends IDecoratorEntityOptions {}
|
|
|
19
19
|
@Entity<IEntityOptionsStudent>('trainingStudent', {
|
|
20
20
|
openapi: { title: $locale('Student') },
|
|
21
21
|
fields: {
|
|
22
|
-
id: $makeMetadata(ZovaRender.order(1, 'core')),
|
|
22
|
+
id: $makeMetadata(ZovaRender.order(1, 'core'), ZovaRender.column({ width: 50, fixed: 'left' })),
|
|
23
23
|
iid: $makeMetadata(ZovaRender.visible(false)),
|
|
24
24
|
deleted: $makeMetadata(ZovaRender.visible(false)),
|
|
25
25
|
createdAt: $makeMetadata(
|
|
26
26
|
ZovaRender.order(-2, 'max'),
|
|
27
|
+
ZovaRender.column({ align: 'center', width: 180, enableSorting: true }),
|
|
27
28
|
ZovaRender.field('basic-date:formFieldDate'),
|
|
28
29
|
ZovaRender.cell('basic-date:date'),
|
|
29
30
|
),
|
|
@@ -40,6 +41,13 @@ export class EntityStudent extends EntityBase {
|
|
|
40
41
|
v.required(),
|
|
41
42
|
v.min(2),
|
|
42
43
|
ZovaRender.order(1),
|
|
44
|
+
ZovaRender.column({
|
|
45
|
+
align: 'left',
|
|
46
|
+
width: 240,
|
|
47
|
+
fixed: 'left',
|
|
48
|
+
enableSorting: true,
|
|
49
|
+
sortDescFirst: true,
|
|
50
|
+
}),
|
|
43
51
|
ZovaRender.cell('basic-table:actionView'),
|
|
44
52
|
)
|
|
45
53
|
name: string;
|
|
@@ -82,6 +90,7 @@ export class EntityStudent extends EntityBase {
|
|
|
82
90
|
v.title($locale('Level')),
|
|
83
91
|
v.required(),
|
|
84
92
|
ZovaRender.order(5),
|
|
93
|
+
ZovaRender.column({ align: 'center', width: 140, enableSorting: true }),
|
|
85
94
|
// Tutorial 3 built-in form renderer example. Keep it commented here for side-by-side comparison.
|
|
86
95
|
// ZovaRender.field('basic-select:formFieldSelect', {
|
|
87
96
|
// items: studentLevelItems,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { DtoDetailRecordResItem } from '../src/dto/detailRecordResItem.tsx';
|
|
14
14
|
import { DtoStudentSummary } from '../src/dto/studentSummary.tsx';
|
|
15
15
|
|
|
16
|
-
describe('student.test.ts', () => {
|
|
16
|
+
describe('student.test.ts', { concurrency: false }, () => {
|
|
17
17
|
it('action:student:formLayoutMetadata', async () => {
|
|
18
18
|
await app.bean.executor.mockCtx(async () => {
|
|
19
19
|
for (const DtoClass of [DtoStudentCreate, DtoStudentUpdate, DtoStudentView]) {
|
|
@@ -95,6 +95,104 @@ describe('student.test.ts', () => {
|
|
|
95
95
|
});
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
+
it('action:student:tableColumnMetadata', async () => {
|
|
99
|
+
await app.bean.executor.mockCtx(async () => {
|
|
100
|
+
const apiJson = await app.bean.openapi.generateJsonOfClass(DtoStudentSelectResItem);
|
|
101
|
+
const component = Object.values(apiJson.components!.schemas as any).find(item => {
|
|
102
|
+
return (item as any).properties?._operationsRow;
|
|
103
|
+
}) as any;
|
|
104
|
+
assert.deepEqual(
|
|
105
|
+
{
|
|
106
|
+
align: component.properties.name.rest.table.align,
|
|
107
|
+
width: component.properties.name.rest.table.width,
|
|
108
|
+
fixed: component.properties.name.rest.table.fixed,
|
|
109
|
+
enableSorting: component.properties.name.rest.table.enableSorting,
|
|
110
|
+
},
|
|
111
|
+
{ align: 'left', width: 240, fixed: 'left', enableSorting: true },
|
|
112
|
+
);
|
|
113
|
+
assert.deepEqual(
|
|
114
|
+
{
|
|
115
|
+
align: component.properties.level.rest.table.align,
|
|
116
|
+
width: component.properties.level.rest.table.width,
|
|
117
|
+
enableSorting: component.properties.level.rest.table.enableSorting,
|
|
118
|
+
},
|
|
119
|
+
{ align: 'center', width: 140, enableSorting: true },
|
|
120
|
+
);
|
|
121
|
+
assert.deepEqual(
|
|
122
|
+
{
|
|
123
|
+
align: component.properties.createdAt.rest.table.align,
|
|
124
|
+
width: component.properties.createdAt.rest.table.width,
|
|
125
|
+
enableSorting: component.properties.createdAt.rest.table.enableSorting,
|
|
126
|
+
},
|
|
127
|
+
{ align: 'center', width: 180, enableSorting: true },
|
|
128
|
+
);
|
|
129
|
+
assert.deepEqual(
|
|
130
|
+
{
|
|
131
|
+
align: component.properties._operationsRow.rest.table.align,
|
|
132
|
+
width: component.properties._operationsRow.rest.table.width,
|
|
133
|
+
fixed: component.properties._operationsRow.rest.table.fixed,
|
|
134
|
+
},
|
|
135
|
+
{ align: 'center', width: 360, fixed: 'right' },
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('action:student:serverSorting', async () => {
|
|
141
|
+
await app.bean.executor.mockCtx(async () => {
|
|
142
|
+
await app.bean.passport.signinMock();
|
|
143
|
+
const studentIds: string[] = [];
|
|
144
|
+
const names = ['__StudentSortA__', '__StudentSortZ__'];
|
|
145
|
+
try {
|
|
146
|
+
for (const [index, name] of names.entries()) {
|
|
147
|
+
const studentId = await app.bean.executor.performAction('post', '/training/student', {
|
|
148
|
+
body: {
|
|
149
|
+
name,
|
|
150
|
+
mobile: `13812345${678 + index}`,
|
|
151
|
+
level: 1,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
studentIds.push(studentId);
|
|
155
|
+
}
|
|
156
|
+
const ascending: DtoStudentSelectRes = await app.bean.executor.performAction(
|
|
157
|
+
'get',
|
|
158
|
+
'/training/student',
|
|
159
|
+
{ query: { orders: [['name', 'asc']] } },
|
|
160
|
+
);
|
|
161
|
+
const descending: DtoStudentSelectRes = await app.bean.executor.performAction(
|
|
162
|
+
'get',
|
|
163
|
+
'/training/student',
|
|
164
|
+
{ query: { orders: [['name', 'desc']] } },
|
|
165
|
+
);
|
|
166
|
+
const ascendingIndexes = names.map(name =>
|
|
167
|
+
ascending.list.findIndex(item => item.name === name),
|
|
168
|
+
);
|
|
169
|
+
const descendingIndexes = names.map(name =>
|
|
170
|
+
descending.list.findIndex(item => item.name === name),
|
|
171
|
+
);
|
|
172
|
+
assert.equal(
|
|
173
|
+
ascendingIndexes.every(index => index >= 0),
|
|
174
|
+
true,
|
|
175
|
+
);
|
|
176
|
+
assert.equal(
|
|
177
|
+
descendingIndexes.every(index => index >= 0),
|
|
178
|
+
true,
|
|
179
|
+
);
|
|
180
|
+
assert.equal(ascendingIndexes[0] < ascendingIndexes[1], true);
|
|
181
|
+
assert.equal(descendingIndexes[0] > descendingIndexes[1], true);
|
|
182
|
+
} finally {
|
|
183
|
+
for (const studentId of studentIds.reverse()) {
|
|
184
|
+
await app
|
|
185
|
+
.scope('training-student')
|
|
186
|
+
.model.studentContent.delete({ studentId }, { disableDeleted: true });
|
|
187
|
+
await app
|
|
188
|
+
.scope('training-student')
|
|
189
|
+
.model.student.deleteById(studentId, { disableDeleted: true });
|
|
190
|
+
}
|
|
191
|
+
await app.bean.passport.signout();
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
98
196
|
it('action:student:emittedDtoSchemas', async () => {
|
|
99
197
|
await app.bean.executor.mockCtx(async () => {
|
|
100
198
|
const summaryApiJson = await app.bean.openapi.generateJsonOfClass(DtoStudentSummary);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona-suite-a-cabloy",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.51",
|
|
4
4
|
"gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"vona-module-a-cabloy": "workspace:^",
|
|
11
11
|
"vona-module-a-markdown": "^5.0.3",
|
|
12
|
-
"vona-module-a-rbac": "^5.0.
|
|
12
|
+
"vona-module-a-rbac": "^5.0.5",
|
|
13
13
|
"vona-module-a-socket": "workspace:^",
|
|
14
14
|
"vona-module-a-ssr": "workspace:^",
|
|
15
15
|
"vona-module-a-ssrhmr": "workspace:^"
|
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
export type TypePipeFilterData = ITableQuery;
|
|
26
26
|
|
|
27
27
|
export type TypePipeFilterResult = TypeQueryParamsPatch;
|
|
28
|
+
type TypeQueryJoin = NonNullable<TypeQueryParamsPatch['joins']>[number];
|
|
28
29
|
|
|
29
30
|
export interface IPipeOptionsFilter
|
|
30
31
|
extends IDecoratorPipeOptions, IDecoratorPipeOptionsArgument, ValidatorOptions {}
|
|
@@ -68,10 +69,13 @@ export class PipeFilter
|
|
|
68
69
|
private async _transform(value: TypePipeFilterData, options: IPipeOptionsFilter) {
|
|
69
70
|
// 1. system: columns/where/orders/pageNo/pageSize
|
|
70
71
|
const params = this._transformSystem(value);
|
|
72
|
+
const rootOpenapi = ZodMetadata.getOpenapiMetadata(options.schema!) as
|
|
73
|
+
| ISchemaObjectExtensionField
|
|
74
|
+
| undefined;
|
|
71
75
|
// 2. fields
|
|
72
|
-
await this._transformFields(params, value, options);
|
|
76
|
+
await this._transformFields(params, value, options, rootOpenapi);
|
|
73
77
|
// 3. system: orders
|
|
74
|
-
this._transformOrders(params, options);
|
|
78
|
+
this._transformOrders(params, options, rootOpenapi);
|
|
75
79
|
// ok
|
|
76
80
|
return params;
|
|
77
81
|
}
|
|
@@ -104,32 +108,75 @@ export class PipeFilter
|
|
|
104
108
|
return params;
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
private _transformOrders(
|
|
111
|
+
private _transformOrders(
|
|
112
|
+
params: TypeQueryParamsPatch,
|
|
113
|
+
options: IPipeOptionsFilter,
|
|
114
|
+
rootOpenapi: ISchemaObjectExtensionField | undefined,
|
|
115
|
+
) {
|
|
108
116
|
if (!params.orders) return;
|
|
109
|
-
// openapi
|
|
110
|
-
const openapi: ISchemaObjectExtensionField | undefined = ZodMetadata.getOpenapiMetadata(
|
|
111
|
-
options.schema!,
|
|
112
|
-
) as ISchemaObjectExtensionField | undefined;
|
|
113
|
-
const table = openapi?.filter?.table;
|
|
114
|
-
// loop
|
|
115
117
|
for (const order of params.orders) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
tableCurrent = openapi?.filter?.table;
|
|
127
|
-
}
|
|
128
|
-
if (openapi?.filter?.originalName) {
|
|
129
|
-
fieldCurrent = openapi?.filter?.originalName;
|
|
130
|
-
}
|
|
118
|
+
if (!Array.isArray(order) || order.length !== 2) {
|
|
119
|
+
throw new Error('invalid order');
|
|
120
|
+
}
|
|
121
|
+
const [key, direction] = order;
|
|
122
|
+
if (typeof key !== 'string' || (direction !== 'asc' && direction !== 'desc')) {
|
|
123
|
+
throw new Error('invalid order');
|
|
124
|
+
}
|
|
125
|
+
const info = this._resolveField(key, options, rootOpenapi);
|
|
126
|
+
if (!info || info.openapi?.filter?.capabilities?.order === false) {
|
|
127
|
+
throw new Error(`invalid order field: ${key}`);
|
|
131
128
|
}
|
|
132
|
-
cast(order)[0] =
|
|
129
|
+
cast(order)[0] = info.orderFullName;
|
|
130
|
+
this._addJoin(params, info.joinInfo);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private _resolveField(
|
|
135
|
+
key: string,
|
|
136
|
+
options: IPipeOptionsFilter,
|
|
137
|
+
rootOpenapi: ISchemaObjectExtensionField | undefined,
|
|
138
|
+
) {
|
|
139
|
+
const fieldSchema = ZodMetadata.getFieldSchema(options.schema!, key);
|
|
140
|
+
if (!fieldSchema) {
|
|
141
|
+
if (!rootOpenapi?.filter?.table) {
|
|
142
|
+
return { orderFullName: key };
|
|
143
|
+
}
|
|
144
|
+
const keyParts = key.split('.');
|
|
145
|
+
const [table, field] = keyParts;
|
|
146
|
+
if (!table || !field || keyParts.length !== 2) return;
|
|
147
|
+
const resolved = this._resolveField(field, options, rootOpenapi);
|
|
148
|
+
if (!resolved || resolved.orderFullName !== key) return;
|
|
149
|
+
return resolved;
|
|
150
|
+
}
|
|
151
|
+
const fieldSchemaInner = ZodMetadata.unwrapChained(fieldSchema);
|
|
152
|
+
const openapi: ISchemaObjectExtensionField | undefined = ZodMetadata.getOpenapiMetadata(
|
|
153
|
+
fieldSchema,
|
|
154
|
+
) as ISchemaObjectExtensionField | undefined;
|
|
155
|
+
const originalName = openapi?.filter?.originalName ?? key;
|
|
156
|
+
const table = openapi?.filter?.table ?? rootOpenapi?.filter?.table;
|
|
157
|
+
const joinInfo = openapi?.filter?.joinOn
|
|
158
|
+
? ([
|
|
159
|
+
openapi.filter.joinType ?? 'innerJoin',
|
|
160
|
+
openapi.filter.table,
|
|
161
|
+
openapi.filter.joinOn,
|
|
162
|
+
] as TypeQueryJoin)
|
|
163
|
+
: undefined;
|
|
164
|
+
return {
|
|
165
|
+
fieldSchema,
|
|
166
|
+
fieldSchemaInner,
|
|
167
|
+
openapi,
|
|
168
|
+
originalName,
|
|
169
|
+
fullName: joinInfo ? `${openapi?.filter?.table}.${originalName}` : originalName,
|
|
170
|
+
orderFullName: table ? `${table}.${originalName}` : originalName,
|
|
171
|
+
joinInfo,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private _addJoin(params: TypeQueryParamsPatch, joinInfo: TypeQueryJoin | undefined) {
|
|
176
|
+
if (!joinInfo) return;
|
|
177
|
+
if (!params.joins) params.joins = [];
|
|
178
|
+
if (params.joins.findIndex(item => item[1] === joinInfo[1]) === -1) {
|
|
179
|
+
params.joins.push(joinInfo);
|
|
133
180
|
}
|
|
134
181
|
}
|
|
135
182
|
|
|
@@ -139,36 +186,21 @@ export class PipeFilter
|
|
|
139
186
|
params: TypeQueryParamsPatch,
|
|
140
187
|
value: any,
|
|
141
188
|
options: IPipeOptionsFilter,
|
|
189
|
+
rootOpenapi: ISchemaObjectExtensionField | undefined,
|
|
142
190
|
) {
|
|
143
191
|
if (__FieldsSystem.includes(key)) return;
|
|
144
|
-
const
|
|
145
|
-
if (!
|
|
146
|
-
const fieldSchemaInner =
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const [transformName] = openapi?.filter?.transform ?? ['a-web:base', undefined];
|
|
192
|
+
const info = this._resolveField(key, options, rootOpenapi);
|
|
193
|
+
if (!info) return;
|
|
194
|
+
const { fieldSchema, fieldSchemaInner, openapi, originalName, fullName, joinInfo } = info;
|
|
195
|
+
const [transformName, transformOptions] = openapi?.filter?.transform ?? [
|
|
196
|
+
'a-web:base',
|
|
197
|
+
undefined,
|
|
198
|
+
];
|
|
152
199
|
const fieldNullable = fieldValue === null && isNullableSchema(fieldSchema);
|
|
153
200
|
if (isNilOrEmptyString(fieldValue) && !fieldNullable) return;
|
|
154
|
-
// name
|
|
155
|
-
const originalName = openapi?.filter?.originalName ?? key;
|
|
156
|
-
let fullName: string;
|
|
157
|
-
// joins
|
|
158
|
-
let joinInfo;
|
|
159
|
-
if (openapi?.filter?.joinOn) {
|
|
160
|
-
const joinType = openapi.filter.joinType ?? 'innerJoin';
|
|
161
|
-
const joinTable = openapi.filter.table;
|
|
162
|
-
const joinOn = openapi.filter.joinOn;
|
|
163
|
-
joinInfo = [joinType, joinTable, joinOn];
|
|
164
|
-
fullName = `${joinTable}.${originalName}`;
|
|
165
|
-
} else {
|
|
166
|
-
fullName = originalName;
|
|
167
|
-
}
|
|
168
201
|
// check where
|
|
169
202
|
if (Object.prototype.hasOwnProperty.call(params.where, fullName)) return;
|
|
170
203
|
// filter transform
|
|
171
|
-
const [, transformOptions] = openapi?.filter?.transform ?? ['a-web:base', undefined];
|
|
172
204
|
const transformOptions2 = this.bean.onion.filterTransform.getOnionOptionsDynamic(
|
|
173
205
|
transformName as keyof IFilterTransformRecord,
|
|
174
206
|
transformOptions,
|
|
@@ -182,7 +214,7 @@ export class PipeFilter
|
|
|
182
214
|
if (!beanInstance.where) {
|
|
183
215
|
throw new Error(`filterTransform.where not found: ${beanFullName}`);
|
|
184
216
|
}
|
|
185
|
-
const
|
|
217
|
+
const transformInfo = {
|
|
186
218
|
params,
|
|
187
219
|
query: value,
|
|
188
220
|
options,
|
|
@@ -194,17 +226,12 @@ export class PipeFilter
|
|
|
194
226
|
schema: fieldSchema,
|
|
195
227
|
openapi,
|
|
196
228
|
};
|
|
197
|
-
const resTransform = await beanInstance.where(
|
|
229
|
+
const resTransform = await beanInstance.where(transformInfo, transformOptions2);
|
|
198
230
|
if (resTransform !== undefined) {
|
|
199
231
|
// where
|
|
200
232
|
params.where[fullName] = resTransform;
|
|
201
233
|
// join
|
|
202
|
-
|
|
203
|
-
if (!params.joins) params.joins = [];
|
|
204
|
-
if (params.joins.findIndex(item => item[1] === joinInfo.joinTable) === -1) {
|
|
205
|
-
params.joins.push(joinInfo);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
234
|
+
this._addJoin(params, joinInfo);
|
|
208
235
|
}
|
|
209
236
|
}
|
|
210
237
|
|
|
@@ -212,10 +239,11 @@ export class PipeFilter
|
|
|
212
239
|
params: TypeQueryParamsPatch,
|
|
213
240
|
value: any,
|
|
214
241
|
options: IPipeOptionsFilter,
|
|
242
|
+
rootOpenapi: ISchemaObjectExtensionField | undefined,
|
|
215
243
|
) {
|
|
216
244
|
// loop
|
|
217
245
|
for (const key in value) {
|
|
218
|
-
await this._transformField(key, value[key], params, value, options);
|
|
246
|
+
await this._transformField(key, value[key], params, value, options, rootOpenapi);
|
|
219
247
|
}
|
|
220
248
|
}
|
|
221
249
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.106",
|
|
4
4
|
"gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
|
|
5
5
|
"description": "zova cli",
|
|
6
6
|
"keywords": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@cabloy/process-helper": "^3.1.8",
|
|
45
45
|
"fs-extra": "^11.3.5",
|
|
46
46
|
"semver": "^7.6.2",
|
|
47
|
-
"zova-cli-set-front": "^1.2.
|
|
47
|
+
"zova-cli-set-front": "^1.2.104"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"clean-package": "^2.2.0",
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
schemaRenderTableActionRowJsx,
|
|
18
18
|
} from './component.ts';
|
|
19
19
|
import {
|
|
20
|
+
schemaRenderColumn,
|
|
20
21
|
schemaRenderDisableNotifyChanged,
|
|
21
22
|
schemaRenderFieldSource,
|
|
22
23
|
schemaRenderLayout,
|
|
@@ -35,6 +36,7 @@ export const ZovaRender = {
|
|
|
35
36
|
disableNotifyChanged: schemaRenderDisableNotifyChanged,
|
|
36
37
|
onEffect: schemaRenderOnEffect,
|
|
37
38
|
fieldSource: schemaRenderFieldSource,
|
|
39
|
+
column: schemaRenderColumn,
|
|
38
40
|
// component
|
|
39
41
|
field: schemaRenderField,
|
|
40
42
|
fieldJsx: schemaRenderFieldJsx,
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type z from 'zod';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import type {
|
|
4
|
+
IResourceFormFieldLayoutOptions,
|
|
5
|
+
ITableColumnOptions,
|
|
6
|
+
TypeFormFieldOnEffect,
|
|
7
|
+
TypeFormSchemaScene,
|
|
8
|
+
TypeSchemaScene,
|
|
9
|
+
} from 'zova-module-a-openapi';
|
|
6
10
|
import type { TypeSchemaOrderLevel } from 'zova-module-a-openapi';
|
|
7
11
|
|
|
8
12
|
import { _generalSchemaRest, _order } from './inner.ts';
|
|
@@ -78,3 +82,9 @@ export function schemaRenderOrder<T extends z.ZodType>(
|
|
|
78
82
|
return _generalSchemaRest(schema, options, scene);
|
|
79
83
|
};
|
|
80
84
|
}
|
|
85
|
+
|
|
86
|
+
export function schemaRenderColumn<T extends z.ZodType>(options: ITableColumnOptions) {
|
|
87
|
+
return function (schema: T): T {
|
|
88
|
+
return schema.openapi({ rest: { table: options } });
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.156",
|
|
4
4
|
"gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
|
|
5
5
|
"description": "A vue3 framework with ioc",
|
|
6
6
|
"keywords": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"zova-core": "^5.1.88",
|
|
49
|
-
"zova-suite-a-zova": "^5.1.
|
|
49
|
+
"zova-suite-a-zova": "^5.1.155"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"clean-package": "^2.2.0",
|
package/zova/pnpm-lock.yaml
CHANGED
|
@@ -449,7 +449,7 @@ importers:
|
|
|
449
449
|
specifier: ^7.6.2
|
|
450
450
|
version: 7.8.5
|
|
451
451
|
zova-cli-set-front:
|
|
452
|
-
specifier: ^1.2.
|
|
452
|
+
specifier: ^1.2.104
|
|
453
453
|
version: link:../cli-set-front
|
|
454
454
|
devDependencies:
|
|
455
455
|
clean-package:
|
|
@@ -558,7 +558,7 @@ importers:
|
|
|
558
558
|
specifier: ^1.1.17
|
|
559
559
|
version: link:../../packages-utils/zova-openapi
|
|
560
560
|
zova-vite:
|
|
561
|
-
specifier: ^1.1.
|
|
561
|
+
specifier: ^1.1.45
|
|
562
562
|
version: link:../../packages-utils/zova-vite
|
|
563
563
|
devDependencies:
|
|
564
564
|
clean-package:
|
|
@@ -761,8 +761,8 @@ importers:
|
|
|
761
761
|
specifier: ^7.28.6
|
|
762
762
|
version: 7.29.7(@babel/core@7.29.7)
|
|
763
763
|
'@cabloy/dotenv':
|
|
764
|
-
specifier: ^1.2.
|
|
765
|
-
version: 1.2.
|
|
764
|
+
specifier: ^1.2.9
|
|
765
|
+
version: 1.2.9
|
|
766
766
|
'@cabloy/extend':
|
|
767
767
|
specifier: ^3.2.8
|
|
768
768
|
version: 3.2.8
|
|
@@ -870,7 +870,7 @@ importers:
|
|
|
870
870
|
specifier: ^5.1.88
|
|
871
871
|
version: link:../zova-core
|
|
872
872
|
zova-suite-a-zova:
|
|
873
|
-
specifier: ^5.1.
|
|
873
|
+
specifier: ^5.1.155
|
|
874
874
|
version: link:../../src/suite-vendor/a-zova
|
|
875
875
|
devDependencies:
|
|
876
876
|
clean-package:
|
|
@@ -977,7 +977,7 @@ importers:
|
|
|
977
977
|
specifier: ^5.0.1
|
|
978
978
|
version: link:modules/a-rbac
|
|
979
979
|
zova-module-rest-resource:
|
|
980
|
-
specifier: ^5.1.
|
|
980
|
+
specifier: ^5.1.50
|
|
981
981
|
version: link:modules/rest-resource
|
|
982
982
|
|
|
983
983
|
src/suite-vendor/a-cabloy/modules/a-rbac:
|
|
@@ -1076,7 +1076,7 @@ importers:
|
|
|
1076
1076
|
specifier: ^5.1.25
|
|
1077
1077
|
version: link:modules/a-fetch
|
|
1078
1078
|
zova-module-a-form:
|
|
1079
|
-
specifier: ^5.1.
|
|
1079
|
+
specifier: ^5.1.51
|
|
1080
1080
|
version: link:modules/a-form
|
|
1081
1081
|
zova-module-a-icon:
|
|
1082
1082
|
specifier: ^5.1.27
|
|
@@ -1094,7 +1094,7 @@ importers:
|
|
|
1094
1094
|
specifier: ^5.1.36
|
|
1095
1095
|
version: link:modules/a-model
|
|
1096
1096
|
zova-module-a-openapi:
|
|
1097
|
-
specifier: ^5.1.
|
|
1097
|
+
specifier: ^5.1.52
|
|
1098
1098
|
version: link:modules/a-openapi
|
|
1099
1099
|
zova-module-a-router:
|
|
1100
1100
|
specifier: ^5.1.34
|
|
@@ -1118,7 +1118,7 @@ importers:
|
|
|
1118
1118
|
specifier: ^5.1.35
|
|
1119
1119
|
version: link:modules/a-style
|
|
1120
1120
|
zova-module-a-table:
|
|
1121
|
-
specifier: ^5.1.
|
|
1121
|
+
specifier: ^5.1.39
|
|
1122
1122
|
version: link:modules/a-table
|
|
1123
1123
|
zova-module-a-zod:
|
|
1124
1124
|
specifier: ^5.1.37
|
|
@@ -2311,8 +2311,8 @@ packages:
|
|
|
2311
2311
|
'@cabloy/deps@1.1.8':
|
|
2312
2312
|
resolution: {integrity: sha512-CWaVGSwPI5qLSuRF+WmB+1CwbRe9+PR+nkUmKc9/Dj7sB75qPXLTYACn23T/jIylbDbWCL82LoOa455Vgseyeg==}
|
|
2313
2313
|
|
|
2314
|
-
'@cabloy/dotenv@1.2.
|
|
2315
|
-
resolution: {integrity: sha512-
|
|
2314
|
+
'@cabloy/dotenv@1.2.9':
|
|
2315
|
+
resolution: {integrity: sha512-iR7KWj1YI2SiTjlcSMnZ/wYw/PMcgAJRvOHdWDrwehY8YOuG6uKPTez1hTCR4kfrhiBnZwM/acZvmqjflx18GA==}
|
|
2316
2316
|
|
|
2317
2317
|
'@cabloy/extend@3.2.8':
|
|
2318
2318
|
resolution: {integrity: sha512-BrXYUtlC1kFY33hNxL/hEaS7wW8TsOuu22k0VCEtzg2iw+USkb4BqONth5Uv2pJcIlDMeWx8A8aUIRF3WQ2ckQ==}
|
|
@@ -5138,8 +5138,8 @@ packages:
|
|
|
5138
5138
|
capital-case@1.0.4:
|
|
5139
5139
|
resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
|
|
5140
5140
|
|
|
5141
|
-
cascade-extend@2.2.
|
|
5142
|
-
resolution: {integrity: sha512-
|
|
5141
|
+
cascade-extend@2.2.9:
|
|
5142
|
+
resolution: {integrity: sha512-YevoTZSywFhLNnHWh9GSzHgrwAJmsDzR0sQeOZ8BG5NlwF8MyH0457ocLVyGgB/m9rTHmRXJkzzvPuDcjpTtfQ==}
|
|
5143
5143
|
|
|
5144
5144
|
ccount@1.1.0:
|
|
5145
5145
|
resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==}
|
|
@@ -8834,9 +8834,9 @@ snapshots:
|
|
|
8834
8834
|
|
|
8835
8835
|
'@cabloy/deps@1.1.8': {}
|
|
8836
8836
|
|
|
8837
|
-
'@cabloy/dotenv@1.2.
|
|
8837
|
+
'@cabloy/dotenv@1.2.9':
|
|
8838
8838
|
dependencies:
|
|
8839
|
-
cascade-extend: 2.2.
|
|
8839
|
+
cascade-extend: 2.2.9
|
|
8840
8840
|
dotenv: 16.6.1
|
|
8841
8841
|
dotenv-expand: 11.0.7
|
|
8842
8842
|
globby: 16.2.0
|
|
@@ -11389,7 +11389,7 @@ snapshots:
|
|
|
11389
11389
|
tslib: 2.8.1
|
|
11390
11390
|
upper-case-first: 2.0.2
|
|
11391
11391
|
|
|
11392
|
-
cascade-extend@2.2.
|
|
11392
|
+
cascade-extend@2.2.9:
|
|
11393
11393
|
dependencies:
|
|
11394
11394
|
'@cabloy/extend': 3.2.8
|
|
11395
11395
|
|