@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.
Files changed (2) hide show
  1. package/dist/index.js +202 -170
  2. 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
- const entity = config.entities?.find((e) => e.name.toLowerCase() === entityName.toLowerCase());
980
- if (!entity) {
981
- console.error(`Entidade "${entityName}" não configurada no devstroupe.config.ts.`);
982
- process.exit(1);
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
- // 1. Gerar Backend (NestJS)
987
- if (entity.crud?.generateBackend !== false) {
988
- const isMultiTenant = !!config.multiTenant?.enabled;
989
- const isTenantScoped = isMultiTenant && (entity.tenantScoped !== false);
990
- const isMicroservices = config.backendType === 'microservices';
991
- const backendProperties = isMicroservices
992
- ? entity.properties
993
- .filter((property) => property.type !== 'relationship' || (0, relationships_1.getRelationships)([property])[0].kind !== 'one-to-many')
994
- .map((property) => property.type === 'relationship'
995
- ? { ...property, type: 'number', name: (0, relationships_1.getRelationships)([property])[0].foreignKey }
996
- : property)
997
- : entity.properties;
998
- let boilerplatesDir = path.resolve(__dirname, 'boilerplates');
999
- if (!fs.existsSync(boilerplatesDir)) {
1000
- boilerplatesDir = path.resolve(__dirname, '../boilerplates');
1001
- }
1002
- if (!fs.existsSync(boilerplatesDir)) {
1003
- boilerplatesDir = path.resolve(__dirname, '../../boilerplates');
1004
- }
1005
- const nestTemplateDir = path.join(boilerplatesDir, 'nest-template');
1006
- if (isMicroservices) {
1007
- const entityIndex = config.entities.findIndex((e) => e.name.toLowerCase() === entity.name.toLowerCase());
1008
- const port = 3001 + (entityIndex >= 0 ? entityIndex : 0);
1009
- // Garantir estrutura do API Gateway
1010
- const gatewayRoot = path.join(backendRoot, 'api-gateway');
1011
- if (!fs.existsSync(gatewayRoot) || !fs.existsSync(path.join(gatewayRoot, 'src', 'app.module.ts'))) {
1012
- console.log(`[Gateway] Inicializando estrutura do API Gateway...`);
1013
- fs.ensureDirSync(gatewayRoot);
1014
- fs.copySync(nestTemplateDir, gatewayRoot);
1015
- const gatewayEnv = `PORT=13000
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
- fs.writeFileSync(path.join(gatewayRoot, '.env'), gatewayEnv, 'utf-8');
1024
- fs.writeFileSync(path.join(gatewayRoot, '.env.example'), gatewayEnv, 'utf-8');
1025
- patchLocalDependencies(gatewayRoot, null, boilerplatesDir);
1026
- try {
1027
- console.log(`[Gateway] Instalando dependências em: ${gatewayRoot}...`);
1028
- (0, child_process_1.execSync)('npm install', { cwd: gatewayRoot, stdio: 'inherit' });
1029
- }
1030
- catch (err) {
1031
- console.warn(`[Aviso] Falha ao rodar "npm install" no API Gateway. Instale manualmente.`);
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
- const msRoot = path.join(backendRoot, 'services', entity.name);
1035
- console.log(`Gerando Microsserviço para a entidade "${entityName}" em: ${msRoot}...`);
1036
- if (!fs.existsSync(msRoot) || !fs.existsSync(path.join(msRoot, 'src', 'app.module.ts'))) {
1037
- console.log(`[Microsserviço] Inicializando estrutura do microsserviço...`);
1038
- fs.ensureDirSync(msRoot);
1039
- fs.copySync(nestTemplateDir, msRoot);
1040
- // Limpa módulos desnecessários
1041
- fs.removeSync(path.join(msRoot, 'src', 'modules', 'user'));
1042
- fs.removeSync(path.join(msRoot, 'src', 'modules', 'auth'));
1043
- // Injeta arquivos específicos de microsserviço
1044
- fs.writeFileSync(path.join(msRoot, 'src', 'main.ts'), generateMsMainTs(port), 'utf-8');
1045
- fs.writeFileSync(path.join(msRoot, 'src', 'app.module.ts'), generateMsAppModule(entity.name), 'utf-8');
1046
- // Injeta env básico no microsserviço
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
- fs.writeFileSync(path.join(msRoot, '.env'), msEnv, 'utf-8');
1056
- fs.writeFileSync(path.join(msRoot, '.env.example'), msEnv, 'utf-8');
1057
- patchLocalDependencies(msRoot, null, boilerplatesDir);
1058
- try {
1059
- console.log(`[Microsserviço] Instalando dependências em: ${msRoot}...`);
1060
- (0, child_process_1.execSync)('npm install', { cwd: msRoot, stdio: 'inherit' });
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
- catch (err) {
1063
- console.warn(`[Aviso] Falha ao rodar "npm install" no microsserviço. Instale manualmente.`);
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
- const modulePath = path.join(msRoot, 'src', 'modules', entity.name);
1067
- fs.ensureDirSync(path.join(modulePath, 'domain'));
1068
- fs.ensureDirSync(path.join(modulePath, 'service'));
1069
- fs.ensureDirSync(path.join(modulePath, 'infra', 'database'));
1070
- fs.ensureDirSync(path.join(modulePath, 'infra', 'http'));
1071
- // Domain Entity
1072
- fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.ts`), (0, cli_templates_1.nestDomainEntityTemplate)(entity.name, backendProperties, isTenantScoped, entity.automaticFields), 'utf-8');
1073
- // Repository Port
1074
- fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.repository.port.ts`), (0, cli_templates_1.nestRepositoryPortTemplate)(entity.name), 'utf-8');
1075
- // DTO
1076
- fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.dto.ts`), (0, cli_templates_1.nestDtoTemplate)(entity.name, backendProperties), 'utf-8');
1077
- // Controller (TCP)
1078
- fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.ms.controller.ts`), (0, cli_templates_1.nestMsControllerTemplate)(entity.name), 'utf-8');
1079
- // ORM Entity
1080
- 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');
1081
- // Repository Adapter
1082
- fs.writeFileSync(path.join(modulePath, 'infra', 'database', `${entity.name}.repository.ts`), (0, cli_templates_1.nestRepositoryAdapterTemplate)(entity.name, backendProperties, isTenantScoped), 'utf-8');
1083
- // Service
1084
- fs.writeFileSync(path.join(modulePath, 'service', `${entity.name}.service.ts`), (0, cli_templates_1.nestServiceTemplate)(entity.name), 'utf-8');
1085
- // Module (TCP)
1086
- fs.writeFileSync(path.join(modulePath, `${entity.name}.module.ts`), (0, cli_templates_1.nestMsModuleTemplate)(entity.name), 'utf-8');
1087
- console.log(`[Microsserviço] Arquivos do microsserviço "${entityName}" gerados com sucesso.`);
1088
- if (entity.crud?.generateMigration !== false) {
1089
- ensureInitialMigrations(msRoot, [entity], new Map([[entity.name, backendProperties]]));
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
- else {
1106
- // Monolito
1107
- console.log(`Gerando arquivos NestJS Monolito para a entidade "${entityName}"...`);
1108
- const modulePath = path.join(backendRoot, 'src', 'modules', entity.name);
1109
- fs.ensureDirSync(path.join(modulePath, 'domain'));
1110
- fs.ensureDirSync(path.join(modulePath, 'service'));
1111
- fs.ensureDirSync(path.join(modulePath, 'infra', 'database'));
1112
- fs.ensureDirSync(path.join(modulePath, 'infra', 'http'));
1113
- // Domain Entity
1114
- fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.ts`), (0, cli_templates_1.nestDomainEntityTemplate)(entity.name, entity.properties, isTenantScoped, entity.automaticFields), 'utf-8');
1115
- // Repository Port
1116
- fs.writeFileSync(path.join(modulePath, 'domain', `${entity.name}.repository.port.ts`), (0, cli_templates_1.nestRepositoryPortTemplate)(entity.name), 'utf-8');
1117
- // DTO
1118
- fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.dto.ts`), (0, cli_templates_1.nestDtoTemplate)(entity.name, entity.properties), 'utf-8');
1119
- // Controller
1120
- fs.writeFileSync(path.join(modulePath, 'infra', 'http', `${entity.name}.controller.ts`), (0, cli_templates_1.nestControllerTemplate)(entity.name, entity.persistence), 'utf-8');
1121
- // ORM Entity
1122
- 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');
1123
- // Repository Adapter
1124
- fs.writeFileSync(path.join(modulePath, 'infra', 'database', `${entity.name}.repository.ts`), (0, cli_templates_1.nestRepositoryAdapterTemplate)(entity.name, entity.properties, isTenantScoped), 'utf-8');
1125
- // Service
1126
- fs.writeFileSync(path.join(modulePath, 'service', `${entity.name}.service.ts`), (0, cli_templates_1.nestServiceTemplate)(entity.name), 'utf-8');
1127
- // Module
1128
- fs.writeFileSync(path.join(modulePath, `${entity.name}.module.ts`), (0, cli_templates_1.nestModuleTemplate)(entity.name), 'utf-8');
1129
- console.log(`[NestJS] Módulo Monolito "${entityName}" gerado com sucesso em: ${modulePath}`);
1130
- patchMonolithAppModule(path.join(backendRoot, 'src', 'app.module.ts'), entity.name);
1131
- const migrationEntities = (config.entities ?? []).filter((configuredEntity) => configuredEntity.crud?.generateBackend !== false
1132
- && configuredEntity.crud?.generateMigration !== false);
1133
- if (migrationEntities.length > 0) {
1134
- ensureInitialMigrations(backendRoot, migrationEntities);
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
- // 2. Gerar Frontend (Angular)
1141
- if (entity.crud?.generateFrontend !== false) {
1142
- console.log(`Gerando arquivos Angular para a entidade "${entityName}"...`);
1143
- const servicePath = path.join(frontendRoot, 'src', 'app', 'services');
1144
- const modulePath = path.join(frontendRoot, 'src', 'app', 'modules', entity.name);
1145
- const uiComponentsDir = path.join(frontendRoot, 'src', 'app', 'shared', 'components', 'devkit');
1146
- // Hook automático: se a pasta de design system local não existir no frontend, inicializa-a primeiro!
1147
- if (!fs.existsSync(uiComponentsDir)) {
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
- console.log(`[Angular] Módulo "${entityName}" gerado com sucesso em: ${modulePath}`);
1175
- console.log(`\n\x1b[32m[SUCESSO] Scaffolding de CRUD completo para "${entityName}" finalizado!\x1b[0m`);
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.5",
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.5"
39
+ "@devstroupe/devkit-core": "1.1.7"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/fs-extra": "^11.0.4",