vona-cli-set-api 1.1.110 → 1.1.117
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/cli/templates/create/module/boilerplate/_package.json +1 -1
- package/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoBaseName%>.tsx_ +18 -0
- package/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoMutateName%>.tsx_ +17 -0
- package/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoResItemName%>.tsx_ +60 -0
- package/cli/templates/tools/masterDetail/boilerplate/dto/<%=argv.detailDtoViewName%>.tsx_ +17 -0
- package/dist/index.js +640 -101
- package/dist/lib/bean/cli.tools.masterDetail.d.ts +94 -0
- package/dist/lib/beans.d.ts +2 -0
- package/dist/lib/command/tools.masterDetail.d.ts +78 -0
- package/dist/lib/commands.d.ts +77 -0
- package/package.json +5 -5
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"tsc:publish": "npm run clean && node <%=argv.suite?'../../../../../':'../../../'%>packages-cli/cli/src/bin/vona.ts :bin:buildModule --sourcemap && tsc -p tsconfig.build.json",
|
|
26
26
|
"prepublishOnly": "npm run tsc:publish",
|
|
27
27
|
"prepack": "clean-package",
|
|
28
|
-
"postpack": "clean-package restore
|
|
28
|
+
"postpack": "clean-package restore"
|
|
29
29
|
},
|
|
30
30
|
"clean-package": {
|
|
31
31
|
"indent": 2,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IDecoratorDtoOptions } from 'vona-module-a-web';
|
|
2
|
+
|
|
3
|
+
import { $makeMetadata } from 'vona-module-a-openapiutils';
|
|
4
|
+
import { $Dto } from 'vona-module-a-orm';
|
|
5
|
+
import { Dto } from 'vona-module-a-web';
|
|
6
|
+
import { Model<%=argv.detailResourceNameCapitalize%> } from '<%=argv.detailPackageName%>';
|
|
7
|
+
import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
|
|
8
|
+
|
|
9
|
+
export interface IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%> extends IDecoratorDtoOptions {}
|
|
10
|
+
|
|
11
|
+
@Dto<IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%>>({
|
|
12
|
+
fields: {
|
|
13
|
+
id: $makeMetadata(ZovaRender.visible(false)),
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
export class Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%> extends $Dto.get(() => Model<%=argv.detailResourceNameCapitalize%>, {
|
|
17
|
+
columns: ['id', 'deleted', 'name', 'description'],
|
|
18
|
+
}) {}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IDecoratorDtoOptions } from 'vona-module-a-web';
|
|
2
|
+
|
|
3
|
+
import { $Dto } from 'vona-module-a-orm';
|
|
4
|
+
import { Dto } from 'vona-module-a-web';
|
|
5
|
+
import { Model<%=argv.detailResourceNameCapitalize%> } from '<%=argv.detailPackageName%>';
|
|
6
|
+
import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
|
|
7
|
+
|
|
8
|
+
import { Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%> } from './<%=argv.detailDtoBaseName%>.tsx';
|
|
9
|
+
|
|
10
|
+
export interface IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoMutateName)%> extends IDecoratorDtoOptions {}
|
|
11
|
+
|
|
12
|
+
@Dto<IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoMutateName)%>>({
|
|
13
|
+
blocks: [ZovaRender.block('basic-details:blockForm')],
|
|
14
|
+
})
|
|
15
|
+
export class Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoMutateName)%> extends $Dto.mutate(() => Model<%=argv.detailResourceNameCapitalize%>, {
|
|
16
|
+
dtoClass: Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%>,
|
|
17
|
+
}) {}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { IDecoratorDtoOptions } from 'vona-module-a-web';
|
|
2
|
+
|
|
3
|
+
import { $makeMetadata, Api, v } from 'vona-module-a-openapiutils';
|
|
4
|
+
import { $Dto } from 'vona-module-a-orm';
|
|
5
|
+
import { Dto } from 'vona-module-a-web';
|
|
6
|
+
import { Model<%=argv.detailResourceNameCapitalize%> } from '<%=argv.detailPackageName%>';
|
|
7
|
+
import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
|
|
8
|
+
|
|
9
|
+
import { $locale } from '../.metadata/locales.ts';
|
|
10
|
+
import { Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%> } from './<%=argv.detailDtoBaseName%>.tsx';
|
|
11
|
+
|
|
12
|
+
export interface IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoResItemName)%> extends IDecoratorDtoOptions {}
|
|
13
|
+
|
|
14
|
+
@Dto<IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoResItemName)%>>({
|
|
15
|
+
blocks: [
|
|
16
|
+
ZovaRender.block('basic-details:blockDetails', {
|
|
17
|
+
blocks: [
|
|
18
|
+
ZovaRender.block('basic-details:blockToolbarBulk', {
|
|
19
|
+
actions: [
|
|
20
|
+
ZovaRender.detailsActionBulk('basic-details:actionCreate', {
|
|
21
|
+
dialogOptions: { title: $locale('Add<%=argv.detailDialogTitleCapitalize%>') },
|
|
22
|
+
permission: { formScene: ['create', 'edit'] },
|
|
23
|
+
}),
|
|
24
|
+
],
|
|
25
|
+
}),
|
|
26
|
+
ZovaRender.block('basic-details:blockTable'),
|
|
27
|
+
],
|
|
28
|
+
}),
|
|
29
|
+
],
|
|
30
|
+
fields: {
|
|
31
|
+
name: $makeMetadata(
|
|
32
|
+
ZovaRender.cell('basic-details:actionView', {
|
|
33
|
+
dialogOptions: { title: $locale('View<%=argv.detailDialogTitleCapitalize%>') },
|
|
34
|
+
}),
|
|
35
|
+
),
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
export class Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoResItemName)%> extends $Dto.get(() => Model<%=argv.detailResourceNameCapitalize%>, {
|
|
39
|
+
dtoClass: Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%>,
|
|
40
|
+
}) {
|
|
41
|
+
@Api.field(v.title('#'), ZovaRender.order(1, 'core'), ZovaRender.cell('basic-details:lineNumber'))
|
|
42
|
+
_lineNumber?: number;
|
|
43
|
+
|
|
44
|
+
@Api.field(
|
|
45
|
+
v.title($locale('Operations')),
|
|
46
|
+
ZovaRender.order(1, 'max'),
|
|
47
|
+
ZovaRender.cell('basic-details:actionOperationsRow', {
|
|
48
|
+
actions: [
|
|
49
|
+
ZovaRender.detailsActionRow('basic-details:actionUpdate', {
|
|
50
|
+
dialogOptions: { title: $locale('Edit<%=argv.detailDialogTitleCapitalize%>') },
|
|
51
|
+
permission: { formScene: ['create', 'edit'] },
|
|
52
|
+
}),
|
|
53
|
+
ZovaRender.detailsActionRow('basic-details:actionDelete', {
|
|
54
|
+
permission: { formScene: ['create', 'edit'] },
|
|
55
|
+
}),
|
|
56
|
+
],
|
|
57
|
+
}),
|
|
58
|
+
)
|
|
59
|
+
_operationsRow?: unknown;
|
|
60
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IDecoratorDtoOptions } from 'vona-module-a-web';
|
|
2
|
+
|
|
3
|
+
import { $Dto } from 'vona-module-a-orm';
|
|
4
|
+
import { Dto } from 'vona-module-a-web';
|
|
5
|
+
import { Model<%=argv.detailResourceNameCapitalize%> } from '<%=argv.detailPackageName%>';
|
|
6
|
+
import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
|
|
7
|
+
|
|
8
|
+
import { Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%> } from './<%=argv.detailDtoBaseName%>.tsx';
|
|
9
|
+
|
|
10
|
+
export interface IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoViewName)%> extends IDecoratorDtoOptions {}
|
|
11
|
+
|
|
12
|
+
@Dto<IDtoOptions<%=cli.helper.firstCharToUpperCase(argv.detailDtoViewName)%>>({
|
|
13
|
+
blocks: [ZovaRender.block('basic-details:blockForm')],
|
|
14
|
+
})
|
|
15
|
+
export class Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoViewName)%> extends $Dto.get(() => Model<%=argv.detailResourceNameCapitalize%>, {
|
|
16
|
+
dtoClass: Dto<%=cli.helper.firstCharToUpperCase(argv.detailDtoBaseName)%>,
|
|
17
|
+
}) {}
|
package/dist/index.js
CHANGED
|
@@ -1067,12 +1067,8 @@ class CliCreateBean extends BeanCliBase {
|
|
|
1067
1067
|
argv.ssrSiteRestNpmWeb = fs.existsSync(path.join(argv.projectPath, 'src/suite/cabloy-start')) ? 'zova-rest-cabloy-start-web' : 'zova-rest-cabloy-basic-web';
|
|
1068
1068
|
// module name/info
|
|
1069
1069
|
const moduleName = argv.module;
|
|
1070
|
-
argv.moduleInfo = this.helper.
|
|
1071
|
-
|
|
1072
|
-
const _module = this.helper.findModule(moduleName);
|
|
1073
|
-
if (!_module) {
|
|
1074
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1075
|
-
}
|
|
1070
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1071
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1076
1072
|
// target dir
|
|
1077
1073
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1078
1074
|
// scene name
|
|
@@ -1166,12 +1162,9 @@ class CliCreateModule extends BeanCliBase {
|
|
|
1166
1162
|
// suite name/info
|
|
1167
1163
|
const suiteName = argv.suite;
|
|
1168
1164
|
if (suiteName) {
|
|
1169
|
-
argv.suiteInfo = this.helper.
|
|
1165
|
+
argv.suiteInfo = this.helper.parseSuiteInfoCanonical(suiteName);
|
|
1170
1166
|
// check if exists
|
|
1171
|
-
argv._suite = this.helper.
|
|
1172
|
-
if (!argv._suite) {
|
|
1173
|
-
throw new Error(`suite does not exist: ${suiteName}`);
|
|
1174
|
-
}
|
|
1167
|
+
argv._suite = this.helper.findSuiteCanonical(suiteName);
|
|
1175
1168
|
}
|
|
1176
1169
|
// nameMeta
|
|
1177
1170
|
const nameMeta = this.helper.parseNameMeta(argv.name);
|
|
@@ -1179,7 +1172,7 @@ class CliCreateModule extends BeanCliBase {
|
|
|
1179
1172
|
argv.name = nameMeta.short;
|
|
1180
1173
|
// module name/info
|
|
1181
1174
|
const moduleName = argv.name;
|
|
1182
|
-
argv.moduleInfo = this.helper.
|
|
1175
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1183
1176
|
argv.relativeNameCapitalize = this.helper.stringToCapitalize(argv.moduleInfo.relativeName, '-');
|
|
1184
1177
|
// check if exists
|
|
1185
1178
|
const _module = this.helper.findModule(moduleName);
|
|
@@ -1246,7 +1239,7 @@ class CliCreateSuite extends BeanCliBase {
|
|
|
1246
1239
|
argv.name = nameMeta.short;
|
|
1247
1240
|
// suite name/info
|
|
1248
1241
|
const suiteName = argv.name;
|
|
1249
|
-
argv.suiteInfo = this.helper.
|
|
1242
|
+
argv.suiteInfo = this.helper.parseSuiteInfoCanonical(suiteName);
|
|
1250
1243
|
// check if exists
|
|
1251
1244
|
const _suite = this.helper.findSuite(suiteName);
|
|
1252
1245
|
if (_suite) {
|
|
@@ -1274,12 +1267,8 @@ class CliCreateTest extends BeanCliBase {
|
|
|
1274
1267
|
await super.execute();
|
|
1275
1268
|
// module name/info
|
|
1276
1269
|
const moduleName = argv.module;
|
|
1277
|
-
argv.moduleInfo = this.helper.
|
|
1278
|
-
|
|
1279
|
-
const _module = this.helper.findModule(moduleName);
|
|
1280
|
-
if (!_module) {
|
|
1281
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1282
|
-
}
|
|
1270
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1271
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1283
1272
|
// target dir
|
|
1284
1273
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1285
1274
|
// name
|
|
@@ -1441,12 +1430,8 @@ class CliInitAsset extends BeanCliBase {
|
|
|
1441
1430
|
await super.execute();
|
|
1442
1431
|
// module name/info
|
|
1443
1432
|
const moduleName = argv.module;
|
|
1444
|
-
argv.moduleInfo = this.helper.
|
|
1445
|
-
|
|
1446
|
-
const _module = this.helper.findModule(moduleName);
|
|
1447
|
-
if (!_module) {
|
|
1448
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1449
|
-
}
|
|
1433
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1434
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1450
1435
|
// target dir
|
|
1451
1436
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1452
1437
|
// scene
|
|
@@ -1470,12 +1455,8 @@ class CliInitConfig extends BeanCliBase {
|
|
|
1470
1455
|
// module name/info
|
|
1471
1456
|
const moduleName = argv._[0];
|
|
1472
1457
|
if (!moduleName) return;
|
|
1473
|
-
argv.moduleInfo = this.helper.
|
|
1474
|
-
|
|
1475
|
-
const _module = this.helper.findModule(moduleName);
|
|
1476
|
-
if (!_module) {
|
|
1477
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1478
|
-
}
|
|
1458
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1459
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1479
1460
|
// target dir
|
|
1480
1461
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1481
1462
|
const configFile = path.join(targetDir, 'src/config/config.ts');
|
|
@@ -1508,12 +1489,8 @@ class CliInitConstant extends BeanCliBase {
|
|
|
1508
1489
|
// module name/info
|
|
1509
1490
|
const moduleName = argv._[0];
|
|
1510
1491
|
if (!moduleName) return;
|
|
1511
|
-
argv.moduleInfo = this.helper.
|
|
1512
|
-
|
|
1513
|
-
const _module = this.helper.findModule(moduleName);
|
|
1514
|
-
if (!_module) {
|
|
1515
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1516
|
-
}
|
|
1492
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1493
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1517
1494
|
// target dir
|
|
1518
1495
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1519
1496
|
const constantFile = path.join(targetDir, 'src/config/constants.ts');
|
|
@@ -1546,12 +1523,8 @@ class CliInitError extends BeanCliBase {
|
|
|
1546
1523
|
// module name/info
|
|
1547
1524
|
const moduleName = argv._[0];
|
|
1548
1525
|
if (!moduleName) return;
|
|
1549
|
-
argv.moduleInfo = this.helper.
|
|
1550
|
-
|
|
1551
|
-
const _module = this.helper.findModule(moduleName);
|
|
1552
|
-
if (!_module) {
|
|
1553
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1554
|
-
}
|
|
1526
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1527
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1555
1528
|
// target dir
|
|
1556
1529
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1557
1530
|
const errorFile = path.join(targetDir, 'src/config/errors.ts');
|
|
@@ -1595,12 +1568,8 @@ class CliInitLib extends BeanCliBase {
|
|
|
1595
1568
|
// module name/info
|
|
1596
1569
|
const moduleName = argv._[0];
|
|
1597
1570
|
if (!moduleName) return;
|
|
1598
|
-
argv.moduleInfo = this.helper.
|
|
1599
|
-
|
|
1600
|
-
const _module = this.helper.findModule(moduleName);
|
|
1601
|
-
if (!_module) {
|
|
1602
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1603
|
-
}
|
|
1571
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1572
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1604
1573
|
// target dir
|
|
1605
1574
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1606
1575
|
const mainFile = path.join(targetDir, 'src/lib/index.ts');
|
|
@@ -1633,12 +1602,8 @@ class CliInitLocale extends BeanCliBase {
|
|
|
1633
1602
|
// module name/info
|
|
1634
1603
|
const moduleName = argv._[0];
|
|
1635
1604
|
if (!moduleName) return;
|
|
1636
|
-
argv.moduleInfo = this.helper.
|
|
1637
|
-
|
|
1638
|
-
const _module = this.helper.findModule(moduleName);
|
|
1639
|
-
if (!_module) {
|
|
1640
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1641
|
-
}
|
|
1605
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1606
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1642
1607
|
// target dir
|
|
1643
1608
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1644
1609
|
const localeFile = path.join(targetDir, 'src/config/locale');
|
|
@@ -1671,12 +1636,8 @@ class CliInitMain extends BeanCliBase {
|
|
|
1671
1636
|
// module name/info
|
|
1672
1637
|
const moduleName = argv._[0];
|
|
1673
1638
|
if (!moduleName) return;
|
|
1674
|
-
argv.moduleInfo = this.helper.
|
|
1675
|
-
|
|
1676
|
-
const _module = this.helper.findModule(moduleName);
|
|
1677
|
-
if (!_module) {
|
|
1678
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1679
|
-
}
|
|
1639
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1640
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1680
1641
|
// target dir
|
|
1681
1642
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1682
1643
|
const mainFile = path.join(targetDir, 'src/main.ts');
|
|
@@ -1709,12 +1670,8 @@ class CliInitMonkey extends BeanCliBase {
|
|
|
1709
1670
|
// module name/info
|
|
1710
1671
|
const moduleName = argv._[0];
|
|
1711
1672
|
if (!moduleName) return;
|
|
1712
|
-
argv.moduleInfo = this.helper.
|
|
1713
|
-
|
|
1714
|
-
const _module = this.helper.findModule(moduleName);
|
|
1715
|
-
if (!_module) {
|
|
1716
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1717
|
-
}
|
|
1673
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1674
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1718
1675
|
// target dir
|
|
1719
1676
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1720
1677
|
const monkeyFile = path.join(targetDir, 'src/monkey.ts');
|
|
@@ -1771,12 +1728,8 @@ class CliInitStatic extends BeanCliBase {
|
|
|
1771
1728
|
// module name/info
|
|
1772
1729
|
const moduleName = argv._[0];
|
|
1773
1730
|
if (!moduleName) return;
|
|
1774
|
-
argv.moduleInfo = this.helper.
|
|
1775
|
-
|
|
1776
|
-
const _module = this.helper.findModule(moduleName);
|
|
1777
|
-
if (!_module) {
|
|
1778
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1779
|
-
}
|
|
1731
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1732
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1780
1733
|
// target dir
|
|
1781
1734
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1782
1735
|
const staticDir = path.join(targetDir, 'assets/static');
|
|
@@ -1807,12 +1760,8 @@ class CliInitTypes extends BeanCliBase {
|
|
|
1807
1760
|
// module name/info
|
|
1808
1761
|
const moduleName = argv._[0];
|
|
1809
1762
|
if (!moduleName) return;
|
|
1810
|
-
argv.moduleInfo = this.helper.
|
|
1811
|
-
|
|
1812
|
-
const _module = this.helper.findModule(moduleName);
|
|
1813
|
-
if (!_module) {
|
|
1814
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1815
|
-
}
|
|
1763
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1764
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1816
1765
|
// target dir
|
|
1817
1766
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1818
1767
|
const mainFile = path.join(targetDir, 'src/types/index.ts');
|
|
@@ -1849,12 +1798,8 @@ class CliToolsCrud extends BeanCliBase {
|
|
|
1849
1798
|
argv.ssrSiteGroupName = isCabloyStart ? 'start-siteadmin:management' : 'basic-siteadmin:management';
|
|
1850
1799
|
// module name/info
|
|
1851
1800
|
const moduleName = argv.module;
|
|
1852
|
-
argv.moduleInfo = this.helper.
|
|
1853
|
-
|
|
1854
|
-
const _module = this.helper.findModule(moduleName);
|
|
1855
|
-
if (!_module) {
|
|
1856
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1857
|
-
}
|
|
1801
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1802
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1858
1803
|
// target dir
|
|
1859
1804
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1860
1805
|
// resourceName
|
|
@@ -1895,12 +1840,8 @@ class CliToolsCrudBasic extends BeanCliBase {
|
|
|
1895
1840
|
await super.execute();
|
|
1896
1841
|
// module name/info
|
|
1897
1842
|
const moduleName = argv.module;
|
|
1898
|
-
argv.moduleInfo = this.helper.
|
|
1899
|
-
|
|
1900
|
-
const _module = this.helper.findModule(moduleName);
|
|
1901
|
-
if (!_module) {
|
|
1902
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1903
|
-
}
|
|
1843
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1844
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1904
1845
|
// target dir
|
|
1905
1846
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1906
1847
|
// resourceName
|
|
@@ -1939,12 +1880,8 @@ class CliToolsCrudStart extends BeanCliBase {
|
|
|
1939
1880
|
await super.execute();
|
|
1940
1881
|
// module name/info
|
|
1941
1882
|
const moduleName = argv.module;
|
|
1942
|
-
argv.moduleInfo = this.helper.
|
|
1943
|
-
|
|
1944
|
-
const _module = this.helper.findModule(moduleName);
|
|
1945
|
-
if (!_module) {
|
|
1946
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1947
|
-
}
|
|
1883
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1884
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1948
1885
|
// target dir
|
|
1949
1886
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1950
1887
|
// resourceName
|
|
@@ -2049,6 +1986,529 @@ class CliToolsDeps extends BeanCliBase {
|
|
|
2049
1986
|
}
|
|
2050
1987
|
}
|
|
2051
1988
|
|
|
1989
|
+
class CliToolsMasterDetail extends BeanCliBase {
|
|
1990
|
+
async execute() {
|
|
1991
|
+
await super.execute();
|
|
1992
|
+
this._prepareArgv();
|
|
1993
|
+
await this._ensureDetailModule();
|
|
1994
|
+
await this._ensureDetailResourceShape();
|
|
1995
|
+
await this._patchDetailModule();
|
|
1996
|
+
await this._renderMasterDetailDtos();
|
|
1997
|
+
await this._patchMasterModule();
|
|
1998
|
+
await this._refreshMetadata();
|
|
1999
|
+
}
|
|
2000
|
+
_prepareArgv() {
|
|
2001
|
+
const {
|
|
2002
|
+
argv
|
|
2003
|
+
} = this.context;
|
|
2004
|
+
argv.detailMode = argv.detailMode || 'aggregate';
|
|
2005
|
+
if (argv.detailMode !== 'aggregate' && argv.detailMode !== 'standalone') {
|
|
2006
|
+
throw new Error(`mode is not valid: ${argv.detailMode}`);
|
|
2007
|
+
}
|
|
2008
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(argv.module, 'master module');
|
|
2009
|
+
const _module = this.helper.findModuleCanonical(argv.module, 'master module');
|
|
2010
|
+
argv._module = _module;
|
|
2011
|
+
argv.resourceNameCapitalize = this.helper.firstCharToUpperCase(argv.resourceName);
|
|
2012
|
+
argv.detailModuleInfo = this.helper.parseModuleInfoCanonical(argv.detailModule, 'detail module');
|
|
2013
|
+
argv._detailModule = this.helper.findModule(argv.detailModule);
|
|
2014
|
+
argv.detailResourceNameCapitalize = this.helper.firstCharToUpperCase(argv.detailResourceName);
|
|
2015
|
+
argv.relationName = argv.relationName || `${argv.detailResourceName}s`;
|
|
2016
|
+
argv.relationNameCapitalize = this.helper.firstCharToUpperCase(argv.relationName);
|
|
2017
|
+
argv.fk = argv.fk || `${argv.resourceName}Id`;
|
|
2018
|
+
argv.detailPackageName = `vona-module-${argv.detailModuleInfo.relativeName}`;
|
|
2019
|
+
argv.detailModuleCapitalize = this.helper.stringToCapitalize(argv.detailModuleInfo.relativeName, '-');
|
|
2020
|
+
argv.detailDtoBaseName = `detail${argv.detailResourceNameCapitalize}Base`;
|
|
2021
|
+
argv.detailDtoMutateName = `detail${argv.detailResourceNameCapitalize}Mutate`;
|
|
2022
|
+
argv.detailDtoViewName = `detail${argv.detailResourceNameCapitalize}View`;
|
|
2023
|
+
argv.detailDtoResItemName = `detail${argv.detailResourceNameCapitalize}ResItem`;
|
|
2024
|
+
argv.detailFieldPrivateName = `_${argv.relationName}`;
|
|
2025
|
+
argv.detailDialogTitleCapitalize = argv.detailModuleCapitalize;
|
|
2026
|
+
}
|
|
2027
|
+
async _ensureDetailModule() {
|
|
2028
|
+
const {
|
|
2029
|
+
argv
|
|
2030
|
+
} = this.context;
|
|
2031
|
+
if (argv._detailModule) return;
|
|
2032
|
+
const args = [':create:module', argv.detailModule, '--nometadata'];
|
|
2033
|
+
if (argv._module.suite) {
|
|
2034
|
+
args.push(`--suite=${argv._module.suite}`);
|
|
2035
|
+
}
|
|
2036
|
+
await this.helper.invokeCli(args, {
|
|
2037
|
+
cwd: argv.projectPath
|
|
2038
|
+
});
|
|
2039
|
+
argv.createdDetailModule = true;
|
|
2040
|
+
argv._detailModule = this.helper.findModule(argv.detailModule);
|
|
2041
|
+
if (!argv._detailModule) {
|
|
2042
|
+
const root = this._resolveCreatedDetailModuleRoot();
|
|
2043
|
+
argv._detailModule = {
|
|
2044
|
+
name: argv.detailModuleInfo.relativeName,
|
|
2045
|
+
info: argv.detailModuleInfo,
|
|
2046
|
+
root,
|
|
2047
|
+
pkg: path.join(root, 'package.json'),
|
|
2048
|
+
package: await this.helper.loadJSONFile(path.join(root, 'package.json')),
|
|
2049
|
+
suite: argv._module.suite
|
|
2050
|
+
};
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
async _ensureDetailResourceShape() {
|
|
2054
|
+
const {
|
|
2055
|
+
argv
|
|
2056
|
+
} = this.context;
|
|
2057
|
+
const {
|
|
2058
|
+
hasCoreDetailFiles,
|
|
2059
|
+
hasStandaloneSurface
|
|
2060
|
+
} = this._detailModuleShape();
|
|
2061
|
+
if (!hasCoreDetailFiles) {
|
|
2062
|
+
await this._createDetailCoreResource();
|
|
2063
|
+
argv.createdDetailResource = true;
|
|
2064
|
+
}
|
|
2065
|
+
if (argv.detailMode === 'aggregate') {
|
|
2066
|
+
this._handleAggregateDetailMode(hasStandaloneSurface);
|
|
2067
|
+
return;
|
|
2068
|
+
}
|
|
2069
|
+
this._handleStandaloneDetailMode();
|
|
2070
|
+
}
|
|
2071
|
+
async _patchDetailModule() {
|
|
2072
|
+
await this._runSequential(this._detailPatchTasks());
|
|
2073
|
+
}
|
|
2074
|
+
async _patchDetailEntity() {
|
|
2075
|
+
const {
|
|
2076
|
+
argv
|
|
2077
|
+
} = this.context;
|
|
2078
|
+
await this._patchFileContent({
|
|
2079
|
+
fileName: this._detailPaths().entity,
|
|
2080
|
+
existsNeedle: `${argv.fk}: TableIdentity;`,
|
|
2081
|
+
patch: (content, fileName) => {
|
|
2082
|
+
content = this._patchDetailEntityImport(content);
|
|
2083
|
+
return this._patchDetailEntityField(content, fileName);
|
|
2084
|
+
}
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
_patchDetailEntityImport(content) {
|
|
2088
|
+
if (!content.includes("import type { TableIdentity } from 'table-identity';")) {
|
|
2089
|
+
content = `import type { TableIdentity } from 'table-identity';\n${content}`;
|
|
2090
|
+
}
|
|
2091
|
+
return content;
|
|
2092
|
+
}
|
|
2093
|
+
_patchDetailEntityField(content, fileName) {
|
|
2094
|
+
const {
|
|
2095
|
+
argv
|
|
2096
|
+
} = this.context;
|
|
2097
|
+
const marker = `export class Entity${argv.detailResourceNameCapitalize} extends EntityBase {\n`;
|
|
2098
|
+
if (!content.includes(marker)) {
|
|
2099
|
+
throw new Error(`detail entity is not in the expected shape: ${fileName}`);
|
|
2100
|
+
}
|
|
2101
|
+
const fieldCode = ` @Api.field(v.required(), ZovaRender.visible(false))\n ${argv.fk}: TableIdentity;\n\n`;
|
|
2102
|
+
return content.replace(marker, `${marker}${fieldCode}`);
|
|
2103
|
+
}
|
|
2104
|
+
async _patchDetailMetaVersion() {
|
|
2105
|
+
const {
|
|
2106
|
+
argv
|
|
2107
|
+
} = this.context;
|
|
2108
|
+
await this._patchFileByMarker({
|
|
2109
|
+
fileName: this._detailPaths().metaVersion,
|
|
2110
|
+
existsNeedle: `entity${argv.detailResourceNameCapitalize}.${argv.fk}`,
|
|
2111
|
+
marker: ' table.basicFields();\n',
|
|
2112
|
+
line: this._detailMetaVersionLine(),
|
|
2113
|
+
shapeName: 'detail meta.version'
|
|
2114
|
+
});
|
|
2115
|
+
}
|
|
2116
|
+
async _patchDetailMetaIndex() {
|
|
2117
|
+
const {
|
|
2118
|
+
argv
|
|
2119
|
+
} = this.context;
|
|
2120
|
+
await this._patchFileByMarker({
|
|
2121
|
+
fileName: this._detailPaths().metaIndex,
|
|
2122
|
+
existsNeedle: `'${argv.fk}'`,
|
|
2123
|
+
marker: ' indexes: {\n',
|
|
2124
|
+
line: this._detailMetaIndexLine(),
|
|
2125
|
+
shapeName: 'detail meta.index'
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
_detailMetaVersionLine() {
|
|
2129
|
+
const {
|
|
2130
|
+
argv
|
|
2131
|
+
} = this.context;
|
|
2132
|
+
return ` table.tableIdentity(entity${argv.detailResourceNameCapitalize}.${argv.fk}).comment(entity${argv.detailResourceNameCapitalize}.$comment.${argv.fk});\n`;
|
|
2133
|
+
}
|
|
2134
|
+
_detailMetaIndexLine() {
|
|
2135
|
+
const {
|
|
2136
|
+
argv
|
|
2137
|
+
} = this.context;
|
|
2138
|
+
return ` ...$tableColumns('${this.helper.combineModuleNameAndResource(argv.detailModuleInfo.relativeName, argv.detailResourceName)}', '${argv.fk}'),\n`;
|
|
2139
|
+
}
|
|
2140
|
+
async _patchFileByMarker({
|
|
2141
|
+
fileName,
|
|
2142
|
+
existsNeedle,
|
|
2143
|
+
marker,
|
|
2144
|
+
line,
|
|
2145
|
+
shapeName
|
|
2146
|
+
}) {
|
|
2147
|
+
let content = this._readFile(fileName);
|
|
2148
|
+
if (content.includes(existsNeedle)) return;
|
|
2149
|
+
if (!content.includes(marker)) {
|
|
2150
|
+
throw new Error(`${shapeName} is not in the expected shape: ${fileName}`);
|
|
2151
|
+
}
|
|
2152
|
+
content = content.replace(marker, `${marker}${line}`);
|
|
2153
|
+
await this._saveFile(fileName, content);
|
|
2154
|
+
}
|
|
2155
|
+
async _patchFileContent({
|
|
2156
|
+
fileName,
|
|
2157
|
+
existsNeedle,
|
|
2158
|
+
patch
|
|
2159
|
+
}) {
|
|
2160
|
+
let content = this._readFile(fileName);
|
|
2161
|
+
if (content.includes(existsNeedle)) return;
|
|
2162
|
+
content = patch(content, fileName);
|
|
2163
|
+
await this._saveFile(fileName, content);
|
|
2164
|
+
}
|
|
2165
|
+
async _renderMasterDetailDtos() {
|
|
2166
|
+
await this.helper.ensureDir(this._masterPaths().dtoDir);
|
|
2167
|
+
for (const [dtoBaseName, templateBaseName] of this._detailDtoTemplates()) {
|
|
2168
|
+
await this._renderMasterDetailDtoFile(dtoBaseName, templateBaseName);
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
async _patchMasterModule() {
|
|
2172
|
+
await this._runSequential(this._masterPatchTasks());
|
|
2173
|
+
}
|
|
2174
|
+
_detailPatchTasks() {
|
|
2175
|
+
return [() => this._patchDetailEntity(), () => this._patchDetailMetaVersion(), () => this._patchDetailMetaIndex()];
|
|
2176
|
+
}
|
|
2177
|
+
_masterPatchTasks() {
|
|
2178
|
+
return [() => this._patchMasterModel(), () => this._patchMasterService(), ...this._masterDtoScenes().map(scene => () => this._patchMasterDto(scene)), ...this._masterLocales().map(locale => () => this._patchMasterLocale(locale))];
|
|
2179
|
+
}
|
|
2180
|
+
async _runSequential(tasks) {
|
|
2181
|
+
for (const task of tasks) {
|
|
2182
|
+
await task();
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
async _patchMasterModel() {
|
|
2186
|
+
const {
|
|
2187
|
+
argv
|
|
2188
|
+
} = this.context;
|
|
2189
|
+
const fileName = this._masterPaths().model;
|
|
2190
|
+
let content = this._readFile(fileName);
|
|
2191
|
+
if (content.includes(`${argv.relationName}: $relation.hasMany(`)) return;
|
|
2192
|
+
content = this._patchMasterModelImport(content, fileName);
|
|
2193
|
+
content = this._patchMasterModelRelations(content, fileName);
|
|
2194
|
+
await this._saveFile(fileName, content);
|
|
2195
|
+
}
|
|
2196
|
+
async _patchMasterService() {
|
|
2197
|
+
const {
|
|
2198
|
+
argv
|
|
2199
|
+
} = this.context;
|
|
2200
|
+
const fileName = this._masterPaths().service;
|
|
2201
|
+
let content = this._readFile(fileName);
|
|
2202
|
+
if (content.includes(`include: { ${argv.relationName}: true }`)) return;
|
|
2203
|
+
for (const [search, replacement] of this._masterServiceIncludeReplacements()) {
|
|
2204
|
+
content = this._replaceStrict(content, search, replacement, fileName);
|
|
2205
|
+
}
|
|
2206
|
+
await this._saveFile(fileName, content);
|
|
2207
|
+
}
|
|
2208
|
+
_patchMasterModelImport(content, fileName) {
|
|
2209
|
+
if (content.includes("import { $relation, BeanModelBase, Model } from 'vona-module-a-orm';")) {
|
|
2210
|
+
return content;
|
|
2211
|
+
}
|
|
2212
|
+
return this._replaceStrict(content, "import { BeanModelBase, Model } from 'vona-module-a-orm';", "import { $relation, BeanModelBase, Model } from 'vona-module-a-orm';", fileName);
|
|
2213
|
+
}
|
|
2214
|
+
_patchMasterModelRelations(content, fileName) {
|
|
2215
|
+
const relationsBlockMarker = ' relations: {\n';
|
|
2216
|
+
if (content.includes(relationsBlockMarker)) {
|
|
2217
|
+
return content.replace(relationsBlockMarker, `${relationsBlockMarker}${this._masterModelRelationCode()}`);
|
|
2218
|
+
}
|
|
2219
|
+
return this._patchMasterModelDecorator(content, fileName);
|
|
2220
|
+
}
|
|
2221
|
+
_patchMasterModelDecorator(content, fileName) {
|
|
2222
|
+
const {
|
|
2223
|
+
argv
|
|
2224
|
+
} = this.context;
|
|
2225
|
+
const marker = `@Model<IModelOptions${argv.resourceNameCapitalize}>({ entity: Entity${argv.resourceNameCapitalize} })`;
|
|
2226
|
+
if (!content.includes(marker)) {
|
|
2227
|
+
throw new Error(`master model is not in the expected shape: ${fileName}`);
|
|
2228
|
+
}
|
|
2229
|
+
return content.replace(marker, `@Model<IModelOptions${argv.resourceNameCapitalize}>({\n entity: Entity${argv.resourceNameCapitalize},\n relations: {\n${this._masterModelRelationCode()} },\n})`);
|
|
2230
|
+
}
|
|
2231
|
+
_masterModelRelationCode() {
|
|
2232
|
+
const {
|
|
2233
|
+
argv
|
|
2234
|
+
} = this.context;
|
|
2235
|
+
return ` ${argv.relationName}: $relation.hasMany('${argv.detailModuleInfo.relativeName}:${argv.detailResourceName}', '${argv.fk}', {\n columns: ['id', 'name', 'description'],\n }),\n`;
|
|
2236
|
+
}
|
|
2237
|
+
_masterServiceIncludeReplacements() {
|
|
2238
|
+
const {
|
|
2239
|
+
argv
|
|
2240
|
+
} = this.context;
|
|
2241
|
+
return [[` return await this.scope.model.${argv.resourceName}.insert(${argv.resourceName});`, ` return await this.scope.model.${argv.resourceName}.insert(${argv.resourceName}, { include: { ${argv.relationName}: true } });`], [` return await this.scope.model.${argv.resourceName}.getById(id);`, ` return await this.scope.model.${argv.resourceName}.getById(id, { include: { ${argv.relationName}: true } });`], [` return await this.scope.model.${argv.resourceName}.updateById(id, ${argv.resourceName});`, ` return await this.scope.model.${argv.resourceName}.updateById(id, ${argv.resourceName}, {\n include: { ${argv.relationName}: true },\n });`], [` return await this.scope.model.${argv.resourceName}.deleteById(id);`, ` return await this.scope.model.${argv.resourceName}.deleteById(id, { include: { ${argv.relationName}: true } });`]];
|
|
2242
|
+
}
|
|
2243
|
+
async _patchMasterDto(scene) {
|
|
2244
|
+
const {
|
|
2245
|
+
argv
|
|
2246
|
+
} = this.context;
|
|
2247
|
+
const fileName = path.join(argv._module.root, 'src/dto', `${argv.resourceName}${scene}.tsx`);
|
|
2248
|
+
let content = this._readFile(fileName);
|
|
2249
|
+
const detailDtoResItemCapitalize = this._detailDtoResItemCapitalize();
|
|
2250
|
+
const detailDtoClassCapitalize = this._detailDtoClassCapitalize(scene);
|
|
2251
|
+
if (content.includes(`${argv.detailFieldPrivateName}?: Dto${detailDtoResItemCapitalize}[];`)) {
|
|
2252
|
+
return;
|
|
2253
|
+
}
|
|
2254
|
+
content = this._patchMasterDtoImports(content, fileName, scene, detailDtoClassCapitalize, detailDtoResItemCapitalize);
|
|
2255
|
+
content = this._patchMasterDtoFields(content, fileName, scene);
|
|
2256
|
+
content = this._patchMasterDtoClass(content, fileName, scene, detailDtoClassCapitalize, detailDtoResItemCapitalize);
|
|
2257
|
+
await this._saveFile(fileName, content);
|
|
2258
|
+
}
|
|
2259
|
+
async _patchMasterLocale(locale) {
|
|
2260
|
+
const fileName = path.join(this._masterPaths().localeDir, `${locale}.ts`);
|
|
2261
|
+
let content = this._readFile(fileName);
|
|
2262
|
+
content = this._patchLocaleAdditions(content, this._masterLocaleAdditions(locale));
|
|
2263
|
+
await this._saveFile(fileName, content);
|
|
2264
|
+
}
|
|
2265
|
+
async _refreshMetadata() {
|
|
2266
|
+
const {
|
|
2267
|
+
argv
|
|
2268
|
+
} = this.context;
|
|
2269
|
+
for (const moduleName of this._metadataModules()) {
|
|
2270
|
+
await this.helper.invokeCli([':tools:metadata', moduleName], {
|
|
2271
|
+
cwd: argv.projectPath
|
|
2272
|
+
});
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
_patchLocaleAdditions(content, additions) {
|
|
2276
|
+
for (const addition of additions) {
|
|
2277
|
+
const key = this._localeAdditionKey(addition);
|
|
2278
|
+
if (content.includes(`${key}:`)) continue;
|
|
2279
|
+
content = content.replace('};\n', ` ${addition},\n};\n`);
|
|
2280
|
+
}
|
|
2281
|
+
return content;
|
|
2282
|
+
}
|
|
2283
|
+
_localeAdditionKey(addition) {
|
|
2284
|
+
return addition.split(':')[0];
|
|
2285
|
+
}
|
|
2286
|
+
_metadataModules() {
|
|
2287
|
+
const {
|
|
2288
|
+
argv
|
|
2289
|
+
} = this.context;
|
|
2290
|
+
return [argv.detailModule, argv.module];
|
|
2291
|
+
}
|
|
2292
|
+
async _renderMasterDetailDtoFile(dtoBaseName, templateBaseName) {
|
|
2293
|
+
const targetFile = path.join(this._masterPaths().dtoDir, `${dtoBaseName}.tsx`);
|
|
2294
|
+
if (fs.existsSync(targetFile)) return;
|
|
2295
|
+
const templateFile = this.template.resolveTemplatePath(__ThisSetName__, `tools/masterDetail/boilerplate/dto/${templateBaseName}`);
|
|
2296
|
+
const templateContent = fs.readFileSync(templateFile).toString('utf8');
|
|
2297
|
+
const renderedContent = await this.template.renderContent({
|
|
2298
|
+
content: templateContent
|
|
2299
|
+
});
|
|
2300
|
+
await this._saveFile(targetFile, renderedContent);
|
|
2301
|
+
}
|
|
2302
|
+
_patchMasterDtoImports(content, fileName, scene, detailDtoClassCapitalize, detailDtoResItemCapitalize) {
|
|
2303
|
+
const {
|
|
2304
|
+
argv
|
|
2305
|
+
} = this.context;
|
|
2306
|
+
if (!content.includes("import { $makeMetadata, Api, v } from 'vona-module-a-openapiutils';")) {
|
|
2307
|
+
content = this._replaceStrict(content, "import { $Dto } from 'vona-module-a-orm';", "import { $makeMetadata, Api, v } from 'vona-module-a-openapiutils';\nimport { $Dto } from 'vona-module-a-orm';", fileName);
|
|
2308
|
+
}
|
|
2309
|
+
if (!content.includes("import { $locale } from '../.metadata/locales.ts';")) {
|
|
2310
|
+
content = this._replaceStrict(content, "import { ZovaRender } from 'zova-rest-cabloy-basic-admin';\n", "import { ZovaRender } from 'zova-rest-cabloy-basic-admin';\n\nimport { $locale } from '../.metadata/locales.ts';\n", fileName);
|
|
2311
|
+
}
|
|
2312
|
+
const importMarker = `import { Model${argv.resourceNameCapitalize} } from '../model/${argv.resourceName}.ts';\n`;
|
|
2313
|
+
if (!content.includes(`import { Dto${detailDtoClassCapitalize} } from './`)) {
|
|
2314
|
+
content = this._replaceStrict(content, importMarker, `${importMarker}${this._masterDtoDetailImports(scene, detailDtoClassCapitalize, detailDtoResItemCapitalize)}`, fileName);
|
|
2315
|
+
}
|
|
2316
|
+
return content;
|
|
2317
|
+
}
|
|
2318
|
+
_patchMasterDtoFields(content, fileName, scene) {
|
|
2319
|
+
const fieldCode = this._masterDtoFieldCode(scene);
|
|
2320
|
+
if (content.includes(' fields: {\n')) {
|
|
2321
|
+
return content.replace(' fields: {\n', ` fields: {\n${fieldCode}`);
|
|
2322
|
+
}
|
|
2323
|
+
const decoratorMarker = ' ],\n})';
|
|
2324
|
+
if (!content.includes(decoratorMarker)) {
|
|
2325
|
+
throw new Error(`master dto decorator is not in the expected shape: ${fileName}`);
|
|
2326
|
+
}
|
|
2327
|
+
return content.replace(decoratorMarker, ` ],\n fields: {\n${fieldCode} },\n})`);
|
|
2328
|
+
}
|
|
2329
|
+
_patchMasterDtoClass(content, fileName, scene, detailDtoClassCapitalize, detailDtoResItemCapitalize) {
|
|
2330
|
+
const classReplaceSource = this._masterDtoClassReplaceSource(scene);
|
|
2331
|
+
if (!content.includes(classReplaceSource)) {
|
|
2332
|
+
throw new Error(`master dto class is not in the expected generated shape: ${fileName}`);
|
|
2333
|
+
}
|
|
2334
|
+
return content.replace(classReplaceSource, this._masterDtoClassReplaceTarget(scene, detailDtoClassCapitalize, detailDtoResItemCapitalize));
|
|
2335
|
+
}
|
|
2336
|
+
_masterDtoDetailImports(scene, detailDtoClassCapitalize, detailDtoResItemCapitalize) {
|
|
2337
|
+
const {
|
|
2338
|
+
argv
|
|
2339
|
+
} = this.context;
|
|
2340
|
+
return `import { Dto${detailDtoClassCapitalize} } from './${scene === 'View' ? argv.detailDtoViewName : argv.detailDtoMutateName}.tsx';\nimport { Dto${detailDtoResItemCapitalize} } from './${argv.detailDtoResItemName}.tsx';\n`;
|
|
2341
|
+
}
|
|
2342
|
+
_masterDtoFieldCode(scene) {
|
|
2343
|
+
const {
|
|
2344
|
+
argv
|
|
2345
|
+
} = this.context;
|
|
2346
|
+
return ` ${argv.relationName}: $makeMetadata(\n v.title($locale('${argv.relationNameCapitalize}')),\n ZovaRender.order(5),\n ZovaRender.field('basic-details:formFieldDetails'),\n${scene === 'Create' ? ' v.optional(),\n' : ''} ),\n`;
|
|
2347
|
+
}
|
|
2348
|
+
_masterDtoClassReplaceSource(scene) {
|
|
2349
|
+
const {
|
|
2350
|
+
argv
|
|
2351
|
+
} = this.context;
|
|
2352
|
+
const kind = scene === 'Create' ? 'create' : scene === 'Update' ? 'update' : 'get';
|
|
2353
|
+
return `export class Dto${argv.resourceNameCapitalize}${scene} extends $Dto.${kind}(() => Model${argv.resourceNameCapitalize}) {}`;
|
|
2354
|
+
}
|
|
2355
|
+
_masterDtoClassReplaceTarget(scene, detailDtoClassCapitalize, detailDtoResItemCapitalize) {
|
|
2356
|
+
const {
|
|
2357
|
+
argv
|
|
2358
|
+
} = this.context;
|
|
2359
|
+
const kind = scene === 'Create' ? 'create' : scene === 'Update' ? 'update' : 'get';
|
|
2360
|
+
return `export class Dto${argv.resourceNameCapitalize}${scene} extends $Dto.${kind}(() => Model${argv.resourceNameCapitalize}, {\n include: { ${argv.relationName}: { dtoClass: Dto${detailDtoClassCapitalize} } },\n}) {\n @Api.field(ZovaRender.visible(false), v.optional(), v.array(Dto${detailDtoResItemCapitalize}))\n ${argv.detailFieldPrivateName}?: Dto${detailDtoResItemCapitalize}[];\n}`;
|
|
2361
|
+
}
|
|
2362
|
+
_detailDtoClassCapitalize(scene) {
|
|
2363
|
+
const {
|
|
2364
|
+
argv
|
|
2365
|
+
} = this.context;
|
|
2366
|
+
return scene === 'View' ? this._capitalize(argv.detailDtoViewName) : this._capitalize(argv.detailDtoMutateName);
|
|
2367
|
+
}
|
|
2368
|
+
_masterLocaleAdditions(locale) {
|
|
2369
|
+
const {
|
|
2370
|
+
argv
|
|
2371
|
+
} = this.context;
|
|
2372
|
+
if (locale === 'en-us') {
|
|
2373
|
+
return [`${argv.relationNameCapitalize}: '${this._titleize(argv.relationName)}'`, `Add${argv.detailDialogTitleCapitalize}: 'Add ${this._titleize(argv.detailModuleInfo.relativeName)}'`, `Edit${argv.detailDialogTitleCapitalize}: 'Edit ${this._titleize(argv.detailModuleInfo.relativeName)}'`, `View${argv.detailDialogTitleCapitalize}: 'View ${this._titleize(argv.detailModuleInfo.relativeName)}'`];
|
|
2374
|
+
}
|
|
2375
|
+
return [`${argv.relationNameCapitalize}: '明细'`, `Add${argv.detailDialogTitleCapitalize}: '添加明细'`, `Edit${argv.detailDialogTitleCapitalize}: '编辑明细'`, `View${argv.detailDialogTitleCapitalize}: '查看明细'`];
|
|
2376
|
+
}
|
|
2377
|
+
async _createDetailCoreResource() {
|
|
2378
|
+
const {
|
|
2379
|
+
argv
|
|
2380
|
+
} = this.context;
|
|
2381
|
+
await this.helper.invokeCli([':tools:crudBasic', argv.detailResourceName, `--module=${argv.detailModule}`, '--nometadata'], {
|
|
2382
|
+
cwd: argv.projectPath
|
|
2383
|
+
});
|
|
2384
|
+
}
|
|
2385
|
+
_handleAggregateDetailMode(hasStandaloneSurface) {
|
|
2386
|
+
const {
|
|
2387
|
+
argv
|
|
2388
|
+
} = this.context;
|
|
2389
|
+
if (hasStandaloneSurface && !argv.createdDetailResource) {
|
|
2390
|
+
throw new Error(`detail module already has a standalone resource surface: ${argv.detailModule}:${argv.detailResourceName}`);
|
|
2391
|
+
}
|
|
2392
|
+
if (this._hasStandaloneDetailSurface()) {
|
|
2393
|
+
this._removeStandaloneDetailSurface();
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
_handleStandaloneDetailMode() {
|
|
2397
|
+
const {
|
|
2398
|
+
argv
|
|
2399
|
+
} = this.context;
|
|
2400
|
+
if (!this._hasStandaloneDetailSurface()) {
|
|
2401
|
+
throw new Error(`detail module does not have a standalone resource surface: ${argv.detailModule}:${argv.detailResourceName}`);
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
_detailModuleShape() {
|
|
2405
|
+
const files = this._detailPaths();
|
|
2406
|
+
return {
|
|
2407
|
+
hasCoreDetailFiles: fs.existsSync(files.entity) && fs.existsSync(files.model),
|
|
2408
|
+
hasStandaloneSurface: this._hasStandaloneDetailSurface()
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2411
|
+
_masterPaths() {
|
|
2412
|
+
const {
|
|
2413
|
+
argv
|
|
2414
|
+
} = this.context;
|
|
2415
|
+
const masterRoot = argv._module.root;
|
|
2416
|
+
return {
|
|
2417
|
+
root: masterRoot,
|
|
2418
|
+
model: path.join(masterRoot, 'src/model', `${argv.resourceName}.ts`),
|
|
2419
|
+
service: path.join(masterRoot, 'src/service', `${argv.resourceName}.ts`),
|
|
2420
|
+
dtoDir: path.join(masterRoot, 'src/dto'),
|
|
2421
|
+
localeDir: path.join(masterRoot, 'src/config/locale')
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2424
|
+
_detailPaths() {
|
|
2425
|
+
const {
|
|
2426
|
+
argv
|
|
2427
|
+
} = this.context;
|
|
2428
|
+
const detailRoot = argv._detailModule.root;
|
|
2429
|
+
return {
|
|
2430
|
+
root: detailRoot,
|
|
2431
|
+
entity: path.join(detailRoot, 'src/entity', `${argv.detailResourceName}.tsx`),
|
|
2432
|
+
model: path.join(detailRoot, 'src/model', `${argv.detailResourceName}.ts`),
|
|
2433
|
+
controller: path.join(detailRoot, 'src/controller', `${argv.detailResourceName}.ts`),
|
|
2434
|
+
service: path.join(detailRoot, 'src/service', `${argv.detailResourceName}.ts`),
|
|
2435
|
+
dtoDir: path.join(detailRoot, 'src/dto'),
|
|
2436
|
+
test: path.join(detailRoot, 'test', `${argv.detailResourceName}.test.ts`),
|
|
2437
|
+
metaVersion: path.join(detailRoot, 'src/bean', 'meta.version.ts'),
|
|
2438
|
+
metaIndex: path.join(detailRoot, 'src/bean', 'meta.index.ts')
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
_hasStandaloneDetailSurface() {
|
|
2442
|
+
const files = this._detailPaths();
|
|
2443
|
+
return fs.existsSync(files.controller) || fs.existsSync(files.service) || fs.existsSync(files.dtoDir);
|
|
2444
|
+
}
|
|
2445
|
+
_removeStandaloneDetailSurface() {
|
|
2446
|
+
const files = this._detailPaths();
|
|
2447
|
+
for (const file of [files.controller, files.service, files.test]) {
|
|
2448
|
+
if (fs.existsSync(file)) {
|
|
2449
|
+
fs.rmSync(file, {
|
|
2450
|
+
force: true
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
if (fs.existsSync(files.dtoDir)) {
|
|
2455
|
+
fs.rmSync(files.dtoDir, {
|
|
2456
|
+
recursive: true,
|
|
2457
|
+
force: true
|
|
2458
|
+
});
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
_detailDtoResItemCapitalize() {
|
|
2462
|
+
return this._capitalize(this.context.argv.detailDtoResItemName);
|
|
2463
|
+
}
|
|
2464
|
+
_detailDtoTemplates() {
|
|
2465
|
+
const {
|
|
2466
|
+
argv
|
|
2467
|
+
} = this.context;
|
|
2468
|
+
return [[argv.detailDtoBaseName, '<%=argv.detailDtoBaseName%>.tsx_'], [argv.detailDtoMutateName, '<%=argv.detailDtoMutateName%>.tsx_'], [argv.detailDtoViewName, '<%=argv.detailDtoViewName%>.tsx_'], [argv.detailDtoResItemName, '<%=argv.detailDtoResItemName%>.tsx_']];
|
|
2469
|
+
}
|
|
2470
|
+
_masterDtoScenes() {
|
|
2471
|
+
return ['Create', 'Update', 'View'];
|
|
2472
|
+
}
|
|
2473
|
+
_masterLocales() {
|
|
2474
|
+
return ['en-us', 'zh-cn'];
|
|
2475
|
+
}
|
|
2476
|
+
_resolveCreatedDetailModuleRoot() {
|
|
2477
|
+
const {
|
|
2478
|
+
argv
|
|
2479
|
+
} = this.context;
|
|
2480
|
+
if (argv._module.suite) {
|
|
2481
|
+
return path.join(argv.projectPath, 'src/suite', argv._module.suite, 'modules', argv.detailModule);
|
|
2482
|
+
}
|
|
2483
|
+
return path.join(argv.projectPath, 'src/module', argv.detailModule);
|
|
2484
|
+
}
|
|
2485
|
+
_capitalize(name) {
|
|
2486
|
+
return this.helper.firstCharToUpperCase(name);
|
|
2487
|
+
}
|
|
2488
|
+
_titleize(name) {
|
|
2489
|
+
return this.helper.stringToCapitalize(name, '-').replace(/([A-Z])/g, ' $1').trim();
|
|
2490
|
+
}
|
|
2491
|
+
_readFile(fileName) {
|
|
2492
|
+
if (!fs.existsSync(fileName)) {
|
|
2493
|
+
throw new Error(`file does not exist: ${fileName}`);
|
|
2494
|
+
}
|
|
2495
|
+
return fs.readFileSync(fileName).toString('utf8');
|
|
2496
|
+
}
|
|
2497
|
+
async _saveFile(fileName, content) {
|
|
2498
|
+
fs.writeFileSync(fileName, content);
|
|
2499
|
+
await this.helper.formatFile({
|
|
2500
|
+
fileName,
|
|
2501
|
+
logPrefix: 'format: '
|
|
2502
|
+
});
|
|
2503
|
+
}
|
|
2504
|
+
_replaceStrict(content, search, replacement, fileName) {
|
|
2505
|
+
if (!content.includes(search)) {
|
|
2506
|
+
throw new Error(`file is not in the expected shape: ${fileName}`);
|
|
2507
|
+
}
|
|
2508
|
+
return content.replace(search, replacement);
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2052
2512
|
function checkIgnoreOfParts(parts) {
|
|
2053
2513
|
const indexLast = parts.length - 1;
|
|
2054
2514
|
if (parts[indexLast].endsWith('_')) {
|
|
@@ -2542,8 +3002,7 @@ class CliToolsMetadata extends BeanCliBase {
|
|
|
2542
3002
|
}
|
|
2543
3003
|
}
|
|
2544
3004
|
async _generateMetadata(moduleName, force) {
|
|
2545
|
-
const module = this.helper.
|
|
2546
|
-
if (!module) throw new Error(`module not found: ${moduleName}`);
|
|
3005
|
+
const module = this.helper.findModuleCanonical(moduleName);
|
|
2547
3006
|
const modulePath = module.root;
|
|
2548
3007
|
const metaDir = path.join(modulePath, 'src/.metadata');
|
|
2549
3008
|
const metaIndexFile = path.join(metaDir, 'index.ts');
|
|
@@ -2788,7 +3247,8 @@ const beans = {
|
|
|
2788
3247
|
'tools.metadata': CliToolsMetadata,
|
|
2789
3248
|
'tools.crudBasic': CliToolsCrudBasic,
|
|
2790
3249
|
'tools.crudStart': CliToolsCrudStart,
|
|
2791
|
-
'tools.crud': CliToolsCrud
|
|
3250
|
+
'tools.crud': CliToolsCrud,
|
|
3251
|
+
'tools.masterDetail': CliToolsMasterDetail
|
|
2792
3252
|
};
|
|
2793
3253
|
|
|
2794
3254
|
var binBuild = {
|
|
@@ -3361,6 +3821,84 @@ var toolsDeps = {
|
|
|
3361
3821
|
options: {}
|
|
3362
3822
|
};
|
|
3363
3823
|
|
|
3824
|
+
var toolsMasterDetail = {
|
|
3825
|
+
bean: 'tools.masterDetail',
|
|
3826
|
+
info: {
|
|
3827
|
+
version: '5.0.0',
|
|
3828
|
+
title: 'Cli: Tools: Master Detail',
|
|
3829
|
+
usage: 'npm run vona :tools:masterDetail resourceName -- [--module=] [--detailModule=] [--detailResourceName=] [--relationName=] [--fk=] [--detailMode=aggregate|standalone]'
|
|
3830
|
+
},
|
|
3831
|
+
options: {
|
|
3832
|
+
module: {
|
|
3833
|
+
description: 'master module relative name, such as training-student',
|
|
3834
|
+
type: 'string'
|
|
3835
|
+
},
|
|
3836
|
+
detailModule: {
|
|
3837
|
+
description: 'detail module relative name, such as training-record',
|
|
3838
|
+
type: 'string'
|
|
3839
|
+
},
|
|
3840
|
+
detailResourceName: {
|
|
3841
|
+
description: 'detail resource name',
|
|
3842
|
+
type: 'string'
|
|
3843
|
+
},
|
|
3844
|
+
relationName: {
|
|
3845
|
+
description: 'master relation name',
|
|
3846
|
+
type: 'string'
|
|
3847
|
+
},
|
|
3848
|
+
fk: {
|
|
3849
|
+
description: 'detail foreign key field name',
|
|
3850
|
+
type: 'string'
|
|
3851
|
+
},
|
|
3852
|
+
detailMode: {
|
|
3853
|
+
description: 'detail mode: aggregate or standalone',
|
|
3854
|
+
type: 'string'
|
|
3855
|
+
}
|
|
3856
|
+
},
|
|
3857
|
+
groups: {
|
|
3858
|
+
default: {
|
|
3859
|
+
questions: {
|
|
3860
|
+
resourceName: {
|
|
3861
|
+
type: 'input',
|
|
3862
|
+
message: 'master resourceName',
|
|
3863
|
+
initial: {
|
|
3864
|
+
expression: 'arg0'
|
|
3865
|
+
},
|
|
3866
|
+
required: true
|
|
3867
|
+
},
|
|
3868
|
+
module: {
|
|
3869
|
+
type: 'input',
|
|
3870
|
+
message: 'master module relative name (for example training-student)',
|
|
3871
|
+
required: true
|
|
3872
|
+
},
|
|
3873
|
+
detailModule: {
|
|
3874
|
+
type: 'input',
|
|
3875
|
+
message: 'detail module relative name (for example training-record)',
|
|
3876
|
+
required: true
|
|
3877
|
+
},
|
|
3878
|
+
detailResourceName: {
|
|
3879
|
+
type: 'input',
|
|
3880
|
+
message: 'detail resourceName',
|
|
3881
|
+
required: true
|
|
3882
|
+
},
|
|
3883
|
+
relationName: {
|
|
3884
|
+
type: 'input',
|
|
3885
|
+
message: 'master relation name'
|
|
3886
|
+
},
|
|
3887
|
+
fk: {
|
|
3888
|
+
type: 'input',
|
|
3889
|
+
message: 'detail foreign key field name'
|
|
3890
|
+
},
|
|
3891
|
+
detailMode: {
|
|
3892
|
+
type: 'input',
|
|
3893
|
+
message: 'detail mode (aggregate|standalone)',
|
|
3894
|
+
initial: 'aggregate',
|
|
3895
|
+
required: true
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3900
|
+
};
|
|
3901
|
+
|
|
3364
3902
|
var toolsMetadata = {
|
|
3365
3903
|
bean: 'tools.metadata',
|
|
3366
3904
|
info: {
|
|
@@ -3415,7 +3953,8 @@ const commands = {
|
|
|
3415
3953
|
metadata: toolsMetadata,
|
|
3416
3954
|
crudBasic: toolsCrudBasic,
|
|
3417
3955
|
crudStart: toolsCrudStart,
|
|
3418
|
-
crud: toolsCrud
|
|
3956
|
+
crud: toolsCrud,
|
|
3957
|
+
masterDetail: toolsMasterDetail
|
|
3419
3958
|
}
|
|
3420
3959
|
};
|
|
3421
3960
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { IModule, IModuleInfo } from '@cabloy/module-info';
|
|
2
|
+
import { BeanCliBase } from '@cabloy/cli';
|
|
3
|
+
type DetailMode = 'aggregate' | 'standalone';
|
|
4
|
+
declare module '@cabloy/cli' {
|
|
5
|
+
interface ICommandArgv {
|
|
6
|
+
module: string;
|
|
7
|
+
moduleInfo: IModuleInfo;
|
|
8
|
+
_module: IModule;
|
|
9
|
+
resourceName: string;
|
|
10
|
+
resourceNameCapitalize: string;
|
|
11
|
+
detailModule: string;
|
|
12
|
+
detailModuleInfo: IModuleInfo;
|
|
13
|
+
_detailModule?: IModule;
|
|
14
|
+
detailResourceName: string;
|
|
15
|
+
detailResourceNameCapitalize: string;
|
|
16
|
+
relationName: string;
|
|
17
|
+
relationNameCapitalize: string;
|
|
18
|
+
fk: string;
|
|
19
|
+
detailMode: DetailMode;
|
|
20
|
+
detailPackageName: string;
|
|
21
|
+
detailModuleCapitalize: string;
|
|
22
|
+
detailDtoBaseName: string;
|
|
23
|
+
detailDtoMutateName: string;
|
|
24
|
+
detailDtoViewName: string;
|
|
25
|
+
detailDtoResItemName: string;
|
|
26
|
+
detailFieldPrivateName: string;
|
|
27
|
+
detailDialogTitleCapitalize: string;
|
|
28
|
+
createdDetailModule?: boolean;
|
|
29
|
+
createdDetailResource?: boolean;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export declare class CliToolsMasterDetail extends BeanCliBase {
|
|
33
|
+
execute(): Promise<void>;
|
|
34
|
+
private _prepareArgv;
|
|
35
|
+
private _ensureDetailModule;
|
|
36
|
+
private _ensureDetailResourceShape;
|
|
37
|
+
private _patchDetailModule;
|
|
38
|
+
private _patchDetailEntity;
|
|
39
|
+
private _patchDetailEntityImport;
|
|
40
|
+
private _patchDetailEntityField;
|
|
41
|
+
private _patchDetailMetaVersion;
|
|
42
|
+
private _patchDetailMetaIndex;
|
|
43
|
+
private _detailMetaVersionLine;
|
|
44
|
+
private _detailMetaIndexLine;
|
|
45
|
+
private _patchFileByMarker;
|
|
46
|
+
private _patchFileContent;
|
|
47
|
+
private _renderMasterDetailDtos;
|
|
48
|
+
private _patchMasterModule;
|
|
49
|
+
private _detailPatchTasks;
|
|
50
|
+
private _masterPatchTasks;
|
|
51
|
+
private _runSequential;
|
|
52
|
+
private _patchMasterModel;
|
|
53
|
+
private _patchMasterService;
|
|
54
|
+
private _patchMasterModelImport;
|
|
55
|
+
private _patchMasterModelRelations;
|
|
56
|
+
private _patchMasterModelDecorator;
|
|
57
|
+
private _masterModelRelationCode;
|
|
58
|
+
private _masterServiceIncludeReplacements;
|
|
59
|
+
private _patchMasterDto;
|
|
60
|
+
private _patchMasterLocale;
|
|
61
|
+
private _refreshMetadata;
|
|
62
|
+
private _patchLocaleAdditions;
|
|
63
|
+
private _localeAdditionKey;
|
|
64
|
+
private _metadataModules;
|
|
65
|
+
private _renderMasterDetailDtoFile;
|
|
66
|
+
private _patchMasterDtoImports;
|
|
67
|
+
private _patchMasterDtoFields;
|
|
68
|
+
private _patchMasterDtoClass;
|
|
69
|
+
private _masterDtoDetailImports;
|
|
70
|
+
private _masterDtoFieldCode;
|
|
71
|
+
private _masterDtoClassReplaceSource;
|
|
72
|
+
private _masterDtoClassReplaceTarget;
|
|
73
|
+
private _detailDtoClassCapitalize;
|
|
74
|
+
private _masterLocaleAdditions;
|
|
75
|
+
private _createDetailCoreResource;
|
|
76
|
+
private _handleAggregateDetailMode;
|
|
77
|
+
private _handleStandaloneDetailMode;
|
|
78
|
+
private _detailModuleShape;
|
|
79
|
+
private _masterPaths;
|
|
80
|
+
private _detailPaths;
|
|
81
|
+
private _hasStandaloneDetailSurface;
|
|
82
|
+
private _removeStandaloneDetailSurface;
|
|
83
|
+
private _detailDtoResItemCapitalize;
|
|
84
|
+
private _detailDtoTemplates;
|
|
85
|
+
private _masterDtoScenes;
|
|
86
|
+
private _masterLocales;
|
|
87
|
+
private _resolveCreatedDetailModuleRoot;
|
|
88
|
+
private _capitalize;
|
|
89
|
+
private _titleize;
|
|
90
|
+
private _readFile;
|
|
91
|
+
private _saveFile;
|
|
92
|
+
private _replaceStrict;
|
|
93
|
+
}
|
|
94
|
+
export {};
|
package/dist/lib/beans.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { CliToolsCrud } from './bean/cli.tools.crud.ts';
|
|
|
26
26
|
import { CliToolsCrudBasic } from './bean/cli.tools.crudBasic.ts';
|
|
27
27
|
import { CliToolsCrudStart } from './bean/cli.tools.crudStart.ts';
|
|
28
28
|
import { CliToolsDeps } from './bean/cli.tools.deps.ts';
|
|
29
|
+
import { CliToolsMasterDetail } from './bean/cli.tools.masterDetail.ts';
|
|
29
30
|
import { CliToolsMetadata } from './bean/cli.tools.metadata.ts';
|
|
30
31
|
export declare const beans: {
|
|
31
32
|
'default.list': typeof CliDefaultList;
|
|
@@ -57,4 +58,5 @@ export declare const beans: {
|
|
|
57
58
|
'tools.crudBasic': typeof CliToolsCrudBasic;
|
|
58
59
|
'tools.crudStart': typeof CliToolsCrudStart;
|
|
59
60
|
'tools.crud': typeof CliToolsCrud;
|
|
61
|
+
'tools.masterDetail': typeof CliToolsMasterDetail;
|
|
60
62
|
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
bean: string;
|
|
3
|
+
info: {
|
|
4
|
+
version: string;
|
|
5
|
+
title: string;
|
|
6
|
+
usage: string;
|
|
7
|
+
};
|
|
8
|
+
options: {
|
|
9
|
+
module: {
|
|
10
|
+
description: string;
|
|
11
|
+
type: string;
|
|
12
|
+
};
|
|
13
|
+
detailModule: {
|
|
14
|
+
description: string;
|
|
15
|
+
type: string;
|
|
16
|
+
};
|
|
17
|
+
detailResourceName: {
|
|
18
|
+
description: string;
|
|
19
|
+
type: string;
|
|
20
|
+
};
|
|
21
|
+
relationName: {
|
|
22
|
+
description: string;
|
|
23
|
+
type: string;
|
|
24
|
+
};
|
|
25
|
+
fk: {
|
|
26
|
+
description: string;
|
|
27
|
+
type: string;
|
|
28
|
+
};
|
|
29
|
+
detailMode: {
|
|
30
|
+
description: string;
|
|
31
|
+
type: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
groups: {
|
|
35
|
+
default: {
|
|
36
|
+
questions: {
|
|
37
|
+
resourceName: {
|
|
38
|
+
type: string;
|
|
39
|
+
message: string;
|
|
40
|
+
initial: {
|
|
41
|
+
expression: string;
|
|
42
|
+
};
|
|
43
|
+
required: boolean;
|
|
44
|
+
};
|
|
45
|
+
module: {
|
|
46
|
+
type: string;
|
|
47
|
+
message: string;
|
|
48
|
+
required: boolean;
|
|
49
|
+
};
|
|
50
|
+
detailModule: {
|
|
51
|
+
type: string;
|
|
52
|
+
message: string;
|
|
53
|
+
required: boolean;
|
|
54
|
+
};
|
|
55
|
+
detailResourceName: {
|
|
56
|
+
type: string;
|
|
57
|
+
message: string;
|
|
58
|
+
required: boolean;
|
|
59
|
+
};
|
|
60
|
+
relationName: {
|
|
61
|
+
type: string;
|
|
62
|
+
message: string;
|
|
63
|
+
};
|
|
64
|
+
fk: {
|
|
65
|
+
type: string;
|
|
66
|
+
message: string;
|
|
67
|
+
};
|
|
68
|
+
detailMode: {
|
|
69
|
+
type: string;
|
|
70
|
+
message: string;
|
|
71
|
+
initial: string;
|
|
72
|
+
required: boolean;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
export default _default;
|
package/dist/lib/commands.d.ts
CHANGED
|
@@ -545,5 +545,82 @@ export declare const commands: {
|
|
|
545
545
|
};
|
|
546
546
|
};
|
|
547
547
|
};
|
|
548
|
+
masterDetail: {
|
|
549
|
+
bean: string;
|
|
550
|
+
info: {
|
|
551
|
+
version: string;
|
|
552
|
+
title: string;
|
|
553
|
+
usage: string;
|
|
554
|
+
};
|
|
555
|
+
options: {
|
|
556
|
+
module: {
|
|
557
|
+
description: string;
|
|
558
|
+
type: string;
|
|
559
|
+
};
|
|
560
|
+
detailModule: {
|
|
561
|
+
description: string;
|
|
562
|
+
type: string;
|
|
563
|
+
};
|
|
564
|
+
detailResourceName: {
|
|
565
|
+
description: string;
|
|
566
|
+
type: string;
|
|
567
|
+
};
|
|
568
|
+
relationName: {
|
|
569
|
+
description: string;
|
|
570
|
+
type: string;
|
|
571
|
+
};
|
|
572
|
+
fk: {
|
|
573
|
+
description: string;
|
|
574
|
+
type: string;
|
|
575
|
+
};
|
|
576
|
+
detailMode: {
|
|
577
|
+
description: string;
|
|
578
|
+
type: string;
|
|
579
|
+
};
|
|
580
|
+
};
|
|
581
|
+
groups: {
|
|
582
|
+
default: {
|
|
583
|
+
questions: {
|
|
584
|
+
resourceName: {
|
|
585
|
+
type: string;
|
|
586
|
+
message: string;
|
|
587
|
+
initial: {
|
|
588
|
+
expression: string;
|
|
589
|
+
};
|
|
590
|
+
required: boolean;
|
|
591
|
+
};
|
|
592
|
+
module: {
|
|
593
|
+
type: string;
|
|
594
|
+
message: string;
|
|
595
|
+
required: boolean;
|
|
596
|
+
};
|
|
597
|
+
detailModule: {
|
|
598
|
+
type: string;
|
|
599
|
+
message: string;
|
|
600
|
+
required: boolean;
|
|
601
|
+
};
|
|
602
|
+
detailResourceName: {
|
|
603
|
+
type: string;
|
|
604
|
+
message: string;
|
|
605
|
+
required: boolean;
|
|
606
|
+
};
|
|
607
|
+
relationName: {
|
|
608
|
+
type: string;
|
|
609
|
+
message: string;
|
|
610
|
+
};
|
|
611
|
+
fk: {
|
|
612
|
+
type: string;
|
|
613
|
+
message: string;
|
|
614
|
+
};
|
|
615
|
+
detailMode: {
|
|
616
|
+
type: string;
|
|
617
|
+
message: string;
|
|
618
|
+
initial: string;
|
|
619
|
+
required: boolean;
|
|
620
|
+
};
|
|
621
|
+
};
|
|
622
|
+
};
|
|
623
|
+
};
|
|
624
|
+
};
|
|
548
625
|
};
|
|
549
626
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona-cli-set-api",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.1.117",
|
|
4
|
+
"gitHead": "1a39e8008e1b48001cfeff475ddd53a2a0d867c4",
|
|
5
5
|
"description": "vona cli-set-api",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"framework",
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
"tsc:publish": "npm run clean && node ../cli/src/bin/vona.ts :bin:buildGeneral && tsc -p tsconfig.build.json && tsc -p tsconfig.cli.json && tsc -p tsconfig.isolate.json",
|
|
36
36
|
"prepublishOnly": "npm run tsc:publish",
|
|
37
37
|
"prepack": "clean-package",
|
|
38
|
-
"postpack": "clean-package restore
|
|
38
|
+
"postpack": "clean-package restore"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
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.
|
|
44
|
+
"@cabloy/cli": "^3.1.23",
|
|
45
45
|
"@cabloy/dotenv": "^1.2.8",
|
|
46
46
|
"@cabloy/extend": "^3.2.8",
|
|
47
47
|
"@cabloy/module-glob": "^5.3.13",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"ts-node-maintained": "^10.9.6",
|
|
74
74
|
"urllib": "^4.9.0",
|
|
75
75
|
"uuid": "^11.1.0",
|
|
76
|
-
"vona-core": "^5.1.
|
|
76
|
+
"vona-core": "^5.1.24",
|
|
77
77
|
"why-is-node-running": "^3.2.2",
|
|
78
78
|
"yargs-parser": "^22.0.0"
|
|
79
79
|
}
|