cabloy 5.1.210 → 5.1.211
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/CHANGELOG.md +7 -0
- package/package.json +2 -1
- package/repo-agent-governance/managed-assets.json +6 -6
- package/repo-agent-governance/skills/cabloy-contract-loop/SKILL.md +14 -8
- package/repo-agent-governance/skills/cabloy-contract-loop/references/verification-checklist.md +4 -1
- package/repo-agent-governance/tests/governance.test.mjs +65 -0
- package/repo-docs/ai/playbook-contract-regeneration.md +2 -0
- package/repo-docs/frontend/openapi-sdk-guide.md +23 -4
- package/repo-docs/fullstack/contract-loop-playbook.md +8 -0
- package/repo-docs/fullstack/openapi-to-sdk.md +12 -6
- package/repo-docs/reference/repo-scripts.md +3 -0
- package/scripts/bootstrapAgentGovernance.mjs +18 -0
- package/scripts/generateOpenapiIsolated.test.ts +207 -0
- package/scripts/generateOpenapiIsolated.ts +91 -0
- package/scripts/runIsolatedTest.test.ts +90 -0
- package/scripts/runIsolatedTest.ts +157 -82
- package/scripts/upgrade.test.ts +113 -0
- package/scripts/upgrade.ts +32 -0
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/packages-vona/vona-core/package.json +1 -1
- package/vona/packages-vona/vona-core/src/lib/core/testClaim.test.ts +8 -1
- package/vona/packages-vona/vona-core/src/lib/core/testClaim.ts +2 -2
- package/vona/packages-vona/vona-mock/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/openapi.config.test.ts +29 -0
- package/zova/openapi.config.ts +13 -4
- package/zova/packages-cli/cli/package.json +2 -2
- package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/project/openapi.config.ts +13 -4
- package/zova/packages-cli/cli-set-front/package.json +1 -1
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/index.ts +7 -7
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +12 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +173 -72
- package/zova/src/suite/a-training/modules/training-student/src/api/trainingStudent.ts +8 -1
- 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/schemaRefresh.ts +21 -12
- package/zova/src/suite-vendor/a-zova/modules/a-form/test/lib/schemaRefreshLifecycle.test.ts +112 -0
- package/zova/src/suite-vendor/a-zova/package.json +2 -2
|
@@ -82,6 +82,7 @@ export type ApiApiTrainingStudentdeleteForceResponseBody =
|
|
|
82
82
|
|
|
83
83
|
@Api()
|
|
84
84
|
export class ApiTrainingStudent extends BeanApiBase {
|
|
85
|
+
/** List Students */
|
|
85
86
|
select(
|
|
86
87
|
options?: {
|
|
87
88
|
query?: ApiApiTrainingStudentselectRequestQuery;
|
|
@@ -93,6 +94,7 @@ export class ApiTrainingStudent extends BeanApiBase {
|
|
|
93
94
|
);
|
|
94
95
|
}
|
|
95
96
|
|
|
97
|
+
/** Create Student */
|
|
96
98
|
create(body: ApiApiTrainingStudentcreateRequestBody, options?: IApiActionOptions) {
|
|
97
99
|
return this.$fetch.post<any, ApiApiTrainingStudentcreateResponseBody>(
|
|
98
100
|
ApiApiTrainingStudentcreatePath,
|
|
@@ -101,6 +103,7 @@ export class ApiTrainingStudent extends BeanApiBase {
|
|
|
101
103
|
);
|
|
102
104
|
}
|
|
103
105
|
|
|
106
|
+
/** View Student */
|
|
104
107
|
view(
|
|
105
108
|
options: {
|
|
106
109
|
params: ApiApiTrainingStudentviewRequestParams;
|
|
@@ -112,6 +115,7 @@ export class ApiTrainingStudent extends BeanApiBase {
|
|
|
112
115
|
);
|
|
113
116
|
}
|
|
114
117
|
|
|
118
|
+
/** Delete Student */
|
|
115
119
|
delete(
|
|
116
120
|
options: {
|
|
117
121
|
params: ApiApiTrainingStudentdeleteRequestParams;
|
|
@@ -123,6 +127,7 @@ export class ApiTrainingStudent extends BeanApiBase {
|
|
|
123
127
|
);
|
|
124
128
|
}
|
|
125
129
|
|
|
130
|
+
/** Update Student */
|
|
126
131
|
update(
|
|
127
132
|
body: ApiApiTrainingStudentupdateRequestBody,
|
|
128
133
|
options: {
|
|
@@ -136,6 +141,7 @@ export class ApiTrainingStudent extends BeanApiBase {
|
|
|
136
141
|
);
|
|
137
142
|
}
|
|
138
143
|
|
|
144
|
+
/** View Student Summary */
|
|
139
145
|
summary(
|
|
140
146
|
options: {
|
|
141
147
|
params: ApiApiTrainingStudentsummaryRequestParams;
|
|
@@ -147,7 +153,7 @@ export class ApiTrainingStudent extends BeanApiBase {
|
|
|
147
153
|
);
|
|
148
154
|
}
|
|
149
155
|
|
|
150
|
-
/** Bulk Delete */
|
|
156
|
+
/** Bulk Delete Students */
|
|
151
157
|
deleteBulk(body: ApiApiTrainingStudentdeleteBulkRequestBody, options?: IApiActionOptions) {
|
|
152
158
|
return this.$fetch.post<any, ApiApiTrainingStudentdeleteBulkResponseBody>(
|
|
153
159
|
ApiApiTrainingStudentdeleteBulkPath,
|
|
@@ -156,6 +162,7 @@ export class ApiTrainingStudent extends BeanApiBase {
|
|
|
156
162
|
);
|
|
157
163
|
}
|
|
158
164
|
|
|
165
|
+
/** Permanently Delete Student */
|
|
159
166
|
deleteForce(
|
|
160
167
|
options: {
|
|
161
168
|
params: ApiApiTrainingStudentdeleteForceRequestParams;
|
|
@@ -238,18 +238,16 @@ function opaqueBehavior(value: unknown): boolean {
|
|
|
238
238
|
);
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
+
const pageEntryBlockOptions = ['blocks', 'resource', 'id', 'formScene', 'pageTitleKey', 'draft'];
|
|
241
242
|
const blockOptions: Record<string, string[]> = {
|
|
242
|
-
'basic-pageentry:blockPageEntry':
|
|
243
|
-
|
|
244
|
-
'resource',
|
|
245
|
-
'id',
|
|
246
|
-
'formScene',
|
|
247
|
-
'pageTitleKey',
|
|
248
|
-
'draft',
|
|
249
|
-
],
|
|
243
|
+
'basic-pageentry:blockPageEntry': pageEntryBlockOptions,
|
|
244
|
+
'start-pageentry:blockPageEntry': pageEntryBlockOptions,
|
|
250
245
|
'basic-pageentry:blockForm': ['blocks'],
|
|
246
|
+
'start-pageentry:blockForm': ['blocks'],
|
|
251
247
|
'basic-form:blockFormLayout': ['formLayout'],
|
|
248
|
+
'start-form:blockFormLayout': ['formLayout'],
|
|
252
249
|
'basic-pageentry:blockToolbarRow': ['actions'],
|
|
250
|
+
'start-pageentry:blockToolbarRow': ['actions'],
|
|
253
251
|
};
|
|
254
252
|
|
|
255
253
|
function safeLayoutNode(value: unknown): boolean {
|
|
@@ -317,7 +315,7 @@ function safeBlocks(value: unknown): boolean {
|
|
|
317
315
|
);
|
|
318
316
|
}
|
|
319
317
|
|
|
320
|
-
// Only Basic's declared layout grammar owns these title strings. Rest data/options,
|
|
318
|
+
// Only Basic's and Start's declared layout grammar owns these title strings. Rest data/options,
|
|
321
319
|
// action metadata, descriptions, field names, and unknown structures stay strict.
|
|
322
320
|
function normalizeLayoutNode(value: unknown): unknown {
|
|
323
321
|
if (!isRecord(value)) return value;
|
|
@@ -334,7 +332,12 @@ function normalizeBlocks(value: unknown): unknown {
|
|
|
334
332
|
if (!isRecord(block) || !isRecord(block.options)) return block;
|
|
335
333
|
const options = { ...block.options };
|
|
336
334
|
if (Object.hasOwn(options, 'blocks')) options.blocks = normalizeBlocks(options.blocks);
|
|
337
|
-
if (
|
|
335
|
+
if (
|
|
336
|
+
['basic-form:blockFormLayout', 'start-form:blockFormLayout'].includes(
|
|
337
|
+
block.render as string,
|
|
338
|
+
) &&
|
|
339
|
+
safeLayout(options.formLayout)
|
|
340
|
+
) {
|
|
338
341
|
const layout = options.formLayout as Record<string, unknown>;
|
|
339
342
|
options.formLayout = { children: (layout.children as unknown[]).map(normalizeLayoutNode) };
|
|
340
343
|
}
|
|
@@ -425,7 +428,13 @@ export function createSchemaRefreshContract(
|
|
|
425
428
|
const form = isRecord(rest.form) ? rest.form : undefined;
|
|
426
429
|
const render = rest.render ?? form?.render;
|
|
427
430
|
const renderType = isRecord(render) ? render.type : render;
|
|
428
|
-
if (
|
|
431
|
+
if (
|
|
432
|
+
!['basic-details:formFieldDetails', 'start-details:formFieldDetails'].includes(
|
|
433
|
+
String(renderType),
|
|
434
|
+
)
|
|
435
|
+
) {
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
429
438
|
for (const name of [
|
|
430
439
|
property.key,
|
|
431
440
|
property.schemaKey,
|
|
@@ -434,7 +443,7 @@ export function createSchemaRefreshContract(
|
|
|
434
443
|
if (typeof name === 'string') detailNames.add(name);
|
|
435
444
|
}
|
|
436
445
|
}
|
|
437
|
-
// Basic Details
|
|
446
|
+
// Basic and Start Details resolve row schemas through the exact hidden `_name` auxiliary.
|
|
438
447
|
// It belongs to that nested form, not to an unrelated parent field's behavior scope.
|
|
439
448
|
const auxiliaryDetails = new Set<string>();
|
|
440
449
|
for (const property of effective) {
|
|
@@ -424,6 +424,118 @@ test(
|
|
|
424
424
|
},
|
|
425
425
|
);
|
|
426
426
|
|
|
427
|
+
test(
|
|
428
|
+
'Start edit layout locale refresh preserves recovered input while localized custom options reset',
|
|
429
|
+
{ concurrency: false },
|
|
430
|
+
async () => {
|
|
431
|
+
const nestedEffect = () => {};
|
|
432
|
+
const studentSchema = (locale: string) => {
|
|
433
|
+
const title = locale === 'en-us' ? 'Training Records' : '培训记录';
|
|
434
|
+
const result: any = schema(
|
|
435
|
+
locale,
|
|
436
|
+
{},
|
|
437
|
+
{
|
|
438
|
+
rest: {
|
|
439
|
+
blocks: [
|
|
440
|
+
{
|
|
441
|
+
render: 'start-pageentry:blockPageEntry',
|
|
442
|
+
options: {
|
|
443
|
+
blocks: [
|
|
444
|
+
{
|
|
445
|
+
render: 'start-pageentry:blockForm',
|
|
446
|
+
options: {
|
|
447
|
+
blocks: [
|
|
448
|
+
{
|
|
449
|
+
render: 'start-form:blockFormLayout',
|
|
450
|
+
options: {
|
|
451
|
+
formLayout: {
|
|
452
|
+
children: [
|
|
453
|
+
{
|
|
454
|
+
type: 'tabs',
|
|
455
|
+
children: [
|
|
456
|
+
{
|
|
457
|
+
type: 'tab',
|
|
458
|
+
title,
|
|
459
|
+
children: [{ type: 'field', name: 'name' }],
|
|
460
|
+
},
|
|
461
|
+
],
|
|
462
|
+
},
|
|
463
|
+
],
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
},
|
|
467
|
+
],
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
render: 'start-pageentry:blockToolbarRow',
|
|
472
|
+
options: {
|
|
473
|
+
actions: [
|
|
474
|
+
{
|
|
475
|
+
render: 'start-form:actionSubmit',
|
|
476
|
+
options: { permission: { actionInherit: 'update' } },
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
],
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
],
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
);
|
|
488
|
+
result.properties.level = {
|
|
489
|
+
type: 'number',
|
|
490
|
+
rest: {
|
|
491
|
+
form: {
|
|
492
|
+
render: 'training-student:formFieldLevel',
|
|
493
|
+
options: { items: [{ value: 1, title }] },
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
};
|
|
497
|
+
result.properties.trainingRecords = {
|
|
498
|
+
type: 'array',
|
|
499
|
+
rest: { form: { render: 'start-details:formFieldDetails' } },
|
|
500
|
+
items: {
|
|
501
|
+
type: 'object',
|
|
502
|
+
properties: {
|
|
503
|
+
subject: { type: 'string', rest: { onEffect: nestedEffect } },
|
|
504
|
+
},
|
|
505
|
+
},
|
|
506
|
+
};
|
|
507
|
+
return result;
|
|
508
|
+
};
|
|
509
|
+
await withRuntime(
|
|
510
|
+
{ data: { name: 'baseline', level: 1 }, schema: studentSchema('en-us') },
|
|
511
|
+
async runtime => {
|
|
512
|
+
const name = await initializedField(runtime, inputBindingProps());
|
|
513
|
+
const level = await initializedField(runtime, {
|
|
514
|
+
name: 'level',
|
|
515
|
+
slotDefault: () => 'custom level options',
|
|
516
|
+
});
|
|
517
|
+
runtime.form.reset(
|
|
518
|
+
{ name: 'recovered unsaved name', level: 2 },
|
|
519
|
+
{ keepDefaultValues: true },
|
|
520
|
+
);
|
|
521
|
+
// Establish the post-recovery epoch before switching locales, like mounted fields do.
|
|
522
|
+
name.refresh();
|
|
523
|
+
level.refresh();
|
|
524
|
+
for (const locale of ['zh-cn', 'en-us']) {
|
|
525
|
+
runtime.form.form.setFieldValue('level', 2, { dontValidate: true });
|
|
526
|
+
runtime.events.length = 0;
|
|
527
|
+
runtime.select(locale, studentSchema(locale));
|
|
528
|
+
name.refresh();
|
|
529
|
+
level.refresh();
|
|
530
|
+
assert.equal(runtime.form.form.getFieldValue('name'), 'recovered unsaved name');
|
|
531
|
+
assert.equal(runtime.form.form.getFieldValue('level'), 1);
|
|
532
|
+
assert.deepEqual(runtime.changed, []);
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
);
|
|
536
|
+
},
|
|
537
|
+
);
|
|
538
|
+
|
|
427
539
|
test(
|
|
428
540
|
'locale replay preserves exact raw empty and falsy values',
|
|
429
541
|
{ concurrency: false },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-suite-a-zova",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.169",
|
|
4
4
|
"gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
|
|
5
5
|
"description": "zova",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"zova-module-a-behaviors": "^5.1.22",
|
|
16
16
|
"zova-module-a-command": "^5.1.35",
|
|
17
17
|
"zova-module-a-fetch": "^5.1.25",
|
|
18
|
-
"zova-module-a-form": "^5.1.
|
|
18
|
+
"zova-module-a-form": "^5.1.54",
|
|
19
19
|
"zova-module-a-icon": "^5.1.27",
|
|
20
20
|
"zova-module-a-interceptor": "^5.1.31",
|
|
21
21
|
"zova-module-a-logger": "^5.1.28",
|