vona-cli-set-api 1.1.109 → 1.1.114
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/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 +646 -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 +4 -4
|
@@ -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);
|
|
@@ -1224,6 +1217,12 @@ class CliCreateModule extends BeanCliBase {
|
|
|
1224
1217
|
if (!argv.vscode && !argv.ci) {
|
|
1225
1218
|
await this.helper.pnpmInstall();
|
|
1226
1219
|
}
|
|
1220
|
+
// tools.metadata
|
|
1221
|
+
if (!argv.nometadata) {
|
|
1222
|
+
await this.helper.invokeCli([':tools:metadata', moduleName], {
|
|
1223
|
+
cwd: argv.projectPath
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1227
1226
|
}
|
|
1228
1227
|
}
|
|
1229
1228
|
|
|
@@ -1240,7 +1239,7 @@ class CliCreateSuite extends BeanCliBase {
|
|
|
1240
1239
|
argv.name = nameMeta.short;
|
|
1241
1240
|
// suite name/info
|
|
1242
1241
|
const suiteName = argv.name;
|
|
1243
|
-
argv.suiteInfo = this.helper.
|
|
1242
|
+
argv.suiteInfo = this.helper.parseSuiteInfoCanonical(suiteName);
|
|
1244
1243
|
// check if exists
|
|
1245
1244
|
const _suite = this.helper.findSuite(suiteName);
|
|
1246
1245
|
if (_suite) {
|
|
@@ -1268,12 +1267,8 @@ class CliCreateTest extends BeanCliBase {
|
|
|
1268
1267
|
await super.execute();
|
|
1269
1268
|
// module name/info
|
|
1270
1269
|
const moduleName = argv.module;
|
|
1271
|
-
argv.moduleInfo = this.helper.
|
|
1272
|
-
|
|
1273
|
-
const _module = this.helper.findModule(moduleName);
|
|
1274
|
-
if (!_module) {
|
|
1275
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1276
|
-
}
|
|
1270
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1271
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1277
1272
|
// target dir
|
|
1278
1273
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1279
1274
|
// name
|
|
@@ -1435,12 +1430,8 @@ class CliInitAsset extends BeanCliBase {
|
|
|
1435
1430
|
await super.execute();
|
|
1436
1431
|
// module name/info
|
|
1437
1432
|
const moduleName = argv.module;
|
|
1438
|
-
argv.moduleInfo = this.helper.
|
|
1439
|
-
|
|
1440
|
-
const _module = this.helper.findModule(moduleName);
|
|
1441
|
-
if (!_module) {
|
|
1442
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1443
|
-
}
|
|
1433
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1434
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1444
1435
|
// target dir
|
|
1445
1436
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1446
1437
|
// scene
|
|
@@ -1464,12 +1455,8 @@ class CliInitConfig extends BeanCliBase {
|
|
|
1464
1455
|
// module name/info
|
|
1465
1456
|
const moduleName = argv._[0];
|
|
1466
1457
|
if (!moduleName) return;
|
|
1467
|
-
argv.moduleInfo = this.helper.
|
|
1468
|
-
|
|
1469
|
-
const _module = this.helper.findModule(moduleName);
|
|
1470
|
-
if (!_module) {
|
|
1471
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1472
|
-
}
|
|
1458
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1459
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1473
1460
|
// target dir
|
|
1474
1461
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1475
1462
|
const configFile = path.join(targetDir, 'src/config/config.ts');
|
|
@@ -1502,12 +1489,8 @@ class CliInitConstant extends BeanCliBase {
|
|
|
1502
1489
|
// module name/info
|
|
1503
1490
|
const moduleName = argv._[0];
|
|
1504
1491
|
if (!moduleName) return;
|
|
1505
|
-
argv.moduleInfo = this.helper.
|
|
1506
|
-
|
|
1507
|
-
const _module = this.helper.findModule(moduleName);
|
|
1508
|
-
if (!_module) {
|
|
1509
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1510
|
-
}
|
|
1492
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1493
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1511
1494
|
// target dir
|
|
1512
1495
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1513
1496
|
const constantFile = path.join(targetDir, 'src/config/constants.ts');
|
|
@@ -1540,12 +1523,8 @@ class CliInitError extends BeanCliBase {
|
|
|
1540
1523
|
// module name/info
|
|
1541
1524
|
const moduleName = argv._[0];
|
|
1542
1525
|
if (!moduleName) return;
|
|
1543
|
-
argv.moduleInfo = this.helper.
|
|
1544
|
-
|
|
1545
|
-
const _module = this.helper.findModule(moduleName);
|
|
1546
|
-
if (!_module) {
|
|
1547
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1548
|
-
}
|
|
1526
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1527
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1549
1528
|
// target dir
|
|
1550
1529
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1551
1530
|
const errorFile = path.join(targetDir, 'src/config/errors.ts');
|
|
@@ -1589,12 +1568,8 @@ class CliInitLib extends BeanCliBase {
|
|
|
1589
1568
|
// module name/info
|
|
1590
1569
|
const moduleName = argv._[0];
|
|
1591
1570
|
if (!moduleName) return;
|
|
1592
|
-
argv.moduleInfo = this.helper.
|
|
1593
|
-
|
|
1594
|
-
const _module = this.helper.findModule(moduleName);
|
|
1595
|
-
if (!_module) {
|
|
1596
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1597
|
-
}
|
|
1571
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1572
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1598
1573
|
// target dir
|
|
1599
1574
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1600
1575
|
const mainFile = path.join(targetDir, 'src/lib/index.ts');
|
|
@@ -1627,12 +1602,8 @@ class CliInitLocale extends BeanCliBase {
|
|
|
1627
1602
|
// module name/info
|
|
1628
1603
|
const moduleName = argv._[0];
|
|
1629
1604
|
if (!moduleName) return;
|
|
1630
|
-
argv.moduleInfo = this.helper.
|
|
1631
|
-
|
|
1632
|
-
const _module = this.helper.findModule(moduleName);
|
|
1633
|
-
if (!_module) {
|
|
1634
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1635
|
-
}
|
|
1605
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1606
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1636
1607
|
// target dir
|
|
1637
1608
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1638
1609
|
const localeFile = path.join(targetDir, 'src/config/locale');
|
|
@@ -1665,12 +1636,8 @@ class CliInitMain extends BeanCliBase {
|
|
|
1665
1636
|
// module name/info
|
|
1666
1637
|
const moduleName = argv._[0];
|
|
1667
1638
|
if (!moduleName) return;
|
|
1668
|
-
argv.moduleInfo = this.helper.
|
|
1669
|
-
|
|
1670
|
-
const _module = this.helper.findModule(moduleName);
|
|
1671
|
-
if (!_module) {
|
|
1672
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1673
|
-
}
|
|
1639
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1640
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1674
1641
|
// target dir
|
|
1675
1642
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1676
1643
|
const mainFile = path.join(targetDir, 'src/main.ts');
|
|
@@ -1703,12 +1670,8 @@ class CliInitMonkey extends BeanCliBase {
|
|
|
1703
1670
|
// module name/info
|
|
1704
1671
|
const moduleName = argv._[0];
|
|
1705
1672
|
if (!moduleName) return;
|
|
1706
|
-
argv.moduleInfo = this.helper.
|
|
1707
|
-
|
|
1708
|
-
const _module = this.helper.findModule(moduleName);
|
|
1709
|
-
if (!_module) {
|
|
1710
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1711
|
-
}
|
|
1673
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1674
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1712
1675
|
// target dir
|
|
1713
1676
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1714
1677
|
const monkeyFile = path.join(targetDir, 'src/monkey.ts');
|
|
@@ -1765,12 +1728,8 @@ class CliInitStatic extends BeanCliBase {
|
|
|
1765
1728
|
// module name/info
|
|
1766
1729
|
const moduleName = argv._[0];
|
|
1767
1730
|
if (!moduleName) return;
|
|
1768
|
-
argv.moduleInfo = this.helper.
|
|
1769
|
-
|
|
1770
|
-
const _module = this.helper.findModule(moduleName);
|
|
1771
|
-
if (!_module) {
|
|
1772
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1773
|
-
}
|
|
1731
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1732
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1774
1733
|
// target dir
|
|
1775
1734
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1776
1735
|
const staticDir = path.join(targetDir, 'assets/static');
|
|
@@ -1801,12 +1760,8 @@ class CliInitTypes extends BeanCliBase {
|
|
|
1801
1760
|
// module name/info
|
|
1802
1761
|
const moduleName = argv._[0];
|
|
1803
1762
|
if (!moduleName) return;
|
|
1804
|
-
argv.moduleInfo = this.helper.
|
|
1805
|
-
|
|
1806
|
-
const _module = this.helper.findModule(moduleName);
|
|
1807
|
-
if (!_module) {
|
|
1808
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1809
|
-
}
|
|
1763
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1764
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1810
1765
|
// target dir
|
|
1811
1766
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1812
1767
|
const mainFile = path.join(targetDir, 'src/types/index.ts');
|
|
@@ -1843,12 +1798,8 @@ class CliToolsCrud extends BeanCliBase {
|
|
|
1843
1798
|
argv.ssrSiteGroupName = isCabloyStart ? 'start-siteadmin:management' : 'basic-siteadmin:management';
|
|
1844
1799
|
// module name/info
|
|
1845
1800
|
const moduleName = argv.module;
|
|
1846
|
-
argv.moduleInfo = this.helper.
|
|
1847
|
-
|
|
1848
|
-
const _module = this.helper.findModule(moduleName);
|
|
1849
|
-
if (!_module) {
|
|
1850
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1851
|
-
}
|
|
1801
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1802
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1852
1803
|
// target dir
|
|
1853
1804
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1854
1805
|
// resourceName
|
|
@@ -1889,12 +1840,8 @@ class CliToolsCrudBasic extends BeanCliBase {
|
|
|
1889
1840
|
await super.execute();
|
|
1890
1841
|
// module name/info
|
|
1891
1842
|
const moduleName = argv.module;
|
|
1892
|
-
argv.moduleInfo = this.helper.
|
|
1893
|
-
|
|
1894
|
-
const _module = this.helper.findModule(moduleName);
|
|
1895
|
-
if (!_module) {
|
|
1896
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1897
|
-
}
|
|
1843
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1844
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1898
1845
|
// target dir
|
|
1899
1846
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1900
1847
|
// resourceName
|
|
@@ -1933,12 +1880,8 @@ class CliToolsCrudStart extends BeanCliBase {
|
|
|
1933
1880
|
await super.execute();
|
|
1934
1881
|
// module name/info
|
|
1935
1882
|
const moduleName = argv.module;
|
|
1936
|
-
argv.moduleInfo = this.helper.
|
|
1937
|
-
|
|
1938
|
-
const _module = this.helper.findModule(moduleName);
|
|
1939
|
-
if (!_module) {
|
|
1940
|
-
throw new Error(`module does not exist: ${moduleName}`);
|
|
1941
|
-
}
|
|
1883
|
+
argv.moduleInfo = this.helper.parseModuleInfoCanonical(moduleName);
|
|
1884
|
+
const _module = this.helper.findModuleCanonical(moduleName);
|
|
1942
1885
|
// target dir
|
|
1943
1886
|
const targetDir = await this.helper.ensureDir(_module.root);
|
|
1944
1887
|
// resourceName
|
|
@@ -2043,6 +1986,529 @@ class CliToolsDeps extends BeanCliBase {
|
|
|
2043
1986
|
}
|
|
2044
1987
|
}
|
|
2045
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
|
+
|
|
2046
2512
|
function checkIgnoreOfParts(parts) {
|
|
2047
2513
|
const indexLast = parts.length - 1;
|
|
2048
2514
|
if (parts[indexLast].endsWith('_')) {
|
|
@@ -2536,8 +3002,7 @@ class CliToolsMetadata extends BeanCliBase {
|
|
|
2536
3002
|
}
|
|
2537
3003
|
}
|
|
2538
3004
|
async _generateMetadata(moduleName, force) {
|
|
2539
|
-
const module = this.helper.
|
|
2540
|
-
if (!module) throw new Error(`module not found: ${moduleName}`);
|
|
3005
|
+
const module = this.helper.findModuleCanonical(moduleName);
|
|
2541
3006
|
const modulePath = module.root;
|
|
2542
3007
|
const metaDir = path.join(modulePath, 'src/.metadata');
|
|
2543
3008
|
const metaIndexFile = path.join(metaDir, 'index.ts');
|
|
@@ -2782,7 +3247,8 @@ const beans = {
|
|
|
2782
3247
|
'tools.metadata': CliToolsMetadata,
|
|
2783
3248
|
'tools.crudBasic': CliToolsCrudBasic,
|
|
2784
3249
|
'tools.crudStart': CliToolsCrudStart,
|
|
2785
|
-
'tools.crud': CliToolsCrud
|
|
3250
|
+
'tools.crud': CliToolsCrud,
|
|
3251
|
+
'tools.masterDetail': CliToolsMasterDetail
|
|
2786
3252
|
};
|
|
2787
3253
|
|
|
2788
3254
|
var binBuild = {
|
|
@@ -3355,6 +3821,84 @@ var toolsDeps = {
|
|
|
3355
3821
|
options: {}
|
|
3356
3822
|
};
|
|
3357
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
|
+
|
|
3358
3902
|
var toolsMetadata = {
|
|
3359
3903
|
bean: 'tools.metadata',
|
|
3360
3904
|
info: {
|
|
@@ -3409,7 +3953,8 @@ const commands = {
|
|
|
3409
3953
|
metadata: toolsMetadata,
|
|
3410
3954
|
crudBasic: toolsCrudBasic,
|
|
3411
3955
|
crudStart: toolsCrudStart,
|
|
3412
|
-
crud: toolsCrud
|
|
3956
|
+
crud: toolsCrud,
|
|
3957
|
+
masterDetail: toolsMasterDetail
|
|
3413
3958
|
}
|
|
3414
3959
|
};
|
|
3415
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.114",
|
|
4
|
+
"gitHead": "ae3d4871534ad17e465e5b8f8789e13b80583344",
|
|
5
5
|
"description": "vona cli-set-api",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"framework",
|
|
@@ -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.
|
|
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
|
}
|