cabloy 5.1.149 → 5.1.150

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.
Files changed (80) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +2 -1
  3. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +1 -0
  4. package/CHANGELOG.md +22 -0
  5. package/CLAUDE.md +1 -0
  6. package/package.json +1 -1
  7. package/repo-docs/backend/dto-guide.md +7 -6
  8. package/repo-docs/backend/dto-infer-generation.md +25 -5
  9. package/repo-docs/frontend/a-model-under-the-hood.md +38 -0
  10. package/repo-docs/frontend/a-openapi-under-the-hood.md +13 -2
  11. package/repo-docs/frontend/form-layout-guide.md +26 -9
  12. package/repo-docs/frontend/model-resource-best-practices.md +2 -0
  13. package/repo-docs/frontend/model-resource-cookbook.md +7 -1
  14. package/repo-docs/frontend/use-state-data-best-practices.md +44 -0
  15. package/repo-docs/frontend/zova-form-source-reading-map.md +26 -9
  16. package/repo-docs/frontend/zova-form-under-the-hood.md +11 -0
  17. package/repo-docs/fullstack/one-to-one-companion-resource-guide.md +1 -1
  18. package/repo-e2e/specs/a-commerce.spec.ts +40 -0
  19. package/vona/packages-cli/cli/package.json +1 -1
  20. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/controller/{{resourceName}}.ts_ +2 -2
  21. package/vona/packages-cli/cli-set-api/package.json +1 -1
  22. package/vona/pnpm-lock.yaml +83 -75
  23. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +108 -108
  24. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +12 -0
  25. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/sku.ts +19 -1
  26. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/skuPresentation.test.ts +53 -4
  27. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +148 -148
  28. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAdjust.tsx +37 -3
  29. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +2 -2
  30. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +7 -6
  31. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +1 -1
  32. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +7 -6
  33. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +10 -7
  34. package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +4 -4
  35. package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +39 -67
  36. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +56 -37
  37. package/zova/packages-zova/zova/package.json +2 -2
  38. package/zova/pnpm-lock.yaml +2 -2
  39. package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +1 -0
  40. package/zova/src/suite/a-commerce/modules/commerce-trade/package.json +6 -1
  41. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/component/tableCellActionAdjustStock.ts +34 -0
  42. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +81 -6
  43. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeStockBalance.ts +32 -0
  44. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +44 -44
  45. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +356 -338
  46. package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeStockBalance.ts +17 -0
  47. package/zova/src/suite/a-commerce/modules/commerce-trade/src/bean/tableCell.actionAdjustStock.tsx +35 -0
  48. package/zova/src/suite/a-commerce/modules/commerce-trade/src/component/tableCellActionAdjustStock/controller.tsx +138 -0
  49. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +3 -0
  50. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +3 -0
  51. package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/stockBalance.ts +36 -0
  52. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +4 -4
  53. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +8 -8
  54. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +11 -11
  55. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +2 -2
  56. package/zova/src/suite/cabloy-basic/modules/basic-app/src/bean/behavior.appModal.tsx +2 -0
  57. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  58. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +2 -1
  59. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/test/model/resource.types.ts +11 -0
  60. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  61. package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
  62. package/zova/src/suite-vendor/a-zova/modules/a-form/src/lib/formLayout.ts +58 -9
  63. package/zova/src/suite-vendor/a-zova/modules/a-form/test/lib/formLayout.test.ts +157 -0
  64. package/zova/src/suite-vendor/a-zova/modules/a-model/package.json +1 -1
  65. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.persister.ts +3 -1
  66. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useQuery.ts +11 -13
  67. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useState.ts +9 -7
  68. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useStateGeneral.ts +5 -12
  69. package/zova/src/suite-vendor/a-zova/modules/a-model/src/lib/queryPersister.ts +17 -0
  70. package/zova/src/suite-vendor/a-zova/modules/a-model/src/lib/queryRefetch.ts +34 -0
  71. package/zova/src/suite-vendor/a-zova/modules/a-model/src/types/query.ts +27 -3
  72. package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/queryPersister.test.ts +115 -0
  73. package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/queryRefetch.test.ts +84 -0
  74. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  75. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts +27 -5
  76. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +2 -2
  77. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +4 -0
  78. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/schema.ts +2 -5
  79. package/zova/src/suite-vendor/a-zova/modules/a-openapi/test/lib/schema.test.ts +179 -0
  80. package/zova/src/suite-vendor/a-zova/package.json +4 -4
