cabloy 5.1.64 → 5.1.66

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 (173) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/cabloy-docs/.vitepress/config.mjs +1 -1
  3. package/cabloy-docs/backend/crud-workflow.md +33 -0
  4. package/cabloy-docs/backend/master-detail-workflow.md +149 -0
  5. package/cabloy-docs/frontend/bean-scene-authoring.md +1 -1
  6. package/cabloy-docs/frontend/cli.md +12 -1
  7. package/cabloy-docs/frontend/command-scene-authoring.md +12 -1
  8. package/cabloy-docs/frontend/component-guide.md +10 -0
  9. package/cabloy-docs/frontend/permission-formscene-action-visibility-guide.md +69 -7
  10. package/cabloy-docs/frontend/table-cell-cookbook.md +10 -0
  11. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions.md +83 -2
  12. package/cabloy-docs/reference/bean-scene-boilerplates.md +9 -4
  13. package/package.json +1 -1
  14. package/vona/packages-cli/cabloy-cli/package.json +1 -1
  15. package/vona/packages-cli/cabloy-cli/src/lib/local.helper.ts +38 -0
  16. package/vona/packages-cli/cli/package.json +1 -1
  17. package/vona/packages-cli/cli-set-api/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoBaseName%>.tsx_ +18 -0
  18. package/vona/packages-cli/cli-set-api/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoMutateName%>.tsx_ +17 -0
  19. package/vona/packages-cli/cli-set-api/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoResItemName%>.tsx_ +60 -0
  20. package/vona/packages-cli/cli-set-api/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoViewName%>.tsx_ +17 -0
  21. package/vona/packages-cli/cli-set-api/package.json +1 -1
  22. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.bean.ts +2 -6
  23. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.module.ts +3 -6
  24. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.suite.ts +1 -1
  25. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.test.ts +2 -6
  26. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.asset.ts +2 -6
  27. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.config.ts +2 -6
  28. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.constant.ts +2 -6
  29. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.error.ts +2 -6
  30. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.lib.ts +2 -6
  31. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.locale.ts +2 -6
  32. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.main.ts +2 -6
  33. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.monkey.ts +2 -6
  34. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.static.ts +2 -6
  35. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.init.types.ts +2 -6
  36. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.tools.crud.ts +2 -6
  37. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.tools.crudBasic.ts +2 -6
  38. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.tools.crudStart.ts +2 -6
  39. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.tools.masterDetail.ts +699 -0
  40. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.tools.metadata.ts +1 -2
  41. package/vona/packages-cli/cli-set-api/src/lib/beans.ts +2 -0
  42. package/vona/packages-cli/cli-set-api/src/lib/command/tools.masterDetail.ts +78 -0
  43. package/vona/packages-cli/cli-set-api/src/lib/commands.ts +2 -0
  44. package/vona/packages-vona/vona/package.json +1 -1
  45. package/vona/packages-vona/vona-core/package.json +1 -1
  46. package/vona/packages-vona/vona-core/src/lib/mappedClass/type.ts +1 -0
  47. package/vona/packages-vona/vona-core/src/lib/mappedClass/utils.ts +36 -14
  48. package/vona/packages-vona/vona-mock/package.json +1 -1
  49. package/vona/pnpm-lock.yaml +29 -11
  50. package/vona/src/suite/a-training/modules/training-record/src/entity/record.tsx +1 -7
  51. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +3 -0
  52. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +3 -0
  53. package/vona/src/suite/a-training/modules/training-student/src/dto/detailRecordBase.tsx +8 -2
  54. package/vona/src/suite/a-training/modules/training-student/src/dto/detailRecordMutate.tsx +1 -15
  55. package/vona/src/suite/a-training/modules/training-student/src/dto/detailRecordResItem.tsx +27 -8
  56. package/vona/src/suite/a-training/modules/training-student/src/dto/detailRecordView.tsx +1 -12
  57. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +6 -4
  58. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectReq.tsx +3 -6
  59. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +1 -1
  60. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +14 -1
  61. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +14 -1
  62. package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +1 -5
  63. package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +9 -4
  64. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  65. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/package.json +1 -1
  66. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/const/decorator.ts +3 -1
  67. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/schema/makeSchemaLikes.ts +21 -17
  68. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/utils.ts +44 -2
  69. package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
  70. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGet.ts +2 -2
  71. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoMutate.ts +8 -1
  72. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/relations_.ts +32 -16
  73. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  74. package/vona/src/suite-vendor/a-vona/modules/a-web/src/lib/decorator/bean.ts +26 -5
  75. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  76. package/zova/packages-cli/cli/package.json +3 -3
  77. package/zova/packages-cli/cli-set-front/cli/templates/create/component/boilerplateDetailsActionBulk/controller.tsx_ +31 -0
  78. package/zova/packages-cli/cli-set-front/cli/templates/rest/component.ts +24 -2
  79. package/zova/packages-cli/cli-set-front/cli/templates/rest/render.ts +4 -0
  80. package/zova/packages-cli/cli-set-front/package.json +2 -2
  81. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.bean.ts +2 -6
  82. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.mock.ts +2 -6
  83. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.module.ts +3 -6
  84. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.suite.ts +1 -1
  85. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.asset.ts +2 -6
  86. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.config.ts +2 -6
  87. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.constant.ts +2 -6
  88. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.error.ts +2 -6
  89. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.icon.ts +2 -6
  90. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.lib.ts +2 -6
  91. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.locale.ts +2 -6
  92. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.main.ts +2 -6
  93. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.mainSys.ts +2 -6
  94. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.monkey.ts +2 -6
  95. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.monkeySys.ts +2 -6
  96. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.init.types.ts +2 -6
  97. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.config.ts +1 -4
  98. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +2 -2
  99. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.anotherRender.ts +2 -6
  100. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.anotherStyle.ts +2 -6
  101. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.componentEmits.ts +2 -6
  102. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.componentGeneric.ts +2 -6
  103. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.componentModel.ts +2 -6
  104. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.componentProps.ts +2 -6
  105. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.componentSlots.ts +2 -6
  106. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.firstRender.ts +2 -6
  107. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.firstStyle.ts +2 -6
  108. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.pageParams.ts +2 -6
  109. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.pageQuery.ts +2 -6
  110. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.refactor.renameComponent.ts +2 -6
  111. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.tools.metadata.ts +1 -2
  112. package/zova/packages-cli/cli-set-front/src/lib/common/cliCreateComponent.ts +2 -6
  113. package/zova/packages-cli/cli-set-front/src/lib/common/cliCreatePage.ts +2 -6
  114. package/zova/packages-zova/zova/package.json +2 -2
  115. package/zova/pnpm-lock.yaml +744 -884
  116. package/zova/src/suite/a-training/modules/training-student/package.json +2 -1
  117. package/zova/src/suite/cabloy-basic/modules/basic-app/src/bean/behavior.appModal.tsx +131 -13
  118. package/zova/src/suite/cabloy-basic/modules/basic-app/src/config/config.ts +15 -0
  119. package/zova/src/suite/cabloy-basic/modules/basic-app/src/service/appModal.ts +23 -5
  120. package/zova/src/suite/cabloy-basic/modules/basic-app/src/types/appModal.ts +30 -4
  121. package/zova/src/suite/cabloy-basic/modules/basic-details/package.json +6 -1
  122. package/zova/src/suite/cabloy-basic/modules/basic-details/src/.metadata/component/blockForm.ts +31 -0
  123. package/zova/src/suite/cabloy-basic/modules/basic-details/src/.metadata/component/blockTable.ts +31 -0
  124. package/zova/src/suite/cabloy-basic/modules/basic-details/src/.metadata/component/blockToolbarBulk.ts +31 -0
  125. package/zova/src/suite/cabloy-basic/modules/basic-details/src/.metadata/index.ts +204 -9
  126. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/command.delete.tsx +47 -0
  127. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.actionDelete.tsx +52 -0
  128. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.actionOperationsRow.tsx +72 -0
  129. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.actionUpdate.tsx +73 -0
  130. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.actionView.tsx +64 -0
  131. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.lineNumber.tsx +30 -0
  132. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/actionCreate/controller.tsx +31 -7
  133. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/blockDetails/controller.tsx +28 -12
  134. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/blockForm/controller.tsx +53 -0
  135. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/blockTable/controller.tsx +49 -0
  136. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/{blockDetailsToolbarBulk → blockToolbarBulk}/controller.tsx +6 -4
  137. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/formFieldDetails/controller.tsx +24 -12
  138. package/zova/src/suite/cabloy-basic/modules/basic-details/src/config/locale/en-us.ts +5 -1
  139. package/zova/src/suite/cabloy-basic/modules/basic-details/src/config/locale/zh-cn.ts +5 -1
  140. package/zova/src/suite/cabloy-basic/modules/basic-details/src/index.ts +1 -0
  141. package/zova/src/suite/cabloy-basic/modules/basic-details/src/lib/index.ts +1 -0
  142. package/zova/src/suite/cabloy-basic/modules/basic-details/src/lib/utils.ts +12 -0
  143. package/zova/src/suite/cabloy-basic/modules/basic-details/src/service/detail.tsx +172 -0
  144. package/zova/src/suite/cabloy-basic/modules/basic-details/src/types/detail.ts +18 -0
  145. package/zova/src/suite/cabloy-basic/modules/basic-details/src/types/details.ts +11 -0
  146. package/zova/src/suite/cabloy-basic/modules/basic-details/src/types/dialogForm.ts +22 -0
  147. package/zova/src/suite/cabloy-basic/modules/basic-details/src/types/index.ts +2 -0
  148. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  149. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/entry/controller.tsx +1 -2
  150. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  151. package/zova/src/suite-vendor/a-zova/modules/a-command/cli/command/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
  152. package/zova/src/suite-vendor/a-zova/modules/a-command/cli/commandBulk/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
  153. package/zova/src/suite-vendor/a-zova/modules/a-command/cli/commandDetailsRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +20 -0
  154. package/zova/src/suite-vendor/a-zova/modules/a-command/cli/commandRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
  155. package/zova/src/suite-vendor/a-zova/modules/a-command/package.json +3 -2
  156. package/zova/src/suite-vendor/a-zova/modules/a-command/src/types/command.ts +2 -0
  157. package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
  158. package/zova/src/suite-vendor/a-zova/modules/a-form/src/component/form/controller.tsx +1 -0
  159. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +2 -2
  160. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts +20 -4
  161. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/action.ts +2 -1
  162. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/detail/detail.ts +10 -0
  163. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/detail/details.ts +4 -1
  164. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/detail/detailsActionRow.ts +24 -0
  165. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/detail/index.ts +2 -0
  166. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/permissions.ts +4 -0
  167. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +2 -0
  168. package/zova/src/suite-vendor/a-zova/modules/a-table/cli/detailsActionRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +24 -0
  169. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +3 -2
  170. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +5 -3
  171. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  172. package/zova/src/suite-vendor/a-zova/package.json +6 -6
  173. package/zova/src/suite/cabloy-basic/modules/basic-details/src/.metadata/component/blockDetailsToolbarBulk.ts +0 -31
