@devstroupe/devkit-cli 1.1.5 → 1.1.7
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/dist/index.js +202 -170
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -976,43 +976,60 @@ program
|
|
|
976
976
|
console.error('Configuração de relacionamentos inválida:', error instanceof Error ? error.message : error);
|
|
977
977
|
process.exit(1);
|
|
978
978
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
979
|
+
let entitiesToGenerate = [];
|
|
980
|
+
const isAll = entityName.toLowerCase() === 'all';
|
|
981
|
+
if (isAll) {
|
|
982
|
+
entitiesToGenerate = config.entities || [];
|
|
983
|
+
if (entitiesToGenerate.length === 0) {
|
|
984
|
+
console.error('Nenhuma entidade configurada no devstroupe.config.ts.');
|
|
985
|
+
process.exit(1);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
const entity = config.entities?.find((e) => e.name.toLowerCase() === entityName.toLowerCase());
|
|
990
|
+
if (!entity) {
|
|
991
|
+
console.error(`Entidade "${entityName}" não configurada no devstroupe.config.ts.`);
|
|
992
|
+
process.exit(1);
|
|
993
|
+
}
|
|
994
|
+
entitiesToGenerate = [entity];
|
|
983
995
|
}
|
|
984
996
|
const backendRoot = path.resolve(process.cwd(), config.backendPath || './backend');
|
|
985
997
|
const frontendRoot = path.resolve(process.cwd(), config.frontendPath || './frontend');
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
boilerplatesDir = path.resolve(__dirname, '
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
const
|
|
1011
|
-
if (
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
const
|
|
998
|
+
for (const entity of entitiesToGenerate) {
|
|
999
|
+
const currentEntityName = entity.name;
|
|
1000
|
+
console.log(`\n=========================================`);
|
|
1001
|
+
console.log(`Processando Entidade: ${currentEntityName.toUpperCase()}`);
|
|
1002
|
+
console.log(`=========================================`);
|
|
1003
|
+
// 1. Gerar Backend (NestJS)
|
|
1004
|
+
if (entity.crud?.generateBackend !== false) {
|
|
1005
|
+
const isMultiTenant = !!config.multiTenant?.enabled;
|
|
1006
|
+
const isTenantScoped = isMultiTenant && (entity.tenantScoped !== false);
|
|
1007
|
+
const isMicroservices = config.backendType === 'microservices';
|
|
1008
|
+
const backendProperties = isMicroservices
|
|
1009
|
+
? entity.properties
|
|
1010
|
+
.filter((property) => property.type !== 'relationship' || (0, relationships_1.getRelationships)([property])[0].kind !== 'one-to-many')
|
|
1011
|
+
.map((property) => property.type === 'relationship'
|
|
1012
|
+
? { ...property, type: 'number', name: (0, relationships_1.getRelationships)([property])[0].foreignKey }
|
|
1013
|
+
: property)
|
|
1014
|
+
: entity.properties;
|
|
1015
|
+
let boilerplatesDir = path.resolve(__dirname, 'boilerplates');
|
|
1016
|
+
if (!fs.existsSync(boilerplatesDir)) {
|
|
1017
|
+
boilerplatesDir = path.resolve(__dirname, '../boilerplates');
|
|
1018
|
+
}
|
|
1019
|
+
if (!fs.existsSync(boilerplatesDir)) {
|
|
1020
|
+
boilerplatesDir = path.resolve(__dirname, '../../boilerplates');
|
|
1021
|
+
}
|
|
1022
|
+
const nestTemplateDir = path.join(boilerplatesDir, 'nest-template');
|
|
1023
|
+
if (isMicroservices) {
|
|
1024
|
+
const entityIndex = config.entities.findIndex((e) => e.name.toLowerCase() === entity.name.toLowerCase());
|
|
1025
|
+
const port = 3001 + (entityIndex >= 0 ? entityIndex : 0);
|
|
1026
|
+
// Garantir estrutura do API Gateway
|
|
1027
|
+
const gatewayRoot = path.join(backendRoot, 'api-gateway');
|
|
1028
|
+
if (!fs.existsSync(gatewayRoot) || !fs.existsSync(path.join(gatewayRoot, 'src', 'app.module.ts'))) {
|
|
1029
|
+
console.log(`[Gateway] Inicializando estrutura do API Gateway...`);
|
|
1030
|
+
fs.ensureDirSync(gatewayRoot);
|
|
1031
|
+
fs.copySync(nestTemplateDir, gatewayRoot);
|
|
1032
|
+
const gatewayEnv = `PORT=13000
|
|
1016
1033
|
DB_HOST=database
|
|
1017
1034
|
DB_PORT=3306
|
|
1018
1035
|
DB_USER=root
|
|
@@ -1020,31 +1037,31 @@ DB_PASSWORD=root
|
|
|
1020
1037
|
DB_NAME=devstroupe
|
|
1021
1038
|
JWT_SECRET=devstroupe-secret-key-12345
|
|
1022
1039
|
`;
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1040
|
+
fs.writeFileSync(path.join(gatewayRoot, '.env'), gatewayEnv, 'utf-8');
|
|
1041
|
+
fs.writeFileSync(path.join(gatewayRoot, '.env.example'), gatewayEnv, 'utf-8');
|
|
1042
|
+
patchLocalDependencies(gatewayRoot, null, boilerplatesDir);
|
|
1043
|
+
try {
|
|
1044
|
+
console.log(`[Gateway] Instalando dependências em: ${gatewayRoot}...`);
|
|
1045
|
+
(0, child_process_1.execSync)('npm install', { cwd: gatewayRoot, stdio: 'inherit' });
|
|
1046
|
+
}
|
|
1047
|
+
catch (err) {
|
|
1048
|
+
console.warn(`[Aviso] Falha ao rodar "npm install" no API Gateway. Instale manualmente.`);
|
|
1049
|
+
}
|
|
1032
1050
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
const msEnv = `PORT=${port}
|
|
1051
|
+
const msRoot = path.join(backendRoot, 'services', entity.name);
|
|
1052
|
+
console.log(`Gerando Microsserviço para a entidade "${currentEntityName}" em: ${msRoot}...`);
|
|
1053
|
+
if (!fs.existsSync(msRoot) || !fs.existsSync(path.join(msRoot, 'src', 'app.module.ts'))) {
|
|
1054
|
+
console.log(`[Microsserviço] Inicializando estrutura do microsserviço...`);
|
|
1055
|
+
fs.ensureDirSync(msRoot);
|
|
1056
|
+
fs.copySync(nestTemplateDir, msRoot);
|
|
1057
|
+
// Limpa módulos desnecessários
|
|
1058
|
+
fs.removeSync(path.join(msRoot, 'src', 'modules', 'user'));
|
|
1059
|
+
fs.removeSync(path.join(msRoot, 'src', 'modules', 'auth'));
|
|
1060
|
+
// Injeta arquivos específicos de microsserviço
|
|
1061
|
+
fs.writeFileSync(path.join(msRoot, 'src', 'main.ts'), generateMsMainTs(port), 'utf-8');
|
|
1062
|
+
fs.writeFileSync(path.join(msRoot, 'src', 'app.module.ts'), generateMsAppModule(entity.name), 'utf-8');
|
|
1063
|
+
// Injeta env básico no microsserviço
|
|
1064
|
+
const msEnv = `PORT=${port}
|
|
1048
1065
|
DB_HOST=database
|
|
1049
1066
|
DB_PORT=3306
|
|
1050
1067
|
DB_USER=root
|
|
@@ -1052,130 +1069,145 @@ DB_PASSWORD=root
|
|
|
1052
1069
|
DB_NAME=devstroupe_${entity.name.toLowerCase()}
|
|
1053
1070
|
SERVICE_PORT=${port}
|
|
1054
1071
|
`;
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1072
|
+
fs.writeFileSync(path.join(msRoot, '.env'), msEnv, 'utf-8');
|
|
1073
|
+
fs.writeFileSync(path.join(msRoot, '.env.example'), msEnv, 'utf-8');
|
|
1074
|
+
patchLocalDependencies(msRoot, null, boilerplatesDir);
|
|
1075
|
+
try {
|
|
1076
|
+
console.log(`[Microsserviço] Instalando dependências em: ${msRoot}...`);
|
|
1077
|
+
(0, child_process_1.execSync)('npm install', { cwd: msRoot, stdio: 'inherit' });
|
|
1078
|
+
}
|
|
1079
|
+
catch (err) {
|
|
1080
|
+
console.warn(`[Aviso] Falha ao rodar "npm install" no microsserviço. Instale manualmente.`);
|
|
1081
|
+
}
|
|
1061
1082
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1083
|
+
const modulePath = path.join(msRoot, 'src', 'modules', entity.name);
|
|
1084
|
+
fs.ensureDirSync(path.join(modulePath, 'domain'));
|
|
1085
|
+
fs.ensureDirSync(path.join(modulePath, 'service'));
|
|
1086
|
+
fs.ensureDirSync(path.join(modulePath, 'infra', 'database'));
|
|
1087
|
+
fs.ensureDirSync(path.join(modulePath, 'infra', 'http'));
|
|
1088
|
+
// Domain Entity
|
|
1089
|
+
fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.ts`), (0, cli_templates_1.nestDomainEntityTemplate)(entity.name, backendProperties, isTenantScoped, entity.automaticFields), 'utf-8');
|
|
1090
|
+
// Repository Port
|
|
1091
|
+
fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.repository.port.ts`), (0, cli_templates_1.nestRepositoryPortTemplate)(entity.name), 'utf-8');
|
|
1092
|
+
// DTO
|
|
1093
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.dto.ts`), (0, cli_templates_1.nestDtoTemplate)(entity.name, backendProperties), 'utf-8');
|
|
1094
|
+
// Controller (TCP)
|
|
1095
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.ms.controller.ts`), (0, cli_templates_1.nestMsControllerTemplate)(entity.name), 'utf-8');
|
|
1096
|
+
// ORM Entity
|
|
1097
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'database', `${entity.name}.orm-entity.ts`), (0, cli_templates_1.nestOrmEntityTemplate)(entity.name, backendProperties, entity.tableName || `${entity.name}s`, isTenantScoped, entity.indexes, entity.persistence, entity.automaticFields), 'utf-8');
|
|
1098
|
+
// Repository Adapter
|
|
1099
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'database', `${entity.name}.repository.ts`), (0, cli_templates_1.nestRepositoryAdapterTemplate)(entity.name, backendProperties, isTenantScoped), 'utf-8');
|
|
1100
|
+
// Service
|
|
1101
|
+
fs.writeFileSync(path.join(modulePath, 'service', `${entity.name}.service.ts`), (0, cli_templates_1.nestServiceTemplate)(entity.name), 'utf-8');
|
|
1102
|
+
// Module (TCP)
|
|
1103
|
+
fs.writeFileSync(path.join(modulePath, `${entity.name}.module.ts`), (0, cli_templates_1.nestMsModuleTemplate)(entity.name), 'utf-8');
|
|
1104
|
+
console.log(`[Microsserviço] Arquivos do microsserviço "${currentEntityName}" gerados com sucesso.`);
|
|
1105
|
+
if (entity.crud?.generateMigration !== false) {
|
|
1106
|
+
ensureInitialMigrations(msRoot, [entity], new Map([[entity.name, backendProperties]]));
|
|
1064
1107
|
}
|
|
1108
|
+
// --- Gerar API Gateway Module ---
|
|
1109
|
+
const gatewayModulePath = path.join(backendRoot, 'api-gateway', 'src', 'modules', entity.name);
|
|
1110
|
+
console.log(`Gerando Módulo Gateway para a entidade "${currentEntityName}" em: ${gatewayModulePath}...`);
|
|
1111
|
+
fs.ensureDirSync(path.join(gatewayModulePath, 'infra', 'http'));
|
|
1112
|
+
// DTO (Gateway)
|
|
1113
|
+
fs.writeFileSync(path.join(gatewayModulePath, 'infra', 'http', `${entity.name}.dto.ts`), (0, cli_templates_1.nestDtoTemplate)(entity.name, backendProperties), 'utf-8');
|
|
1114
|
+
// Controller (Gateway)
|
|
1115
|
+
fs.writeFileSync(path.join(gatewayModulePath, 'infra', 'http', `${entity.name}.controller.ts`), (0, cli_templates_1.nestGatewayControllerTemplate)(entity.name), 'utf-8');
|
|
1116
|
+
// Module (Gateway)
|
|
1117
|
+
fs.writeFileSync(path.join(gatewayModulePath, `${entity.name}.module.ts`), (0, cli_templates_1.nestGatewayModuleTemplate)(entity.name, port), 'utf-8');
|
|
1118
|
+
// Patch app.module.ts do Gateway
|
|
1119
|
+
patchGatewayAppModule(path.join(backendRoot, 'api-gateway', 'src', 'app.module.ts'), entity.name);
|
|
1120
|
+
console.log(`[Gateway] Módulo Gateway "${currentEntityName}" gerado com sucesso.`);
|
|
1065
1121
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1122
|
+
else {
|
|
1123
|
+
// Monolito
|
|
1124
|
+
console.log(`Gerando arquivos NestJS Monolito para a entidade "${currentEntityName}"...`);
|
|
1125
|
+
const modulePath = path.join(backendRoot, 'src', 'modules', entity.name);
|
|
1126
|
+
fs.ensureDirSync(path.join(modulePath, 'domain'));
|
|
1127
|
+
fs.ensureDirSync(path.join(modulePath, 'service'));
|
|
1128
|
+
fs.ensureDirSync(path.join(modulePath, 'infra', 'database'));
|
|
1129
|
+
fs.ensureDirSync(path.join(modulePath, 'infra', 'http'));
|
|
1130
|
+
// Domain Entity
|
|
1131
|
+
fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.ts`), (0, cli_templates_1.nestDomainEntityTemplate)(entity.name, entity.properties, isTenantScoped, entity.automaticFields), 'utf-8');
|
|
1132
|
+
// Repository Port
|
|
1133
|
+
fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.repository.port.ts`), (0, cli_templates_1.nestRepositoryPortTemplate)(entity.name), 'utf-8');
|
|
1134
|
+
// DTO
|
|
1135
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.dto.ts`), (0, cli_templates_1.nestDtoTemplate)(entity.name, entity.properties), 'utf-8');
|
|
1136
|
+
// Controller
|
|
1137
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.controller.ts`), (0, cli_templates_1.nestControllerTemplate)(entity.name, entity.persistence), 'utf-8');
|
|
1138
|
+
// ORM Entity
|
|
1139
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'database', `${entity.name}.orm-entity.ts`), (0, cli_templates_1.nestOrmEntityTemplate)(entity.name, entity.properties, entity.tableName || `${entity.name}s`, isTenantScoped, entity.indexes, entity.persistence, entity.automaticFields), 'utf-8');
|
|
1140
|
+
// Repository Adapter
|
|
1141
|
+
fs.writeFileSync(path.join(modulePath, 'infra', 'database', `${entity.name}.repository.ts`), (0, cli_templates_1.nestRepositoryAdapterTemplate)(entity.name, entity.properties, isTenantScoped), 'utf-8');
|
|
1142
|
+
// Service
|
|
1143
|
+
fs.writeFileSync(path.join(modulePath, 'service', `${entity.name}.service.ts`), (0, cli_templates_1.nestServiceTemplate)(entity.name), 'utf-8');
|
|
1144
|
+
// Module
|
|
1145
|
+
fs.writeFileSync(path.join(modulePath, `${entity.name}.module.ts`), (0, cli_templates_1.nestModuleTemplate)(entity.name), 'utf-8');
|
|
1146
|
+
console.log(`[NestJS] Módulo Monolito "${currentEntityName}" gerado com sucesso em: ${modulePath}`);
|
|
1147
|
+
patchMonolithAppModule(path.join(backendRoot, 'src', 'app.module.ts'), entity.name);
|
|
1090
1148
|
}
|
|
1091
|
-
// --- Gerar API Gateway Module ---
|
|
1092
|
-
const gatewayModulePath = path.join(backendRoot, 'api-gateway', 'src', 'modules', entity.name);
|
|
1093
|
-
console.log(`Gerando Módulo Gateway para a entidade "${entityName}" em: ${gatewayModulePath}...`);
|
|
1094
|
-
fs.ensureDirSync(path.join(gatewayModulePath, 'infra', 'http'));
|
|
1095
|
-
// DTO (Gateway)
|
|
1096
|
-
fs.writeFileSync(path.join(gatewayModulePath, 'infra', 'http', `${entity.name}.dto.ts`), (0, cli_templates_1.nestDtoTemplate)(entity.name, backendProperties), 'utf-8');
|
|
1097
|
-
// Controller (Gateway)
|
|
1098
|
-
fs.writeFileSync(path.join(gatewayModulePath, 'infra', 'http', `${entity.name}.controller.ts`), (0, cli_templates_1.nestGatewayControllerTemplate)(entity.name), 'utf-8');
|
|
1099
|
-
// Module (Gateway)
|
|
1100
|
-
fs.writeFileSync(path.join(gatewayModulePath, `${entity.name}.module.ts`), (0, cli_templates_1.nestGatewayModuleTemplate)(entity.name, port), 'utf-8');
|
|
1101
|
-
// Patch app.module.ts do Gateway
|
|
1102
|
-
patchGatewayAppModule(path.join(backendRoot, 'api-gateway', 'src', 'app.module.ts'), entity.name);
|
|
1103
|
-
console.log(`[Gateway] Módulo Gateway "${entityName}" gerado com sucesso.`);
|
|
1104
1149
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
console.log(`Gerando arquivos
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
fs.
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
fs.
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
// Service
|
|
1126
|
-
fs.writeFileSync(path.join(
|
|
1127
|
-
//
|
|
1128
|
-
fs.writeFileSync(path.join(modulePath, `${entity.name}.
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1150
|
+
// 2. Gerar Frontend (Angular)
|
|
1151
|
+
if (entity.crud?.generateFrontend !== false) {
|
|
1152
|
+
console.log(`Gerando arquivos Angular para a entidade "${currentEntityName}"...`);
|
|
1153
|
+
const servicePath = path.join(frontendRoot, 'src', 'app', 'services');
|
|
1154
|
+
const modulePath = path.join(frontendRoot, 'src', 'app', 'modules', entity.name);
|
|
1155
|
+
const uiComponentsDir = path.join(frontendRoot, 'src', 'app', 'shared', 'components', 'devkit');
|
|
1156
|
+
// Hook automático: se a pasta de design system local não existir no frontend, inicializa-a primeiro!
|
|
1157
|
+
if (!fs.existsSync(uiComponentsDir)) {
|
|
1158
|
+
console.log('[Autoconfig] Design System local não encontrado. Inicializando automaticamente...');
|
|
1159
|
+
initUi(frontendRoot, config);
|
|
1160
|
+
}
|
|
1161
|
+
const listType = entity.crud?.listType || config.designSystem?.defaultListType || 'table';
|
|
1162
|
+
const formType = entity.crud?.formType || 'page';
|
|
1163
|
+
const filterType = entity.crud?.filterType || 'popover';
|
|
1164
|
+
fs.ensureDirSync(servicePath);
|
|
1165
|
+
fs.ensureDirSync(path.join(modulePath, 'list'));
|
|
1166
|
+
fs.ensureDirSync(path.join(modulePath, 'form'));
|
|
1167
|
+
if (formType === 'dialog') {
|
|
1168
|
+
fs.ensureDirSync(path.join(modulePath, 'form-dialog-handler'));
|
|
1169
|
+
}
|
|
1170
|
+
// Angular Service
|
|
1171
|
+
fs.writeFileSync(path.join(servicePath, `${entity.name}.service.ts`), (0, cli_templates_1.angularServiceTemplate)(entity.name), 'utf-8');
|
|
1172
|
+
// List HTML
|
|
1173
|
+
fs.writeFileSync(path.join(modulePath, 'list', `${entity.name}-list.component.html`), (0, cli_templates_1.angularListHtmlTemplate)(entity.name, entity.properties, listType, formType, filterType), 'utf-8');
|
|
1174
|
+
// List TS
|
|
1175
|
+
fs.writeFileSync(path.join(modulePath, 'list', `${entity.name}-list.component.ts`), (0, cli_templates_1.angularListTsTemplate)(entity.name, entity.properties, listType, formType), 'utf-8');
|
|
1176
|
+
// Form HTML
|
|
1177
|
+
fs.writeFileSync(path.join(modulePath, 'form', `${entity.name}-form.component.html`), (0, cli_templates_1.angularFormHtmlTemplate)(entity.name, entity.properties, config.entities), 'utf-8');
|
|
1178
|
+
// Form TS
|
|
1179
|
+
fs.writeFileSync(path.join(modulePath, 'form', `${entity.name}-form.component.ts`), (0, cli_templates_1.angularFormTsTemplate)(entity.name, entity.properties, config.entities), 'utf-8');
|
|
1180
|
+
if (formType === 'dialog') {
|
|
1181
|
+
fs.writeFileSync(path.join(modulePath, 'form-dialog-handler', `${entity.name}-form-dialog-handler.component.html`), (0, cli_templates_1.angularFormDialogHandlerHtmlTemplate)(entity.name), 'utf-8');
|
|
1182
|
+
fs.writeFileSync(path.join(modulePath, 'form-dialog-handler', `${entity.name}-form-dialog-handler.component.ts`), (0, cli_templates_1.angularFormDialogHandlerTsTemplate)(entity.name), 'utf-8');
|
|
1135
1183
|
}
|
|
1184
|
+
console.log(`[Angular] Módulo "${currentEntityName}" gerado com sucesso em: ${modulePath}`);
|
|
1136
1185
|
}
|
|
1137
|
-
// Regerar docker-compose.yml e init.sql para sincronizar portas/bancos
|
|
1138
|
-
generateDockerComposeAndDbInit(process.cwd(), config);
|
|
1139
1186
|
}
|
|
1140
|
-
//
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
console.log('[Autoconfig] Design System local não encontrado. Inicializando automaticamente...');
|
|
1149
|
-
initUi(frontendRoot, config);
|
|
1150
|
-
}
|
|
1151
|
-
const listType = entity.crud?.listType || config.designSystem?.defaultListType || 'table';
|
|
1152
|
-
const formType = entity.crud?.formType || 'page';
|
|
1153
|
-
const filterType = entity.crud?.filterType || 'popover';
|
|
1154
|
-
fs.ensureDirSync(servicePath);
|
|
1155
|
-
fs.ensureDirSync(path.join(modulePath, 'list'));
|
|
1156
|
-
fs.ensureDirSync(path.join(modulePath, 'form'));
|
|
1157
|
-
if (formType === 'dialog') {
|
|
1158
|
-
fs.ensureDirSync(path.join(modulePath, 'form-dialog-handler'));
|
|
1159
|
-
}
|
|
1160
|
-
// Angular Service
|
|
1161
|
-
fs.writeFileSync(path.join(servicePath, `${entity.name}.service.ts`), (0, cli_templates_1.angularServiceTemplate)(entity.name), 'utf-8');
|
|
1162
|
-
// List HTML
|
|
1163
|
-
fs.writeFileSync(path.join(modulePath, 'list', `${entity.name}-list.component.html`), (0, cli_templates_1.angularListHtmlTemplate)(entity.name, entity.properties, listType, formType, filterType), 'utf-8');
|
|
1164
|
-
// List TS
|
|
1165
|
-
fs.writeFileSync(path.join(modulePath, 'list', `${entity.name}-list.component.ts`), (0, cli_templates_1.angularListTsTemplate)(entity.name, entity.properties, listType, formType), 'utf-8');
|
|
1166
|
-
// Form HTML
|
|
1167
|
-
fs.writeFileSync(path.join(modulePath, 'form', `${entity.name}-form.component.html`), (0, cli_templates_1.angularFormHtmlTemplate)(entity.name, entity.properties, config.entities), 'utf-8');
|
|
1168
|
-
// Form TS
|
|
1169
|
-
fs.writeFileSync(path.join(modulePath, 'form', `${entity.name}-form.component.ts`), (0, cli_templates_1.angularFormTsTemplate)(entity.name, entity.properties, config.entities), 'utf-8');
|
|
1170
|
-
if (formType === 'dialog') {
|
|
1171
|
-
fs.writeFileSync(path.join(modulePath, 'form-dialog-handler', `${entity.name}-form-dialog-handler.component.html`), (0, cli_templates_1.angularFormDialogHandlerHtmlTemplate)(entity.name), 'utf-8');
|
|
1172
|
-
fs.writeFileSync(path.join(modulePath, 'form-dialog-handler', `${entity.name}-form-dialog-handler.component.ts`), (0, cli_templates_1.angularFormDialogHandlerTsTemplate)(entity.name), 'utf-8');
|
|
1187
|
+
// 3. Pós-processamento geral (depois de gerar todas as entidades selecionadas)
|
|
1188
|
+
// Sincronizar migrações no Monolito, se houver
|
|
1189
|
+
const isMicroservices = config.backendType === 'microservices';
|
|
1190
|
+
if (!isMicroservices) {
|
|
1191
|
+
const migrationEntities = (config.entities ?? []).filter((configuredEntity) => configuredEntity.crud?.generateBackend !== false
|
|
1192
|
+
&& configuredEntity.crud?.generateMigration !== false);
|
|
1193
|
+
if (migrationEntities.length > 0) {
|
|
1194
|
+
ensureInitialMigrations(backendRoot, migrationEntities);
|
|
1173
1195
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1196
|
+
}
|
|
1197
|
+
// Regerar docker-compose.yml e init.sql
|
|
1198
|
+
generateDockerComposeAndDbInit(process.cwd(), config);
|
|
1199
|
+
// Se gerou frontend para alguma delas, atualiza as rotas uma vez
|
|
1200
|
+
const anyFrontendGenerated = entitiesToGenerate.some(e => e.crud?.generateFrontend !== false);
|
|
1201
|
+
if (anyFrontendGenerated) {
|
|
1176
1202
|
console.log('[Angular] Rotas e navegação serão sincronizadas automaticamente.');
|
|
1177
1203
|
updateAppRoutes(frontendRoot, config);
|
|
1178
1204
|
}
|
|
1205
|
+
if (isAll) {
|
|
1206
|
+
console.log(`\n\x1b[32m[SUCESSO] Scaffolding de CRUD completo para todas as entidades finalizado com sucesso!\x1b[0m`);
|
|
1207
|
+
}
|
|
1208
|
+
else {
|
|
1209
|
+
console.log(`\n\x1b[32m[SUCESSO] Scaffolding de CRUD completo para "${entitiesToGenerate[0].name}" finalizado!\x1b[0m`);
|
|
1210
|
+
}
|
|
1179
1211
|
});
|
|
1180
1212
|
// Helper para linkar dependências locais se estiver rodando no monorepo de desenvolvimento
|
|
1181
1213
|
function patchLocalDependencies(backendDest, frontendDest, boilerplatesDir) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devstroupe/devkit-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "DevsTroupe Development Kit CLI — scaffold NestJS+Angular projects, inject Spartan UI, generate CRUDs and audit architectural governance",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"commander": "^12.0.0",
|
|
38
38
|
"fs-extra": "^11.2.0",
|
|
39
|
-
"@devstroupe/devkit-core": "1.1.
|
|
39
|
+
"@devstroupe/devkit-core": "1.1.7"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/fs-extra": "^11.0.4",
|