@devstroupe/devkit-cli 1.1.7 → 1.1.9
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 +10 -1
- package/dist/templates/nest/migration.template.js +21 -15
- package/dist/templates/relationship-templates.test.js +3 -2
- package/dist/templates/ui/layout/header.template.js +104 -15
- package/dist/templates/ui/layout/main-layout.template.js +7 -0
- package/dist/templates/ui/shared/theme-service.template.js +30 -15
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -433,6 +433,13 @@ function initUi(frontendRoot, config) {
|
|
|
433
433
|
});
|
|
434
434
|
});
|
|
435
435
|
}
|
|
436
|
+
// Adicionar item de Permissões no final, visível apenas para quem tem manage:permissions
|
|
437
|
+
navigation.push({
|
|
438
|
+
label: 'Permissões',
|
|
439
|
+
icon: 'lucideShield',
|
|
440
|
+
route: '/role',
|
|
441
|
+
roles: ['manage:permissions']
|
|
442
|
+
});
|
|
436
443
|
}
|
|
437
444
|
const targetDir = path.join(frontendRoot, 'src', 'app', 'shared', 'components', 'devkit');
|
|
438
445
|
const layoutsDir = path.join(frontendRoot, 'src', 'app', 'shared', 'layouts', 'main-layout');
|
|
@@ -681,7 +688,9 @@ function updateMainLayoutNavigation(frontendRoot, entities = [], configuredNavig
|
|
|
681
688
|
label: entity.navigation?.label || entity.label || entity.name,
|
|
682
689
|
icon: entity.navigation?.icon || 'lucideTable',
|
|
683
690
|
route: `/${entity.name}`
|
|
684
|
-
}))
|
|
691
|
+
})),
|
|
692
|
+
// Item de Permissões fixo, visível apenas para quem tem manage:permissions
|
|
693
|
+
{ label: 'Permissões', icon: 'lucideShield', route: '/role', roles: ['manage:permissions'] }
|
|
685
694
|
];
|
|
686
695
|
writeAppNavigation(frontendRoot, navigation);
|
|
687
696
|
const content = fs.readFileSync(layoutPath, 'utf-8');
|
|
@@ -80,16 +80,25 @@ function nestMigrationTemplate(entity, entities, timestamp, properties = entity.
|
|
|
80
80
|
const relationColumns = relationships
|
|
81
81
|
.filter((relationship) => (0, relationships_1.isSingularRelationship)(relationship.kind))
|
|
82
82
|
.map((relationship) => ` { name: '${relationship.foreignKey}', type: 'int', isNullable: ${!relationship.property.required}, isUnique: ${relationship.kind === 'one-to-one'} }`);
|
|
83
|
-
|
|
83
|
+
// Gera SQL idempotente para cada FK: DROP IF EXISTS + ADD CONSTRAINT
|
|
84
|
+
const foreignKeysSql = relationships
|
|
84
85
|
.filter((relationship) => (0, relationships_1.isSingularRelationship)(relationship.kind))
|
|
85
|
-
.map((relationship) =>
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
.map((relationship) => {
|
|
87
|
+
const fkName = `FK_${tableName}_${relationship.foreignKey}`;
|
|
88
|
+
const refTable = targetTable(relationship.target, entities);
|
|
89
|
+
return [
|
|
90
|
+
` await queryRunner.query(\`ALTER TABLE \\\`${tableName}\\\` DROP FOREIGN KEY IF EXISTS \\\`${fkName}\\\`\`);`,
|
|
91
|
+
` await queryRunner.query(\`ALTER TABLE \\\`${tableName}\\\` ADD CONSTRAINT \\\`${fkName}\\\` FOREIGN KEY (\\\`${relationship.foreignKey}\\\`) REFERENCES \\\`${refTable}\\\`(\\\`${relationship.valueField}\\\`) ON DELETE ${relationship.onDelete}\`);`,
|
|
92
|
+
].join('\n');
|
|
93
|
+
})
|
|
94
|
+
.join('\n');
|
|
95
|
+
const dropForeignKeysSql = relationships
|
|
96
|
+
.filter((relationship) => (0, relationships_1.isSingularRelationship)(relationship.kind))
|
|
97
|
+
.map((relationship) => {
|
|
98
|
+
const fkName = `FK_${tableName}_${relationship.foreignKey}`;
|
|
99
|
+
return ` await queryRunner.query(\`ALTER TABLE \\\`${tableName}\\\` DROP FOREIGN KEY IF EXISTS \\\`${fkName}\\\`\`);`;
|
|
100
|
+
})
|
|
101
|
+
.join('\n');
|
|
93
102
|
const junctions = relationships
|
|
94
103
|
.filter((relationship) => relationship.kind === 'many-to-many' && relationship.owner)
|
|
95
104
|
.map((relationship) => {
|
|
@@ -154,7 +163,7 @@ function nestMigrationTemplate(entity, entities, timestamp, properties = entity.
|
|
|
154
163
|
return ` await queryRunner.query('ALTER TABLE \`${tableName}\` DROP CONSTRAINT \`${checkName}\`');`;
|
|
155
164
|
}).join('\n')
|
|
156
165
|
: '';
|
|
157
|
-
return `import { MigrationInterface, QueryRunner, Table,
|
|
166
|
+
return `import { MigrationInterface, QueryRunner, Table, TableIndex } from 'typeorm';
|
|
158
167
|
|
|
159
168
|
export class ${className} implements MigrationInterface {
|
|
160
169
|
name = '${className}';
|
|
@@ -166,10 +175,7 @@ export class ${className} implements MigrationInterface {
|
|
|
166
175
|
{ name: 'id', type: 'int', isPrimary: true, isGenerated: true, generationStrategy: 'increment' }${scalarColumns.length + relationColumns.length > 0 ? ',\n' : ''}${[...scalarColumns, ...relationColumns].join(',\n')}
|
|
167
176
|
]
|
|
168
177
|
}), true);
|
|
169
|
-
${
|
|
170
|
-
await queryRunner.createForeignKeys('${tableName}', [
|
|
171
|
-
${foreignKeys}
|
|
172
|
-
]);` : ''}
|
|
178
|
+
${foreignKeysSql ? `\n${foreignKeysSql}` : ''}
|
|
173
179
|
${tableIndexes ? `\n${tableIndexes}` : ''}
|
|
174
180
|
${checkConstraints ? `\n${checkConstraints}` : ''}
|
|
175
181
|
${junctions.map((junction) => `
|
|
@@ -177,7 +183,7 @@ ${junction.up}`).join('\n')}
|
|
|
177
183
|
}
|
|
178
184
|
|
|
179
185
|
async down(queryRunner: QueryRunner): Promise<void> {
|
|
180
|
-
${dropChecks ? `${dropChecks}\n` : ''}${dropIndexes ? `${dropIndexes}\n` : ''}${junctions.slice().reverse().map((junction) => ` await queryRunner.dropTable('${junction.tableName}', true);`).join('\n')}${junctions.length > 0 ? '\n' : ''} await queryRunner.dropTable('${tableName}', true);
|
|
186
|
+
${dropChecks ? `${dropChecks}\n` : ''}${dropIndexes ? `${dropIndexes}\n` : ''}${dropForeignKeysSql ? `${dropForeignKeysSql}\n` : ''}${junctions.slice().reverse().map((junction) => ` await queryRunner.dropTable('${junction.tableName}', true);`).join('\n')}${junctions.length > 0 ? '\n' : ''} await queryRunner.dropTable('${tableName}', true);
|
|
181
187
|
}
|
|
182
188
|
}
|
|
183
189
|
`;
|
|
@@ -149,8 +149,9 @@ function assertValidTypeScript(source) {
|
|
|
149
149
|
strict_1.default.match(companyMigration, /name: 'companies'/);
|
|
150
150
|
strict_1.default.doesNotMatch(companyMigration, /FK_companies_cabins/);
|
|
151
151
|
strict_1.default.match(cabinMigration, /name: 'company_id', type: 'int'/);
|
|
152
|
-
strict_1.default.match(cabinMigration, /
|
|
153
|
-
strict_1.default.match(cabinMigration, /
|
|
152
|
+
strict_1.default.match(cabinMigration, /ADD CONSTRAINT/);
|
|
153
|
+
strict_1.default.match(cabinMigration, /FK_cabins_company_id/);
|
|
154
|
+
strict_1.default.match(cabinMigration, /ON DELETE CASCADE/);
|
|
154
155
|
strict_1.default.match(dataSource, /migrations: \[path\.join/);
|
|
155
156
|
strict_1.default.match(dataSource, /synchronize: false/);
|
|
156
157
|
assertValidTypeScript(companyMigration);
|
|
@@ -8,11 +8,12 @@ import { CommonModule } from '@angular/common';
|
|
|
8
8
|
import { HlmButton } from '@spartan-ng/helm/button';
|
|
9
9
|
import { HlmInput } from '@spartan-ng/helm/input';
|
|
10
10
|
import { NgIconComponent } from '@ng-icons/core';
|
|
11
|
+
import type { ThemeMode } from '../../../core/services/theme.service';
|
|
11
12
|
|
|
12
13
|
export interface IUserProfile {
|
|
13
14
|
name: string;
|
|
14
15
|
avatar?: string;
|
|
15
|
-
role?: string
|
|
16
|
+
role?: any; // pode ser string ou { name: string, permissions: string[] }
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
@Component({
|
|
@@ -28,16 +29,35 @@ export class DevkitHeaderComponent {
|
|
|
28
29
|
@Input() user: IUserProfile | null = null;
|
|
29
30
|
@Input() isSidebarCollapsed = false;
|
|
30
31
|
@Input() isDarkMode = false;
|
|
32
|
+
@Input() themeMode: ThemeMode = 'auto';
|
|
31
33
|
|
|
32
34
|
@Output() toggleSidebar = new EventEmitter<void>();
|
|
33
35
|
@Output() logout = new EventEmitter<void>();
|
|
34
36
|
@Output() toggleTheme = new EventEmitter<void>();
|
|
35
37
|
@Output() openProfile = new EventEmitter<void>();
|
|
38
|
+
@Output() setThemeMode = new EventEmitter<ThemeMode>();
|
|
36
39
|
|
|
37
40
|
isProfileDropdownOpen = false;
|
|
41
|
+
isThemeDropdownOpen = false;
|
|
42
|
+
|
|
43
|
+
get roleName(): string {
|
|
44
|
+
if (!this.user?.role) return '';
|
|
45
|
+
return typeof this.user.role === 'object' ? (this.user.role.name ?? '') : this.user.role;
|
|
46
|
+
}
|
|
38
47
|
|
|
39
48
|
toggleProfileDropdown(): void {
|
|
40
49
|
this.isProfileDropdownOpen = !this.isProfileDropdownOpen;
|
|
50
|
+
this.isThemeDropdownOpen = false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
toggleThemeDropdown(): void {
|
|
54
|
+
this.isThemeDropdownOpen = !this.isThemeDropdownOpen;
|
|
55
|
+
this.isProfileDropdownOpen = false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
onSelectTheme(mode: ThemeMode): void {
|
|
59
|
+
this.isThemeDropdownOpen = false;
|
|
60
|
+
this.setThemeMode.emit(mode);
|
|
41
61
|
}
|
|
42
62
|
|
|
43
63
|
onLogoutClick(): void {
|
|
@@ -53,6 +73,18 @@ export class DevkitHeaderComponent {
|
|
|
53
73
|
onToggleTheme(): void {
|
|
54
74
|
this.toggleTheme.emit();
|
|
55
75
|
}
|
|
76
|
+
|
|
77
|
+
get themeIcon(): string {
|
|
78
|
+
if (this.themeMode === 'light') return 'lucideSun';
|
|
79
|
+
if (this.themeMode === 'dark') return 'lucideMoon';
|
|
80
|
+
return 'lucideMonitor';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get themeLabel(): string {
|
|
84
|
+
if (this.themeMode === 'light') return 'Light';
|
|
85
|
+
if (this.themeMode === 'dark') return 'Dark';
|
|
86
|
+
return 'Auto';
|
|
87
|
+
}
|
|
56
88
|
}
|
|
57
89
|
`,
|
|
58
90
|
html: `<header class="dt-header">
|
|
@@ -70,18 +102,35 @@ export class DevkitHeaderComponent {
|
|
|
70
102
|
|
|
71
103
|
<div class="flex items-center space-x-3">
|
|
72
104
|
|
|
73
|
-
<!--
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
105
|
+
<!-- Seletor de Tema (Light / Dark / Auto) -->
|
|
106
|
+
<div class="relative">
|
|
107
|
+
<button
|
|
108
|
+
hlmBtn
|
|
109
|
+
variant="ghost"
|
|
110
|
+
size="icon"
|
|
111
|
+
class="dt-header-action"
|
|
112
|
+
[title]="'Tema: ' + themeLabel"
|
|
113
|
+
(click)="toggleThemeDropdown()"
|
|
114
|
+
>
|
|
115
|
+
<ng-icon [name]="themeIcon" class="size-5"></ng-icon>
|
|
116
|
+
</button>
|
|
117
|
+
|
|
118
|
+
<!-- Dropdown de Tema -->
|
|
119
|
+
<div *ngIf="isThemeDropdownOpen" class="dt-theme-dropdown">
|
|
120
|
+
<button class="dt-theme-option" [class.dt-theme-option--active]="themeMode === 'light'" (click)="onSelectTheme('light')">
|
|
121
|
+
<ng-icon name="lucideSun" class="size-4 mr-2"></ng-icon>
|
|
122
|
+
Light
|
|
123
|
+
</button>
|
|
124
|
+
<button class="dt-theme-option" [class.dt-theme-option--active]="themeMode === 'dark'" (click)="onSelectTheme('dark')">
|
|
125
|
+
<ng-icon name="lucideMoon" class="size-4 mr-2"></ng-icon>
|
|
126
|
+
Dark
|
|
127
|
+
</button>
|
|
128
|
+
<button class="dt-theme-option" [class.dt-theme-option--active]="themeMode === 'auto'" (click)="onSelectTheme('auto')">
|
|
129
|
+
<ng-icon name="lucideMonitor" class="size-4 mr-2"></ng-icon>
|
|
130
|
+
Auto
|
|
131
|
+
</button>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
85
134
|
|
|
86
135
|
<!-- Notificações -->
|
|
87
136
|
<button *ngIf="showNotifications" hlmBtn variant="ghost" size="icon" class="dt-header-action relative" title="Notificações">
|
|
@@ -103,7 +152,7 @@ export class DevkitHeaderComponent {
|
|
|
103
152
|
</ng-template>
|
|
104
153
|
<div class="hidden md:flex flex-col text-left">
|
|
105
154
|
<span class="text-sm font-semibold leading-none text-foreground">{{ user.name }}</span>
|
|
106
|
-
<span *ngIf="
|
|
155
|
+
<span *ngIf="roleName" class="text-[10px] font-medium leading-none mt-1 text-muted-foreground">{{ roleName }}</span>
|
|
107
156
|
</div>
|
|
108
157
|
</button>
|
|
109
158
|
|
|
@@ -111,7 +160,7 @@ export class DevkitHeaderComponent {
|
|
|
111
160
|
<div *ngIf="isProfileDropdownOpen" class="dt-header-dropdown">
|
|
112
161
|
<div class="px-4 py-3 border-b border-border">
|
|
113
162
|
<p class="text-sm font-bold text-foreground">{{ user.name }}</p>
|
|
114
|
-
<p *ngIf="
|
|
163
|
+
<p *ngIf="roleName" class="text-xs text-muted-foreground mt-0.5">{{ roleName }}</p>
|
|
115
164
|
</div>
|
|
116
165
|
<button hlmBtn variant="ghost" (click)="onOpenProfile()" class="dt-header-dropdown-item">
|
|
117
166
|
<ng-icon name="lucideUser" class="size-4 mr-2"></ng-icon>
|
|
@@ -180,6 +229,46 @@ export class DevkitHeaderComponent {
|
|
|
180
229
|
width: 280px;
|
|
181
230
|
}
|
|
182
231
|
|
|
232
|
+
.dt-theme-dropdown {
|
|
233
|
+
position: absolute;
|
|
234
|
+
right: 0;
|
|
235
|
+
top: calc(100% + 8px);
|
|
236
|
+
width: 140px;
|
|
237
|
+
background-color: var(--popover);
|
|
238
|
+
color: var(--popover-foreground);
|
|
239
|
+
border: 1px solid var(--border);
|
|
240
|
+
border-radius: var(--radius);
|
|
241
|
+
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
242
|
+
z-index: 100;
|
|
243
|
+
display: flex;
|
|
244
|
+
flex-direction: column;
|
|
245
|
+
padding: 4px 0;
|
|
246
|
+
font-family: var(--font-family);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.dt-theme-option {
|
|
250
|
+
display: flex;
|
|
251
|
+
align-items: center;
|
|
252
|
+
width: 100%;
|
|
253
|
+
padding: 9px 14px;
|
|
254
|
+
background: transparent;
|
|
255
|
+
border: none;
|
|
256
|
+
font-size: 13px;
|
|
257
|
+
color: var(--popover-foreground);
|
|
258
|
+
cursor: pointer;
|
|
259
|
+
font-family: var(--font-family);
|
|
260
|
+
transition: background-color 0.15s ease-in-out;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.dt-theme-option:hover {
|
|
264
|
+
background-color: var(--muted);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.dt-theme-option--active {
|
|
268
|
+
color: var(--primary);
|
|
269
|
+
font-weight: 600;
|
|
270
|
+
}
|
|
271
|
+
|
|
183
272
|
.dt-header-dropdown {
|
|
184
273
|
position: absolute;
|
|
185
274
|
right: 0;
|
|
@@ -32,6 +32,7 @@ export class MainLayoutComponent implements OnInit {
|
|
|
32
32
|
menuItems: INavigationItem[] = APP_NAVIGATION;
|
|
33
33
|
currentUser$ = this.authService.currentUser$;
|
|
34
34
|
isDark$ = this.themeService.isDark$;
|
|
35
|
+
themeMode$ = this.themeService.themeMode$;
|
|
35
36
|
|
|
36
37
|
brandLogo = '${brandLogo}';
|
|
37
38
|
brandLogoCollapsed = '${brandLogoCollapsed}';
|
|
@@ -53,6 +54,10 @@ export class MainLayoutComponent implements OnInit {
|
|
|
53
54
|
this.themeService.toggle();
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
onSetThemeMode(mode: 'light' | 'dark' | 'auto'): void {
|
|
58
|
+
this.themeService.setMode(mode);
|
|
59
|
+
}
|
|
60
|
+
|
|
56
61
|
onOpenProfile(): void {
|
|
57
62
|
this.router.navigate(['/profile']);
|
|
58
63
|
}
|
|
@@ -87,9 +92,11 @@ export class MainLayoutComponent implements OnInit {
|
|
|
87
92
|
[user]="currentUser$ | async"
|
|
88
93
|
[isSidebarCollapsed]="isCollapsed"
|
|
89
94
|
[isDarkMode]="(isDark$ | async) ?? false"
|
|
95
|
+
[themeMode]="(themeMode$ | async) ?? 'auto'"
|
|
90
96
|
(toggleSidebar)="isCollapsed = !isCollapsed"
|
|
91
97
|
(logout)="onLogout()"
|
|
92
98
|
(toggleTheme)="onToggleTheme()"
|
|
99
|
+
(setThemeMode)="onSetThemeMode($event)"
|
|
93
100
|
(openProfile)="onOpenProfile()"
|
|
94
101
|
></devkit-header>
|
|
95
102
|
|
|
@@ -5,42 +5,57 @@ function devkitThemeServiceTemplate() {
|
|
|
5
5
|
return `import { Injectable } from '@angular/core';
|
|
6
6
|
import { BehaviorSubject } from 'rxjs';
|
|
7
7
|
|
|
8
|
+
export type ThemeMode = 'light' | 'dark' | 'auto';
|
|
9
|
+
|
|
8
10
|
const THEME_KEY = 'devkit-theme';
|
|
9
11
|
|
|
10
12
|
@Injectable({
|
|
11
13
|
providedIn: 'root'
|
|
12
14
|
})
|
|
13
15
|
export class ThemeService {
|
|
16
|
+
private modeSubject = new BehaviorSubject<ThemeMode>('auto');
|
|
14
17
|
private isDarkSubject = new BehaviorSubject<boolean>(false);
|
|
18
|
+
|
|
19
|
+
themeMode$ = this.modeSubject.asObservable();
|
|
15
20
|
isDark$ = this.isDarkSubject.asObservable();
|
|
16
21
|
|
|
17
|
-
get isDark(): boolean {
|
|
18
|
-
|
|
19
|
-
}
|
|
22
|
+
get isDark(): boolean { return this.isDarkSubject.getValue(); }
|
|
23
|
+
get mode(): ThemeMode { return this.modeSubject.getValue(); }
|
|
20
24
|
|
|
21
25
|
constructor() {
|
|
22
26
|
this.loadTheme();
|
|
27
|
+
window.matchMedia?.('(prefers-color-scheme: dark)')
|
|
28
|
+
.addEventListener('change', () => {
|
|
29
|
+
if (this.mode === 'auto') this.applyMode('auto');
|
|
30
|
+
});
|
|
23
31
|
}
|
|
24
32
|
|
|
33
|
+
/** Cicla entre light → dark → auto */
|
|
25
34
|
toggle(): void {
|
|
26
|
-
this.
|
|
35
|
+
const next: ThemeMode = this.mode === 'light' ? 'dark' : this.mode === 'dark' ? 'auto' : 'light';
|
|
36
|
+
this.setMode(next);
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
setMode(mode: ThemeMode): void {
|
|
40
|
+
this.modeSubject.next(mode);
|
|
41
|
+
localStorage.setItem(THEME_KEY, mode);
|
|
42
|
+
this.applyMode(mode);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** @deprecated use setMode */
|
|
46
|
+
setDark(dark: boolean): void { this.setMode(dark ? 'dark' : 'light'); }
|
|
47
|
+
|
|
48
|
+
private applyMode(mode: ThemeMode): void {
|
|
49
|
+
const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches ?? false;
|
|
50
|
+
const dark = mode === 'dark' || (mode === 'auto' && prefersDark);
|
|
30
51
|
this.isDarkSubject.next(dark);
|
|
31
|
-
|
|
32
|
-
if (dark) {
|
|
33
|
-
document.documentElement.classList.add('dark');
|
|
34
|
-
} else {
|
|
35
|
-
document.documentElement.classList.remove('dark');
|
|
36
|
-
}
|
|
52
|
+
document.documentElement.classList.toggle('dark', dark);
|
|
37
53
|
}
|
|
38
54
|
|
|
39
55
|
private loadTheme(): void {
|
|
40
|
-
const saved = localStorage.getItem(THEME_KEY);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.setDark(dark);
|
|
56
|
+
const saved = (localStorage.getItem(THEME_KEY) ?? 'auto') as ThemeMode;
|
|
57
|
+
this.modeSubject.next(saved);
|
|
58
|
+
this.applyMode(saved);
|
|
44
59
|
}
|
|
45
60
|
}
|
|
46
61
|
`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devstroupe/devkit-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
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.9"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/fs-extra": "^11.0.4",
|