@devstroupe/devkit-cli 1.1.2 → 1.1.3
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/boilerplates/angular-template/proxy.conf.json +1 -1
- package/dist/boilerplates/angular-template/src/app/modules/role/role-permissions.component.ts +7 -0
- package/dist/boilerplates/nest-template/src/app.module.ts +3 -0
- package/dist/boilerplates/nest-template/src/main.ts +0 -7
- package/dist/boilerplates/nest-template/src/modules/user/database-seed.service.ts +17 -5
- package/dist/index.js +57 -19
- package/dist/templates/ui/layout/sidebar.template.js +47 -3
- package/package.json +2 -2
package/dist/boilerplates/angular-template/src/app/modules/role/role-permissions.component.ts
CHANGED
|
@@ -81,6 +81,7 @@ export class RolePermissionsComponent implements OnInit {
|
|
|
81
81
|
|
|
82
82
|
hasPermission(action: string, resource: string): boolean {
|
|
83
83
|
if (!this.selectedRole) return false;
|
|
84
|
+
if (this.selectedRole.permissions.includes('*')) return true;
|
|
84
85
|
const permission = `${action}:${resource}`;
|
|
85
86
|
return this.selectedRole.permissions.includes(permission);
|
|
86
87
|
}
|
|
@@ -98,6 +99,7 @@ export class RolePermissionsComponent implements OnInit {
|
|
|
98
99
|
|
|
99
100
|
hasSpecialPermission(permission: string): boolean {
|
|
100
101
|
if (!this.selectedRole) return false;
|
|
102
|
+
if (this.selectedRole.permissions.includes('*')) return true;
|
|
101
103
|
return this.selectedRole.permissions.includes(permission);
|
|
102
104
|
}
|
|
103
105
|
|
|
@@ -118,6 +120,11 @@ export class RolePermissionsComponent implements OnInit {
|
|
|
118
120
|
this.successMessage = '';
|
|
119
121
|
this.errorMessage = '';
|
|
120
122
|
|
|
123
|
+
// Se for o perfil do Administrador, garantimos que a permissão curinga '*' continue salva
|
|
124
|
+
if (this.selectedRole.name === 'Administrador' && !this.selectedRole.permissions.includes('*')) {
|
|
125
|
+
this.selectedRole.permissions.push('*');
|
|
126
|
+
}
|
|
127
|
+
|
|
121
128
|
this.roleService.update(this.selectedRole.id, this.selectedRole).subscribe({
|
|
122
129
|
next: (updated: any) => {
|
|
123
130
|
this.isSaving = false;
|
|
@@ -5,6 +5,7 @@ import { UserModule } from './modules/user/user.module';
|
|
|
5
5
|
import { AuthModule } from './modules/auth/auth.module';
|
|
6
6
|
import { RoleModule } from './modules/role/role.module';
|
|
7
7
|
import { StorageDownloadModule } from './modules/storage/storage.module';
|
|
8
|
+
import * as path from 'path';
|
|
8
9
|
|
|
9
10
|
@Module({
|
|
10
11
|
imports: [
|
|
@@ -17,6 +18,8 @@ import { StorageDownloadModule } from './modules/storage/storage.module';
|
|
|
17
18
|
database: process.env.DB_NAME || 'devstroupe',
|
|
18
19
|
autoLoadEntities: true,
|
|
19
20
|
synchronize: false,
|
|
21
|
+
migrations: [path.join(__dirname, './database/migrations/*{.ts,.js}')],
|
|
22
|
+
migrationsRun: true,
|
|
20
23
|
}),
|
|
21
24
|
(StorageModule as any).registerAsync({
|
|
22
25
|
useFactory: () => ({
|
|
@@ -20,7 +20,6 @@ if (fs.existsSync(envPath)) {
|
|
|
20
20
|
import { NestFactory } from '@nestjs/core';
|
|
21
21
|
import { AppModule } from './app.module';
|
|
22
22
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
23
|
-
import { DataSource } from 'typeorm';
|
|
24
23
|
|
|
25
24
|
async function bootstrap() {
|
|
26
25
|
const app = await NestFactory.create(AppModule);
|
|
@@ -40,12 +39,6 @@ async function bootstrap() {
|
|
|
40
39
|
const document = SwaggerModule.createDocument(app, config);
|
|
41
40
|
SwaggerModule.setup('docs', app, document);
|
|
42
41
|
|
|
43
|
-
// Executar migrations programaticamente antes de iniciar a aplicação
|
|
44
|
-
const dataSource = app.get(DataSource);
|
|
45
|
-
console.log('Executando migrations do banco de dados...');
|
|
46
|
-
await dataSource.runMigrations();
|
|
47
|
-
console.log('Migrations executadas com sucesso!');
|
|
48
|
-
|
|
49
42
|
await app.listen(13000);
|
|
50
43
|
console.log('Backend NestJS iniciado com sucesso na porta 13000!');
|
|
51
44
|
console.log('Documentação Swagger disponível em: http://localhost:13000/docs');
|
|
@@ -19,17 +19,25 @@ export class DatabaseSeedService implements OnApplicationBootstrap {
|
|
|
19
19
|
try {
|
|
20
20
|
const isProduction = process.env.NODE_ENV === 'production';
|
|
21
21
|
|
|
22
|
+
const allPermissions = [
|
|
23
|
+
'*',
|
|
24
|
+
'read:cabin', 'create:cabin', 'update:cabin', 'delete:cabin',
|
|
25
|
+
'read:company', 'create:company', 'update:company', 'delete:company',
|
|
26
|
+
'read:role', 'create:role', 'update:role', 'delete:role', 'manage:permissions'
|
|
27
|
+
];
|
|
28
|
+
|
|
22
29
|
// 1. Criar Perfil Administrador se não existir
|
|
23
30
|
let adminRole = await this.roleService.findByName('Administrador');
|
|
24
31
|
if (!adminRole) {
|
|
25
32
|
this.logger.log('Semente: Criando Perfil Administrador...');
|
|
26
33
|
adminRole = await this.roleService.create({
|
|
27
34
|
name: 'Administrador',
|
|
28
|
-
permissions:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
permissions: allPermissions,
|
|
36
|
+
});
|
|
37
|
+
} else if (!adminRole.permissions.includes('*')) {
|
|
38
|
+
this.logger.log('Semente: Atualizando Perfil Administrador com curinga *...');
|
|
39
|
+
adminRole = await this.roleService.update(adminRole.id, {
|
|
40
|
+
permissions: [...new Set(['*', ...adminRole.permissions])],
|
|
33
41
|
});
|
|
34
42
|
}
|
|
35
43
|
|
|
@@ -61,6 +69,8 @@ export class DatabaseSeedService implements OnApplicationBootstrap {
|
|
|
61
69
|
password: adminPassword || 'adminpassword123',
|
|
62
70
|
role: adminRole,
|
|
63
71
|
isActive: true,
|
|
72
|
+
createdAt: new Date(),
|
|
73
|
+
updatedAt: new Date()
|
|
64
74
|
});
|
|
65
75
|
this.logger.log('Semente: Usuário administrador cadastrado com sucesso!');
|
|
66
76
|
}
|
|
@@ -77,6 +87,8 @@ export class DatabaseSeedService implements OnApplicationBootstrap {
|
|
|
77
87
|
password: 'userpassword123',
|
|
78
88
|
role: userRole,
|
|
79
89
|
isActive: true,
|
|
90
|
+
createdAt: new Date(),
|
|
91
|
+
updatedAt: new Date()
|
|
80
92
|
});
|
|
81
93
|
this.logger.log('Semente: Usuário comum cadastrado com sucesso!');
|
|
82
94
|
}
|
package/dist/index.js
CHANGED
|
@@ -1192,6 +1192,8 @@ function patchLocalDependencies(backendDest, frontendDest, boilerplatesDir) {
|
|
|
1192
1192
|
return;
|
|
1193
1193
|
const packageJson = fs.readJsonSync(packagePath);
|
|
1194
1194
|
delete packageJson.devDependencies;
|
|
1195
|
+
delete packageJson.peerDependencies;
|
|
1196
|
+
delete packageJson.dependencies;
|
|
1195
1197
|
packageJson.scripts = {};
|
|
1196
1198
|
fs.writeJsonSync(packagePath, packageJson, { spaces: 2 });
|
|
1197
1199
|
};
|
|
@@ -1750,7 +1752,7 @@ ${gatewayDependsOn}`;
|
|
|
1750
1752
|
- "14200:4200"
|
|
1751
1753
|
command: sh -c "npm install && npm run start -- --host 0.0.0.0 --poll 2000"
|
|
1752
1754
|
depends_on:
|
|
1753
|
-
- backend
|
|
1755
|
+
- backend
|
|
1754
1756
|
`;
|
|
1755
1757
|
}
|
|
1756
1758
|
const dockerComposeContent = `version: '3.8'
|
|
@@ -1927,12 +1929,13 @@ R2_SECRET_KEY=
|
|
|
1927
1929
|
// 3.2 Criar Makefile na raiz
|
|
1928
1930
|
console.log('Gerando arquivo Makefile na raiz...');
|
|
1929
1931
|
const backendServiceName = isMicroservices ? 'api-gateway' : 'backend';
|
|
1930
|
-
const makefileContent = `.PHONY: up down restart build logs ps clean backend-shell frontend-shell db-shell help
|
|
1931
|
-
|
|
1932
|
+
const makefileContent = `.PHONY: up down restart build logs ps clean backend-shell frontend-shell db-shell dev-up dev-down dev-restart dev-build dev-logs dev-ps dev-clean help
|
|
1933
|
+
|
|
1932
1934
|
DC = docker compose
|
|
1933
|
-
|
|
1935
|
+
DC_DEV = docker compose -f docker-compose.dev.yml
|
|
1936
|
+
|
|
1934
1937
|
help:
|
|
1935
|
-
@echo "Comandos disponíveis:"
|
|
1938
|
+
@echo "Comandos disponíveis (Produção):"
|
|
1936
1939
|
@echo " make up Inicia os containers em background"
|
|
1937
1940
|
@echo " make down Para os containers e mantém os dados"
|
|
1938
1941
|
@echo " make restart Reinicia os containers"
|
|
@@ -1940,40 +1943,75 @@ help:
|
|
|
1940
1943
|
@echo " make logs Exibe os logs em tempo real"
|
|
1941
1944
|
@echo " make ps Exibe o status dos containers"
|
|
1942
1945
|
@echo " make clean Para os containers e apaga todos os volumes (reseta o banco)"
|
|
1946
|
+
@echo ""
|
|
1947
|
+
@echo "Comandos disponíveis (Desenvolvimento local com Live Reload):"
|
|
1948
|
+
@echo " make dev-up Inicia os containers dev em background"
|
|
1949
|
+
@echo " make dev-down Para os containers dev e mantém os dados"
|
|
1950
|
+
@echo " make dev-restart Reinicia os containers dev"
|
|
1951
|
+
@echo " make dev-build Reconstrói as imagens dev Docker"
|
|
1952
|
+
@echo " make dev-logs Exibe os logs dev em tempo real"
|
|
1953
|
+
@echo " make dev-ps Exibe o status dos containers dev"
|
|
1954
|
+
@echo " make dev-clean Para os containers dev e apaga todos os volumes (reseta o banco)"
|
|
1955
|
+
@echo ""
|
|
1956
|
+
@echo "Utilitários:"
|
|
1943
1957
|
@echo " make backend-shell Abre o terminal sh do container do backend"
|
|
1944
1958
|
@echo " make frontend-shell Abre o terminal sh do container do frontend"
|
|
1945
1959
|
@echo " make db-shell Abre o cliente mysql no container do banco"
|
|
1946
|
-
|
|
1960
|
+
|
|
1961
|
+
# --- Produção ---
|
|
1947
1962
|
up:
|
|
1948
1963
|
\$(DC) up -d
|
|
1949
|
-
|
|
1964
|
+
|
|
1950
1965
|
down:
|
|
1951
1966
|
\$(DC) down
|
|
1952
|
-
|
|
1967
|
+
|
|
1953
1968
|
restart:
|
|
1954
1969
|
\$(DC) restart
|
|
1955
|
-
|
|
1970
|
+
|
|
1956
1971
|
build:
|
|
1957
1972
|
\$(DC) build
|
|
1958
|
-
|
|
1973
|
+
|
|
1959
1974
|
logs:
|
|
1960
1975
|
\$(DC) logs -f
|
|
1961
|
-
|
|
1976
|
+
|
|
1962
1977
|
ps:
|
|
1963
1978
|
\$(DC) ps
|
|
1964
|
-
|
|
1979
|
+
|
|
1965
1980
|
clean:
|
|
1966
1981
|
\$(DC) down -v
|
|
1967
|
-
|
|
1982
|
+
|
|
1983
|
+
# --- Desenvolvimento ---
|
|
1984
|
+
dev-up:
|
|
1985
|
+
\$(DC_DEV) up -d
|
|
1986
|
+
|
|
1987
|
+
dev-down:
|
|
1988
|
+
\$(DC_DEV) down
|
|
1989
|
+
|
|
1990
|
+
dev-restart:
|
|
1991
|
+
\$(DC_DEV) restart
|
|
1992
|
+
|
|
1993
|
+
dev-build:
|
|
1994
|
+
\$(DC_DEV) build
|
|
1995
|
+
|
|
1996
|
+
dev-logs:
|
|
1997
|
+
\$(DC_DEV) logs -f
|
|
1998
|
+
|
|
1999
|
+
dev-ps:
|
|
2000
|
+
\$(DC_DEV) ps
|
|
2001
|
+
|
|
2002
|
+
dev-clean:
|
|
2003
|
+
\$(DC_DEV) down -v
|
|
2004
|
+
|
|
2005
|
+
# --- Utilitários ---
|
|
1968
2006
|
backend-shell:
|
|
1969
|
-
\$(DC) exec ${backendServiceName} sh
|
|
1970
|
-
|
|
2007
|
+
\$(DC_DEV) exec -it ${backendServiceName} sh || \$(DC) exec -it ${backendServiceName} sh
|
|
2008
|
+
|
|
1971
2009
|
frontend-shell:
|
|
1972
|
-
\$(DC) exec frontend sh
|
|
1973
|
-
|
|
2010
|
+
\$(DC_DEV) exec -it frontend sh || \$(DC) exec -it frontend sh
|
|
2011
|
+
|
|
1974
2012
|
db-shell:
|
|
1975
|
-
\$(DC) exec database mysql -u root -p
|
|
1976
|
-
|
|
2013
|
+
\$(DC_DEV) exec -it database mysql -u root -p || \$(DC) exec -it database mysql -u root -p
|
|
2014
|
+
|
|
1977
2015
|
# Evita que argumentos (ex: main, staging) sejam interpretados como target
|
|
1978
2016
|
%:
|
|
1979
2017
|
@:
|
|
@@ -3,11 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.devkitSidebarTemplate = devkitSidebarTemplate;
|
|
4
4
|
function devkitSidebarTemplate() {
|
|
5
5
|
return {
|
|
6
|
-
ts: `import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
6
|
+
ts: `import { Component, EventEmitter, Input, OnInit, Output, inject } from '@angular/core';
|
|
7
7
|
import { CommonModule } from '@angular/common';
|
|
8
8
|
import { RouterModule, Router, NavigationEnd } from '@angular/router';
|
|
9
9
|
import { NgIconComponent } from '@ng-icons/core';
|
|
10
10
|
import { filter } from 'rxjs/operators';
|
|
11
|
+
import { DEVKIT_AUTH_SERVICE } from '@devstroupe/devkit-angular';
|
|
11
12
|
|
|
12
13
|
export interface INavigationItem {
|
|
13
14
|
label: string;
|
|
@@ -26,13 +27,26 @@ export interface INavigationItem {
|
|
|
26
27
|
styleUrls: ['./sidebar.component.css']
|
|
27
28
|
})
|
|
28
29
|
export class DevkitSidebarComponent implements OnInit {
|
|
29
|
-
|
|
30
|
+
private _items: INavigationItem[] = [];
|
|
31
|
+
filteredItems: INavigationItem[] = [];
|
|
32
|
+
|
|
33
|
+
@Input() set items(value: INavigationItem[]) {
|
|
34
|
+
this._items = value || [];
|
|
35
|
+
this.filterItems();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get items(): INavigationItem[] {
|
|
39
|
+
return this._items;
|
|
40
|
+
}
|
|
41
|
+
|
|
30
42
|
@Input() brandLogo = '';
|
|
31
43
|
@Input() brandLogoCollapsed = '';
|
|
32
44
|
@Input() brandName = '';
|
|
33
45
|
@Input() isCollapsed = false;
|
|
34
46
|
@Output() closeSidebar = new EventEmitter<void>();
|
|
35
47
|
|
|
48
|
+
private authService = inject(DEVKIT_AUTH_SERVICE, { optional: true });
|
|
49
|
+
|
|
36
50
|
expandedItems = new Set<string>();
|
|
37
51
|
currentUrl = '';
|
|
38
52
|
|
|
@@ -45,6 +59,36 @@ export class DevkitSidebarComponent implements OnInit {
|
|
|
45
59
|
.subscribe((event: any) => {
|
|
46
60
|
this.currentUrl = event.urlAfterRedirects || event.url;
|
|
47
61
|
});
|
|
62
|
+
this.filterItems();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
filterItems(): void {
|
|
66
|
+
if (!this._items) {
|
|
67
|
+
this.filteredItems = [];
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.filteredItems = this._items.filter(item => {
|
|
72
|
+
if (!item.roles || item.roles.length === 0) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
if (!this.authService) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return item.roles.some(role => this.authService!.hasPermission(role));
|
|
79
|
+
}).map(item => {
|
|
80
|
+
if (item.children) {
|
|
81
|
+
return {
|
|
82
|
+
...item,
|
|
83
|
+
children: item.children.filter(child => {
|
|
84
|
+
if (!child.roles || child.roles.length === 0) return true;
|
|
85
|
+
if (!this.authService) return true;
|
|
86
|
+
return child.roles.some(role => this.authService!.hasPermission(role));
|
|
87
|
+
})
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return item;
|
|
91
|
+
});
|
|
48
92
|
}
|
|
49
93
|
|
|
50
94
|
toggleExpand(label: string): void {
|
|
@@ -119,7 +163,7 @@ export class DevkitSidebarComponent implements OnInit {
|
|
|
119
163
|
<!-- Menu / Navegação -->
|
|
120
164
|
<nav class="dt-sidebar-nav">
|
|
121
165
|
<ul class="dt-sidebar-list">
|
|
122
|
-
<li *ngFor="let item of
|
|
166
|
+
<li *ngFor="let item of filteredItems">
|
|
123
167
|
|
|
124
168
|
<!-- Link Simples (Sem Filhos) -->
|
|
125
169
|
<a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devstroupe/devkit-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
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.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/fs-extra": "^11.0.4",
|