@@ -21,7 +21,7 @@ export function loadSchemaProperties(
21
21
  schema: SchemaObject | undefined,
22
22
  onGetSchema: (schemaName: string) => SchemaObject | undefined,
23
23
  schemaScene?: TypeSchemaScene,
24
- ): SchemaObject[] | undefined {
24
+ ): ISchemaObjectExtensionField[] | undefined {
25
25
  if (!schema) return;
26
26
  const properties = schema.properties!;
27
27
  const result: ISchemaObjectExtensionField[] = [];
@@ -32,12 +32,26 @@ export function loadSchemaProperties(
32
32
  property = onGetSchema(property.$ref)!;
33
33
  }
34
34
  if (!property) continue;
35
- const fieldSource = property.rest?.fieldSource;
35
+ const schemaKey = key;
36
+ const propertyRest = deepExtend(
37
+ {},
38
+ property.rest,
39
+ schemaScene && ['form-view', 'form-create', 'filter'].includes(schemaScene)
40
+ ? property.rest?.form
41
+ : undefined,
42
+ schemaScene ? property.rest?.[schemaScene] : undefined,
43
+ );
44
+ const fieldSource = propertyRest?.fieldSource;
36
45
  if (fieldSource) {
37
46
  const parts = fieldSource.split('.');
38
- const propertyParent: any =
39
- parts[0] === key ? property : result.find(item => item.key === parts[0]);
40
- property = propertyParent?.properties[parts[1]];
47
+ let propertyParent =
48
+ parts[0] === schemaKey
49
+ ? property
50
+ : (properties[parts[0]] as ISchemaObjectExtensionField | undefined);
51
+ if (propertyParent?.$ref) {
52
+ propertyParent = onGetSchema(propertyParent.$ref)!;
53
+ }
54
+ property = propertyParent?.properties?.[parts[1]] as ISchemaObjectExtensionField;
41
55
  key = fieldSource;
42
56
  }
43
57
  if (!property) continue;
@@ -49,6 +63,14 @@ export function loadSchemaProperties(
49
63
  : undefined,
50
64
  schemaScene ? { rest: property.rest?.[schemaScene] ?? {} } : undefined,
51
65
  );
66
+ if (schemaKey !== key) {
67
+ property.schemaKey = schemaKey;
68
+ }
69
+ const propertyExisting = result.find(item => item.key === key);
70
+ if (propertyExisting) {
71
+ propertyExisting.schemaKeys = [...(propertyExisting.schemaKeys ?? []), schemaKey];
72
+ continue;
73
+ }
52
74
  result.push(property);
53
75
  }
54
76
  // sort
@@ -20,7 +20,7 @@ import {
20
20
  schemaToZodSchema,
21
21
  } from '../lib/schema.js';
22
22
  import { TypeOpenapiPermissions } from '../types/permissions.js';
23
- import { TypeSchemaScene } from '../types/rest.js';
23
+ import { ISchemaObjectExtensionField, TypeSchemaScene } from '../types/rest.js';
24
24
  import { IOpenapiSchemas, TypeOpenapiSchemasSdk } from '../types/schema.js';
25
25
  import { TypeRequestMethod } from '../types/sdk.js';
26
26
 