@@ -15,7 +15,7 @@ import type { ModelStudent } from '../model/student.ts';
15
15
  @Service()
16
16
  export class ServiceStudent extends BeanBase {
17
17
  async create(student: DtoStudentCreate): Promise<EntityStudent> {
18
- return await this.scope.model.student.insert(student);
18
+ return await this.scope.model.student.insert(student, { include: { trainingRecords: true } });
19
19
  }
20
20
 
21
21
  async select(params?: IQueryParams<ModelStudent>): Promise<DtoStudentSelectRes> {
@@ -27,7 +27,9 @@ export class ServiceStudent extends BeanBase {
27
27
  }
28
28
 
29
29
  async update(id: TableIdentity, student: DtoStudentUpdate) {
30
- return await this.scope.model.student.updateById(id, student);
30
+ return await this.scope.model.student.updateById(id, student, {
31
+ include: { trainingRecords: true },
32
+ });
31
33
  }
32
34
 
33
35
  async summary(id: TableIdentity): Promise<DtoStudentSummary | undefined> {
@@ -48,10 +50,13 @@ export class ServiceStudent extends BeanBase {
48
50
  }
49
51
 
50
52
  async delete(id: TableIdentity) {
51
- return await this.scope.model.student.deleteById(id);
53
+ return await this.scope.model.student.deleteById(id, { include: { trainingRecords: true } });
52
54
  }
53
55
 
54
56
  async deleteForce(id: TableIdentity) {
55
- return await this.scope.model.student.deleteById(id, { disableDeleted: true });
57
+ return await this.scope.model.student.deleteById(id, {
58
+ disableDeleted: true,
59
+ include: { trainingRecords: true },
60
+ });
56
61
  }
57
62
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-core",
3
- "version": "5.1.27",
3
+ "version": "5.1.31",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-openapiutils",
3
- "version": "5.1.14",
3
+ "version": "5.1.15",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -2,5 +2,7 @@ export const SymbolRouteHandlersArgumentsMeta = Symbol('SymbolRouteHandlersArgum
2
2
  export const SymbolRouteHandlersArgumentsValue = Symbol('SymbolRouteHandlersArgumentsValue');
3
3
 
4
4
  export const SymbolOpenApiOptions = Symbol('SymbolOpenApiOptions');
5
- export const SymbolDecoratorRule = Symbol('SymbolDecoratorRule');
6
5
  export const SymbolControllerResource = Symbol('SymbolControllerResource');
6
+ export const SymbolDecoratorRule = Symbol('SymbolDecoratorRule');
7
+ export const SymbolDecoratorDtoOpenapi = Symbol('SymbolDecoratorDtoOpenapi');
8
+ export const SymbolDecoratorDtoPipes = Symbol('SymbolDecoratorDtoPipes');
@@ -1,5 +1,5 @@
1
1
  import type { Constructable } from 'vona';
2
- import type { ISchemaObjectExtensionField, ISchemaObjectOptions } from 'vona-module-a-openapi';
2
+ import type { ISchemaObjectOptions } from 'vona-module-a-openapi';
3
3
 
4
4
  import { isClass } from '@cabloy/utils';
5
5
  import { appMetadata, appResource, cast } from 'vona';
@@ -8,7 +8,11 @@ import { z } from 'zod';
8
8
  import type { SchemaLike, SchemaLikeCreate } from '../../types/decorator.ts';
9
9
 
10
10
  import { SymbolDecoratorRule } from '../const/decorator.ts';
11
- import { prepareClassType } from '../utils.ts';
11
+ import {
12
+ getTargetDecoratorDtoOpenapi,
13
+ getTargetDecoratorDtoPipes,
14
+ prepareClassType,
15
+ } from '../utils.ts';
12
16
  import { SymbolSchemaDynamicRefId } from './schemaDynamic.ts';
13
17
 
14
18
  export function $makeSchema<T>(...schemaLikes: SchemaLike<T>[]): z.ZodType<T> {
@@ -82,22 +86,22 @@ export function $schema(classType: any, options?: ISchemaObjectOptions): any {
82
86
  }
83
87
  // object
84
88
  let schema = _createSchemaObject(rules, options);
85
- // refId
86
- const schemaDynamicRefId = classType[SymbolSchemaDynamicRefId];
87
- if (schemaDynamicRefId) {
88
- // dynamic
89
- schema = schema.openapi(schemaDynamicRefId);
90
- } else {
91
- // static
89
+ // dto: pipes
90
+ const dtoPipes = getTargetDecoratorDtoPipes(classType.prototype, true);
91
+ if (dtoPipes) {
92
+ schema = makeSchemaLikes(dtoPipes, schema) as any;
93
+ }
94
+ // dto: openapi
95
+ let schemaRefId = classType[SymbolSchemaDynamicRefId];
96
+ if (!schemaRefId) {
92
97
  const beanOptions = appResource.getBean(classType);
93
- if (beanOptions) {
94
- const pipes: SchemaLike | SchemaLike[] = cast(beanOptions.options)?.pipes;
95
- if (pipes) {
96
- schema = makeSchemaLikes(pipes, schema) as any;
97
- }
98
- const openapi: ISchemaObjectExtensionField = cast(beanOptions.options)?.openapi;
99
- schema = schema.openapi(beanOptions.beanFullName, openapi);
100
- }
98
+ schemaRefId = beanOptions?.beanFullName;
99
+ }
100
+ const dtoOpenapi = getTargetDecoratorDtoOpenapi(classType.prototype, true);
101
+ if (schemaRefId) {
102
+ schema = schema.openapi(schemaRefId, dtoOpenapi);
103
+ } else if (dtoOpenapi) {
104
+ schema = schema.openapi(dtoOpenapi);
101
105
  }
102
106
  return schema as any;
103
107
  }
@@ -6,10 +6,14 @@ import { ZodMetadata } from '@cabloy/zod-openapi';
6
6
  import { appMetadata, appResource, cast, deepExtend, registerMappedClassMetadataKey } from 'vona';
7
7
  import { z } from 'zod';
8
8
 
9
- import type { TypeDecoratorRules } from '../types/decorator.ts';
9
+ import type { SchemaLike, TypeDecoratorRules } from '../types/decorator.ts';
10
10
 
11
11
  import { OrderLevelBaseMap } from './const/database.ts';
12
- import { SymbolDecoratorRule } from './const/decorator.ts';
12
+ import {
13
+ SymbolDecoratorDtoOpenapi,
14
+ SymbolDecoratorDtoPipes,
15
+ SymbolDecoratorRule,
16
+ } from './const/decorator.ts';
13
17
 
14
18
  export function getTargetDecoratorRules(
15
19
  target: object,
@@ -25,6 +29,44 @@ export function getTargetDecoratorRules(
25
29
  return appMetadata.getOwnMetadataMap(true, SymbolDecoratorRule, target);
26
30
  }
27
31
 
32
+ export function getTargetDecoratorDtoOpenapi(
33
+ target: object,
34
+ disableRegisterMetadata?: boolean,
35
+ ): ISchemaObjectExtensionField | undefined {
36
+ if (!disableRegisterMetadata) {
37
+ registerMappedClassMetadataKey(target, SymbolDecoratorDtoOpenapi, {
38
+ replace: true,
39
+ });
40
+ }
41
+ return appMetadata.getOwnMetadata(SymbolDecoratorDtoOpenapi, target);
42
+ }
43
+
44
+ export function setTargetDecoratorDtoOpenapi(
45
+ openapi: ISchemaObjectExtensionField | undefined,
46
+ target: object,
47
+ ) {
48
+ appMetadata.defineMetadata(SymbolDecoratorDtoOpenapi, openapi, target);
49
+ }
50
+
51
+ export function getTargetDecoratorDtoPipes(
52
+ target: object,
53
+ disableRegisterMetadata?: boolean,
54
+ ): SchemaLike | SchemaLike[] | undefined {
55
+ if (!disableRegisterMetadata) {
56
+ registerMappedClassMetadataKey(target, SymbolDecoratorDtoPipes, {
57
+ replace: true,
58
+ });
59
+ }
60
+ return appMetadata.getOwnMetadata(SymbolDecoratorDtoPipes, target);
61
+ }
62
+
63
+ export function setTargetDecoratorDtoPipes(
64
+ pipes: SchemaLike | SchemaLike[] | undefined,
65
+ target: object,
66
+ ) {
67
+ appMetadata.defineMetadata(SymbolDecoratorDtoPipes, pipes, target);
68
+ }
69
+
28
70
  export function getTargetDecoratorRuleColumns(target: object): string[] {
29
71
  const rules = getTargetDecoratorRules(target, true);
30
72
  return Object.keys(rules);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-orm",
3
- "version": "5.1.13",
3
+ "version": "5.1.14",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "db",
6
6
  "keywords": [
@@ -55,8 +55,8 @@ function _DtoGet_raw<
55
55
  // entity
56
56
  let entityClass = params?.dtoClass ?? getClassEntityFromClassModel(modelClass);
57
57
  // columns
58
- const columns = prepareColumns(params?.columns);
59
- // always create a new class, no matter if columns empty
58
+ const columns = params?.dtoClass ? undefined : prepareColumns(params?.columns);
59
+ // always create a new class, no matter if columns empty: dtoClass keeps own fields
60
60
  entityClass = $Class.pick(entityClass, columns as any);
61
61
  // relations
62
62
  _DtoGet_relations(modelClass, entityClass, params as any);
@@ -2,6 +2,7 @@ import type { Constructable } from 'vona';
2
2
 
3
3
  import { mutate } from 'mutate-on-copy';
4
4
  import { $Class } from 'vona';
5
+ import { getTargetDecoratorRuleColumns } from 'vona-module-a-openapiutils';
5
6
 
6
7
  import type {
7
8
  IDtoMutateParams,
@@ -54,7 +55,13 @@ export function _DtoMutate_raw<
54
55
  // entity
55
56
  let entityClass = params?.dtoClass ?? getClassEntityFromClassModel(modelClass);
56
57
  // columns
57
- let columns = prepareColumns(params?.columns);
58
+ let columns;
59
+ // if dtoClass, use dtoClass fields
60
+ if (params?.dtoClass) {
61
+ columns = getTargetDecoratorRuleColumns(params.dtoClass.prototype) as any;
62
+ } else {
63
+ columns = prepareColumns(params?.columns);
64
+ }
58
65
  if (columns) {
59
66
  if (!topLevel) {
60
67
  if (mutateTypeTopLevel === 'create') {
@@ -187,7 +187,7 @@ export class ServiceRelations extends BeanBase {
187
187
  }
188
188
  for (const entity of entities) {
189
189
  entity[relationName] = items.find(item => {
190
- if (item[key] === cast(entity).id) {
190
+ if (this.__sameTableIdentity(item[key], cast(entity).id)) {
191
191
  if (!withKey) delete item[key];
192
192
  return true;
193
193
  }
@@ -199,7 +199,9 @@ export class ServiceRelations extends BeanBase {
199
199
  const options2 = deepExtend({}, methodOptionsReal, optionsReal);
200
200
  const items = await modelTarget.mget(idsTo, options2);
201
201
  for (const entity of entities) {
202
- entity[relationName] = items.find(item => cast(item).id === cast(entity)[key]);
202
+ entity[relationName] = items.find(item =>
203
+ this.__sameTableIdentity(cast(item).id, cast(entity)[key]),
204
+ );
203
205
  }
204
206
  } else if (type === 'hasMany') {
205
207
  const idsFrom = entities.map(item => cast(item).id).filter(id => !isNil(id));
@@ -210,7 +212,7 @@ export class ServiceRelations extends BeanBase {
210
212
  for (const entity of entities) {
211
213
  entity[relationName] = [];
212
214
  for (const item of items) {
213
- if (item[key] === cast(entity).id) {
215
+ if (this.__sameTableIdentity(item[key], cast(entity).id)) {
214
216
  delete item[key];
215
217
  entity[relationName].push(item);
216
218
  }
@@ -220,7 +222,7 @@ export class ServiceRelations extends BeanBase {
220
222
  const options2 = deepExtend({}, optionsReal, { groups: key, where: { [key]: idsFrom } });
221
223
  const items = await modelTarget.group(options2, methodOptionsReal);
222
224
  for (const entity of entities) {
223
- const item = items.find(item => item[key] === cast(entity).id);
225
+ const item = items.find(item => this.__sameTableIdentity(item[key], cast(entity).id));
224
226
  if (item) {
225
227
  delete item[key];
226
228
  }
@@ -233,7 +235,7 @@ export class ServiceRelations extends BeanBase {
233
235
  for (const entity of entities) {
234
236
  entity[relationName] = [];
235
237
  for (const item of items) {
236
- if (item[key] === cast(entity).id) {
238
+ if (this.__sameTableIdentity(item[key], cast(entity).id)) {
237
239
  if (!withKey) delete item[key];
238
240
  entity[relationName].push(item);
239
241
  }
@@ -258,7 +260,7 @@ export class ServiceRelations extends BeanBase {
258
260
  if (optionsReal.groups) {
259
261
  for (const entity of entities) {
260
262
  const idsTo = itemsMiddle
261
- .filter(item => item[keyFrom] === cast(entity).id)
263
+ .filter(item => this.__sameTableIdentity(item[keyFrom], cast(entity).id))
262
264
  .map(item => item[keyTo]);
263
265
  const options2 = deepExtend({}, optionsReal, {
264
266
  groups: optionsReal.groups,
@@ -269,7 +271,7 @@ export class ServiceRelations extends BeanBase {
269
271
  } else if (optionsReal.aggrs) {
270
272
  for (const entity of entities) {
271
273
  const idsTo = itemsMiddle
272
- .filter(item => item[keyFrom] === cast(entity).id)
274
+ .filter(item => this.__sameTableIdentity(item[keyFrom], cast(entity).id))
273
275
  .map(item => item[keyTo]);
274
276
  const options2 = deepExtend({}, optionsReal, { where: { id: idsTo } });
275
277
  entity[relationName] = await modelTarget.aggregate(options2, methodOptionsReal);
@@ -281,9 +283,11 @@ export class ServiceRelations extends BeanBase {
281
283
  for (const entity of entities) {
282
284
  entity[relationName] = [];
283
285
  for (const itemMiddle of itemsMiddle) {
284
- if (itemMiddle[keyFrom] === cast(entity).id) {
286
+ if (this.__sameTableIdentity(itemMiddle[keyFrom], cast(entity).id)) {
285
287
  entity[relationName].push(
286
- items.find(item => cast(item).id === cast(itemMiddle)[keyTo]),
288
+ items.find(item =>
289
+ this.__sameTableIdentity(cast(item).id, cast(itemMiddle)[keyTo]),
290
+ ),
287
291
  );
288
292
  }
289
293
  }
@@ -348,19 +352,21 @@ export class ServiceRelations extends BeanBase {
348
352
  if (entity[relationName] && entity[relationName].length > 0) {
349
353
  const entityId = cast(entity).id;
350
354
  const idsTo = entity[relationName].map(item => item.id).filter(id => !isNil(id));
351
- let idsTarget;
355
+ let idsTargetSet: Set<string>;
352
356
  if (idsTo.length === 0) {
353
- idsTarget = [];
357
+ idsTargetSet = new Set();
354
358
  } else {
355
359
  const itemsTarget = await cast(modelTarget).__select_raw(
356
360
  undefined,
357
361
  { where: { [key]: entityId, id: idsTo } },
358
362
  methodOptionsReal,
359
363
  );
360
- idsTarget = itemsTarget.map(item => item.id);
364
+ idsTargetSet = new Set(
365
+ itemsTarget.map((item: { id: TableIdentity }) => String(item.id)),
366
+ );
361
367
  }
362
368
  for (const child of entity[relationName]) {
363
- if (!isNil(child.id) && !idsTarget.includes(child.id)) {
369
+ if (!isNil(child.id) && !idsTargetSet.has(String(child.id))) {
364
370
  throw new Error(`invalid id: ${child.id}`);
365
371
  }
366
372
  children.push(Object.assign({}, child, { [key]: entityId }));
@@ -375,7 +381,7 @@ export class ServiceRelations extends BeanBase {
375
381
  if (entity[relationName]) {
376
382
  entityResult[relationName] = [];
377
383
  for (const child of children) {
378
- if (child[key] === cast(entity).id) {
384
+ if (this.__sameTableIdentity(child[key], cast(entity).id)) {
379
385
  entityResult[relationName].push(child);
380
386
  }
381
387
  }
@@ -403,7 +409,9 @@ export class ServiceRelations extends BeanBase {
403
409
  );
404
410
  }
405
411
  for (const child of entity[relationName]) {
406
- const itemMiddle = itemsMiddle.find(item => item[keyTo] === child.id);
412
+ const itemMiddle = itemsMiddle.find(item =>
413
+ this.__sameTableIdentity(item[keyTo], child.id),
414
+ );
407
415
  if (!itemMiddle) {
408
416
  if (!child.deleted) {
409
417
  // add
@@ -426,7 +434,7 @@ export class ServiceRelations extends BeanBase {
426
434
  if (entity[relationName]) {
427
435
  entityResult[relationName] = [];
428
436
  for (const child of children) {
429
- if (child[keyFrom] === cast(entity).id) {
437
+ if (this.__sameTableIdentity(child[keyFrom], cast(entity).id)) {
430
438
  entityResult[relationName].push({ id: child[keyTo] });
431
439
  }
432
440
  }
@@ -475,6 +483,14 @@ export class ServiceRelations extends BeanBase {
475
483
  }
476
484
  }
477
485
 
486
+ private __sameTableIdentity(
487
+ id1: TableIdentity | null | undefined,
488
+ id2: TableIdentity | null | undefined,
489
+ ) {
490
+ if (isNil(id1) || isNil(id2)) return false;
491
+ return String(id1) === String(id2);
492
+ }
493
+
478
494
  private __prepareColumnsAndKey(columns: string | string[] | undefined, key: string) {
479
495
  if (!columns) return [columns, true];
480
496
  columns = Array.isArray(columns) ? columns : [columns];
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-web",
3
- "version": "5.1.15",
3
+ "version": "5.1.16",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -11,7 +11,11 @@ import {
11
11
  useApp,
12
12
  } from 'vona';
13
13
  import {
14
+ getTargetDecoratorDtoOpenapi,
15
+ getTargetDecoratorDtoPipes,
14
16
  mergeDtoFieldsOpenapiMetadata,
17
+ setTargetDecoratorDtoOpenapi,
18
+ setTargetDecoratorDtoPipes,
15
19
  SymbolControllerResource,
16
20
  } from 'vona-module-a-openapiutils';
17
21
  import { SymbolOpenApiOptions } from 'vona-module-a-openapiutils';
@@ -85,6 +89,7 @@ export function Dto<T extends IDecoratorDtoOptions<any>>(options?: T): ClassDeco
85
89
  return createBeanDecorator('dto', options, false, target => {
86
90
  mergeDtoFieldsOpenapiMetadata(target);
87
91
  mergeDtoBlocksOpenapiMetadata(target);
92
+ mergeDtoPipesOpenapiMetadata(target);
88
93
  });
89
94
  }
90
95
 
@@ -111,9 +116,25 @@ export function mergeDtoBlocksOpenapiMetadata(target: Constructable) {
111
116
  const beanOptions = appResource.getBean(target);
112
117
  const onionOptions = beanOptions?.options as IDecoratorDtoOptions | undefined;
113
118
  const blocks = onionOptions?.blocks;
114
- if (!blocks) return;
115
- // openapi
116
- onionOptions.openapi = deepExtend({}, onionOptions.openapi, {
117
- rest: { blocks },
118
- });
119
+ if (blocks) {
120
+ onionOptions.openapi = deepExtend({}, onionOptions.openapi, {
121
+ rest: { blocks },
122
+ });
123
+ }
124
+ // always
125
+ getTargetDecoratorDtoOpenapi(target.prototype);
126
+ if (onionOptions?.openapi) {
127
+ setTargetDecoratorDtoOpenapi(onionOptions?.openapi, target.prototype);
128
+ }
129
+ }
130
+
131
+ export function mergeDtoPipesOpenapiMetadata(target: Constructable) {
132
+ // beanOptions
133
+ const beanOptions = appResource.getBean(target);
134
+ const onionOptions = beanOptions?.options as IDecoratorDtoOptions | undefined;
135
+ // always
136
+ getTargetDecoratorDtoPipes(target.prototype);
137
+ if (onionOptions?.pipes) {
138
+ setTargetDecoratorDtoPipes(onionOptions?.pipes, target.prototype);
139
+ }
119
140
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-vona",
3
- "version": "5.1.42",
3
+ "version": "5.1.46",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli",
3
- "version": "1.2.81",
3
+ "version": "1.2.86",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli",
6
6
  "keywords": [
@@ -40,11 +40,11 @@
40
40
  "postpack": "clean-package restore"
41
41
  },
42
42
  "dependencies": {
43
- "@cabloy/cli": "^3.1.18",
43
+ "@cabloy/cli": "^3.1.23",
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.79"
47
+ "zova-cli-set-front": "^1.2.84"
48
48
  },
49
49
  "devDependencies": {
50
50
  "clean-package": "^2.2.0",
@@ -0,0 +1,31 @@
1
+ import type { IComponentOptions } from 'zova';
2
+ import type {
3
+ IJsxRenderContextDetails,
4
+ IResourceDetailsActionBulkOptionsBase,
5
+ } from 'zova-module-a-openapi';
6
+
7
+ import { BeanControllerBase, Use } from 'zova';
8
+ import { Controller } from 'zova-module-a-bean';
9
+
10
+ declare module 'zova-module-a-openapi' {
11
+ export interface IResourceDetailsActionBulkRecord {
12
+ '<%=argv.module%>:<%=argv.nameMeta.full%>'?: Controller<%=argv.nameMeta.fullCapitalize%>Props;
13
+ }
14
+ }
15
+
16
+ export interface Controller<%=argv.nameMeta.fullCapitalize%>Props extends IResourceDetailsActionBulkOptionsBase {}
17
+
18
+ @Controller()
19
+ export class Controller<%=argv.nameMeta.fullCapitalize%> extends BeanControllerBase {
20
+ static $propsDefault = {};
21
+ static $componentOptions: IComponentOptions = { inheritAttrs: false, deepExtendDefault: true };
22
+
23
+ @Use({ injectionScope: 'host' })
24
+ $$renderContext: IJsxRenderContextDetails;
25
+
26
+ protected async __init__() {}
27
+
28
+ protected render() {
29
+ return null;
30
+ }
31
+ }
@@ -4,17 +4,20 @@ import type {
4
4
  IResourceFormFieldRecord,
5
5
  IResourceTableCellRecord,
6
6
  IResourceTableActionRowRecord,
7
+ IResourceDetailsActionRowRecord,
7
8
  IResourceFormActionRowRecord,
8
9
  IResourceTableActionBulkRecord,
9
10
  IResourceDetailsActionBulkRecord,
10
11
  IResourceBlockRecord,
11
12
  TypeFormSchemaScene,
12
13
  IResourceRenderTableActionRowOptionsAction,
14
+ IResourceRenderDetailsActionRowOptionsAction,
13
15
  IResourceRenderFormActionRowOptionsAction,
14
16
  IResourceRenderTableActionBulkOptionsAction,
15
17
  IResourceRenderDetailsActionBulkOptionsAction,
16
18
  IResourceRenderBlockOptionsBlock,
17
19
  IResourceTableActionRowOptionsBase,
20
+ IResourceDetailsActionRowOptionsBase,
18
21
  IResourceFormActionRowOptionsBase,
19
22
  IResourceTableActionBulkOptionsBase,
20
23
  IResourceDetailsActionBulkOptionsBase,
@@ -44,9 +47,9 @@ export function schemaRenderFieldJsx<T extends z.ZodType>(
44
47
  }
45
48
 
46
49
  export function schemaRenderCell<
47
- K extends keyof (IResourceTableCellRecord & IResourceTableActionRowRecord),
50
+ K extends keyof (IResourceTableCellRecord & IResourceTableActionRowRecord & IResourceDetailsActionRowRecord),
48
51
  T extends z.ZodType,
49
- >(render: K, options?: (IResourceTableCellRecord & IResourceTableActionRowRecord)[K]) {
52
+ >(render: K, options?: (IResourceTableCellRecord & IResourceTableActionRowRecord & IResourceDetailsActionRowRecord)[K]) {
50
53
  return function (schema: T): T {
51
54
  const options2 = options !== undefined ? { render, columnProps: options } : { render };
52
55
  return _generalSchemaRest(schema, options2, 'table');
@@ -85,6 +88,25 @@ export function schemaRenderTableActionRowJsx(
85
88
  return { render: renderComponentJsx, options };
86
89
  }
87
90
 
91
+ export function schemaRenderDetailsActionRow<K extends keyof IResourceDetailsActionRowRecord>(
92
+ render: K,
93
+ options?: IResourceDetailsActionRowRecord[K],
94
+ ): IResourceRenderDetailsActionRowOptionsAction {
95
+ const pos = render.toString().indexOf(':action');
96
+ const name =
97
+ pos > -1
98
+ ? _toLowerCaseFirstChar(render.toString().substring(pos + ':action'.length))
99
+ : undefined;
100
+ return { $$typeof: 'zova-jsx:actionRow', name, render, options };
101
+ }
102
+
103
+ export function schemaRenderDetailsActionRowJsx(
104
+ renderComponentJsx: TypeRenderComponentJsx,
105
+ options?: Pick<IResourceDetailsActionRowOptionsBase, 'permission'>,
106
+ ) {
107
+ return { render: renderComponentJsx, options };
108
+ }
109
+
88
110
  export function schemaRenderFormActionRow<K extends keyof IResourceFormActionRowRecord>(
89
111
  render: K,
90
112
  options?: IResourceFormActionRowRecord[K],
@@ -5,6 +5,8 @@ import {
5
5
  schemaRenderCellJsx,
6
6
  schemaRenderDetailsActionBulk,
7
7
  schemaRenderDetailsActionBulkJsx,
8
+ schemaRenderDetailsActionRow,
9
+ schemaRenderDetailsActionRowJsx,
8
10
  schemaRenderField,
9
11
  schemaRenderFieldJsx,
10
12
  schemaRenderFormActionRow,
@@ -38,6 +40,8 @@ export const ZovaRender = {
38
40
  cellJsx: schemaRenderCellJsx,
39
41
  tableActionRow: schemaRenderTableActionRow,
40
42
  tableActionRowJsx: schemaRenderTableActionRowJsx,
43
+ detailsActionRow: schemaRenderDetailsActionRow,
44
+ detailsActionRowJsx: schemaRenderDetailsActionRowJsx,
41
45
  formActionRow: schemaRenderFormActionRow,
42
46
  formActionRowJsx: schemaRenderFormActionRowJsx,
43
47
  tableActionBulk: schemaRenderTableActionBulk,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli-set-front",
3
- "version": "1.2.79",
3
+ "version": "1.2.84",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli-set-front",
6
6
  "keywords": [
@@ -41,7 +41,7 @@
41
41
  "@babel/plugin-proposal-decorators": "^7.29.0",
42
42
  "@babel/plugin-transform-class-properties": "^7.28.6",
43
43
  "@babel/plugin-transform-typescript": "^7.28.6",
44
- "@cabloy/cli": "^3.1.18",
44
+ "@cabloy/cli": "^3.1.23",
45
45
  "@cabloy/extend": "^3.2.8",
46
46
  "@cabloy/module-info": "^2.0.0",
47
47
  "@cabloy/openapi-typescript": "^7.9.2",
@@ -32,12 +32,8 @@ export class CliCreateBean extends BeanCliBase {
32
32
  await super.execute();
33
33
  // module name/info
34
34
  const moduleName = argv.module;
35
- argv.moduleInfo = this.helper.parseModuleInfo(moduleName);
36
- // check if exists
37
- const _module = this.helper.findModule(moduleName);
38
- if (!_module) {
39
- throw new Error(`module does not exist: ${moduleName}`);
40
- }
35
+ argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
36
+ const _module = this.helper.findModuleCanonical(moduleName);
41
37
  // target dir
42
38
  const targetDir = await this.helper.ensureDir(_module.root);
43
39
  // scene name
@@ -23,12 +23,8 @@ export class CliCreateMock extends BeanCliBase {
23
23
  await super.execute();
24
24
  // module name/info
25
25
  const moduleName = argv.module;
26
- argv.moduleInfo = this.helper.parseModuleInfo(moduleName);
27
- // check if exists
28
- const _module = this.helper.findModule(moduleName);
29
- if (!_module) {
30
- throw new Error(`module does not exist: ${moduleName}`);
31
- }
26
+ argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
27
+ const _module = this.helper.findModuleCanonical(moduleName);
32
28
  // target dir
33
29
  const targetDir = await this.helper.ensureDir(_module.root);
34
30
  // mockName
@@ -25,12 +25,9 @@ export class CliCreateModule extends BeanCliBase {
25
25
  // suite name/info
26
26
  const suiteName = argv.suite;
27
27
  if (suiteName) {
28
- argv.suiteInfo = this.helper.parseSuiteInfo(suiteName);
28
+ argv.suiteInfo = this.helper.parseSuiteInfoCanonical(suiteName);
29
29
  // check if exists
30
- argv._suite = this.helper.findSuite(suiteName);
31
- if (!argv._suite) {
32
- throw new Error(`suite does not exist: ${suiteName}`);
33
- }
30
+ argv._suite = this.helper.findSuiteCanonical(suiteName);
34
31
  }
35
32
  // nameMeta
36
33
  const nameMeta = this.helper.parseNameMeta(argv.name);
@@ -38,7 +35,7 @@ export class CliCreateModule extends BeanCliBase {
38
35
  argv.name = nameMeta.short;
39
36
  // module name/info
40
37
  const moduleName = argv.name;
41
- argv.moduleInfo = this.helper.parseModuleInfo(moduleName);
38
+ argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
42
39
  argv.relativeNameCapitalize = this.helper.stringToCapitalize(argv.moduleInfo.relativeName, '-');
43
40
  // check if exists
44
41
  const _module = this.helper.findModule(moduleName);
@@ -24,7 +24,7 @@ export class CliCreateSuite extends BeanCliBase {
24
24
  argv.name = nameMeta.short;
25
25
  // suite name/info
26
26
  const suiteName = argv.name;
27
- argv.suiteInfo = this.helper.parseSuiteInfo(suiteName);
27
+ argv.suiteInfo = this.helper.parseSuiteInfoCanonical(suiteName);
28
28
  // check if exists
29
29
  const _suite = this.helper.findSuite(suiteName);
30
30
  if (_suite) {