@@ -236,7 +236,7 @@ export class ModelSdk extends BeanModelBase {
236
236
  public loadSchemaProperties(
237
237
  schema: SchemaObject | undefined,
238
238
  schemaScene?: TypeSchemaScene,
239
- ): SchemaObject[] | undefined {
239
+ ): ISchemaObjectExtensionField[] | undefined {
240
240
  return loadSchemaProperties(schema, schemaName => this.getSchema(schemaName).data, schemaScene);
241
241
  }
242
242
 
@@ -47,6 +47,10 @@ export interface ISchemaObjectExtensionFieldFilter {
47
47
 
48
48
  export interface ISchemaObjectExtensionField extends SchemaObject {
49
49
  key?: string;
50
+ /** Original property name before fieldSource normalization. */
51
+ schemaKey?: string;
52
+ /** Additional schema aliases that resolve to this canonical key. */
53
+ schemaKeys?: string[];
50
54
  rest?: ISchemaObjectExtensionFieldRest;
51
55
  filter?: ISchemaObjectExtensionFieldFilter;
52
56
  }
@@ -1,6 +1,5 @@
1
- import type { DefaultError, UseQueryReturnType } from '@tanstack/vue-query';
2
1
  import type { OpenAPIObject, SchemaObject } from 'openapi3-ts/oas31';
3
- import type { UnwrapNestedRefs } from 'vue';
2
+ import type { ModelUseQueryReturnType } from 'zova-module-a-model';
4
3
 
5
4
  import type { IOpenapiSdkItem } from './sdk.js';
6
5
 
@@ -11,9 +10,7 @@ export interface IOpenapiSchema {
11
10
 
12
11
  export interface IOpenapiSchemaMeta {}
13
12
 
14
- export type TypeOpenapiSchemasSdk = UnwrapNestedRefs<
15
- UseQueryReturnType<IOpenapiSdkItem, DefaultError>
16
- >;
13
+ export type TypeOpenapiSchemasSdk = ModelUseQueryReturnType<IOpenapiSdkItem, Error>;
17
14
 
18
15
  export interface IOpenapiSchemas {
19
16
  sdk: TypeOpenapiSchemasSdk;
@@ -0,0 +1,179 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import type { ISchemaObjectExtensionField } from '../../src/types/rest.js';
5
+
6
+ import { loadSchemaProperties } from '../../src/lib/schema.js';
7
+
8
+ const onGetSchema = () => undefined;
9
+
10
+ function field(field: ISchemaObjectExtensionField) {
11
+ return field;
12
+ }
13
+
14
+ test('schema properties preserve the canonical fieldSource key and original schema key', () => {
15
+ const properties = loadSchemaProperties(
16
+ {
17
+ type: 'object',
18
+ properties: {
19
+ content: field({
20
+ type: 'object',
21
+ rest: { fieldSource: 'content.descriptionMarkdown' },
22
+ properties: {
23
+ descriptionMarkdown: field({
24
+ type: 'string',
25
+ rest: { render: 'start-markdown:formFieldMarkdown' as any },
26
+ }),
27
+ },
28
+ }),
29
+ },
30
+ },
31
+ onGetSchema,
32
+ );
33
+
34
+ assert.deepEqual(properties, [
35
+ {
36
+ key: 'content.descriptionMarkdown',
37
+ schemaKey: 'content',
38
+ type: 'string',
39
+ rest: { render: 'start-markdown:formFieldMarkdown' },
40
+ },
41
+ ]);
42
+ });
43
+
44
+ test('schema properties preserve virtual aliases without changing the form key', () => {
45
+ const properties = loadSchemaProperties(
46
+ {
47
+ type: 'object',
48
+ properties: {
49
+ content: field({
50
+ type: 'object',
51
+ rest: { visible: false },
52
+ properties: {
53
+ descriptionMarkdown: field({ type: 'string' }),
54
+ },
55
+ }),
56
+ _descriptionMarkdown: field({
57
+ type: 'object',
58
+ rest: { fieldSource: 'content.descriptionMarkdown' },
59
+ }),
60
+ },
61
+ },
62
+ onGetSchema,
63
+ );
64
+
65
+ assert.deepEqual(properties?.[1], {
66
+ key: 'content.descriptionMarkdown',
67
+ schemaKey: '_descriptionMarkdown',
68
+ type: 'string',
69
+ });
70
+ });
71
+
72
+ test('schema properties normalize a scene-specific fieldSource', () => {
73
+ const properties = loadSchemaProperties(
74
+ {
75
+ type: 'object',
76
+ properties: {
77
+ content: field({
78
+ type: 'object',
79
+ rest: { visible: false },
80
+ properties: {
81
+ descriptionMarkdown: field({ type: 'string' }),
82
+ },
83
+ }),
84
+ _descriptionMarkdown: field({
85
+ type: 'object',
86
+ rest: { form: { fieldSource: 'content.descriptionMarkdown' } },
87
+ }),
88
+ },
89
+ },
90
+ onGetSchema,
91
+ 'form',
92
+ );
93
+
94
+ assert.deepEqual(properties?.[1], {
95
+ key: 'content.descriptionMarkdown',
96
+ schemaKey: '_descriptionMarkdown',
97
+ type: 'string',
98
+ });
99
+ });
100
+
101
+ test('schema properties coalesce aliases when the source property has fieldSource', () => {
102
+ const properties = loadSchemaProperties(
103
+ {
104
+ type: 'object',
105
+ properties: {
106
+ content: field({
107
+ type: 'object',
108
+ rest: { fieldSource: 'content.descriptionMarkdown' },
109
+ properties: {
110
+ descriptionMarkdown: field({ type: 'string' }),
111
+ },
112
+ }),
113
+ _descriptionMarkdown: field({
114
+ type: 'object',
115
+ rest: { fieldSource: 'content.descriptionMarkdown' },
116
+ }),
117
+ studentContentForm: field({
118
+ type: 'object',
119
+ rest: { fieldSource: 'content.descriptionMarkdown' },
120
+ }),
121
+ },
122
+ },
123
+ onGetSchema,
124
+ );
125
+
126
+ assert.deepEqual(properties, [
127
+ {
128
+ key: 'content.descriptionMarkdown',
129
+ schemaKey: 'content',
130
+ schemaKeys: ['_descriptionMarkdown', 'studentContentForm'],
131
+ type: 'string',
132
+ },
133
+ ]);
134
+ });
135
+
136
+ test('schema properties coalesce aliases declared before their fieldSource parent', () => {
137
+ const properties = loadSchemaProperties(
138
+ {
139
+ type: 'object',
140
+ properties: {
141
+ _descriptionMarkdown: field({
142
+ type: 'object',
143
+ rest: { fieldSource: 'content.descriptionMarkdown' },
144
+ }),
145
+ content: field({
146
+ type: 'object',
147
+ rest: { fieldSource: 'content.descriptionMarkdown' },
148
+ properties: {
149
+ descriptionMarkdown: field({ type: 'string' }),
150
+ },
151
+ }),
152
+ },
153
+ },
154
+ onGetSchema,
155
+ );
156
+
157
+ assert.deepEqual(properties, [
158
+ {
159
+ key: 'content.descriptionMarkdown',
160
+ schemaKey: '_descriptionMarkdown',
161
+ schemaKeys: ['content'],
162
+ type: 'string',
163
+ },
164
+ ]);
165
+ });
166
+
167
+ test('ordinary schema properties do not gain a schema alias', () => {
168
+ const properties = loadSchemaProperties(
169
+ {
170
+ type: 'object',
171
+ properties: {
172
+ name: field({ type: 'string' }),
173
+ },
174
+ },
175
+ onGetSchema,
176
+ );
177
+
178
+ assert.deepEqual(properties, [{ key: 'name', type: 'string' }]);
179
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.153",
3
+ "version": "5.1.154",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -16,13 +16,13 @@
16
16
  "zova-module-a-boundary": "^5.1.22",
17
17
  "zova-module-a-command": "^5.1.34",
18
18
  "zova-module-a-fetch": "^5.1.25",
19
- "zova-module-a-form": "^5.1.49",
19
+ "zova-module-a-form": "^5.1.50",
20
20
  "zova-module-a-icon": "^5.1.27",
21
21
  "zova-module-a-interceptor": "^5.1.31",
22
22
  "zova-module-a-logger": "^5.1.28",
23
23
  "zova-module-a-meta": "^5.1.22",
24
- "zova-module-a-model": "^5.1.35",
25
- "zova-module-a-openapi": "^5.1.50",
24
+ "zova-module-a-model": "^5.1.36",
25
+ "zova-module-a-openapi": "^5.1.51",
26
26
  "zova-module-a-router": "^5.1.34",
27
27
  "zova-module-a-routerstack": "^5.1.27",
28
28
  "zova-module-a-routertabs": "^5.1.34",