@devstroupe/devkit-cli 1.0.1 → 1.1.0

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 (29) hide show
  1. package/dist/boilerplates/angular-template/src/app/services/user.service.ts +12 -0
  2. package/dist/boilerplates/nest-template/src/app.module.ts +23 -0
  3. package/dist/boilerplates/nest-template/src/database/migrations/1600000000000-create-roles.ts +20 -0
  4. package/dist/boilerplates/nest-template/src/database/migrations/1700000000000-create-users.ts +13 -2
  5. package/dist/boilerplates/nest-template/src/modules/auth/auth.controller.ts +16 -0
  6. package/dist/boilerplates/nest-template/src/modules/auth/auth.service.ts +44 -5
  7. package/dist/boilerplates/nest-template/src/modules/storage/infra/http/storage-download.controller.ts +38 -0
  8. package/dist/boilerplates/nest-template/src/modules/storage/storage.module.ts +7 -0
  9. package/dist/boilerplates/nest-template/src/modules/user/database-seed.service.ts +31 -18
  10. package/dist/boilerplates/nest-template/src/modules/user/domain/user.repository.ts +1 -0
  11. package/dist/boilerplates/nest-template/src/modules/user/domain/user.ts +1 -0
  12. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.orm-entity.ts +3 -0
  13. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.repository.adapter.ts +6 -0
  14. package/dist/boilerplates/nest-template/src/modules/user/infra/http/user.controller.ts +56 -0
  15. package/dist/boilerplates/nest-template/src/modules/user/service/user.service.ts +4 -0
  16. package/dist/boilerplates/nest-template/src/modules/user/user.module.ts +2 -0
  17. package/dist/index.js +24 -3
  18. package/dist/templates/angular/form.template.js +85 -9
  19. package/dist/templates/angular/list.template.js +27 -5
  20. package/dist/templates/nest/crud.templates.d.ts +16 -2
  21. package/dist/templates/nest/crud.templates.js +175 -13
  22. package/dist/templates/nest/migration.template.js +82 -6
  23. package/dist/templates/shared/relationships.js +7 -4
  24. package/dist/templates/ui/components/index.d.ts +1 -0
  25. package/dist/templates/ui/components/index.js +1 -0
  26. package/dist/templates/ui/components/input.template.js +17 -9
  27. package/dist/templates/ui/components/textarea.template.d.ts +4 -0
  28. package/dist/templates/ui/components/textarea.template.js +76 -0
  29. package/package.json +3 -3
@@ -17,17 +17,19 @@ function normalizeRelationship(property) {
17
17
  throw new Error(`Relationship property "${property.name}" must define relation.target.`);
18
18
  }
19
19
  const config = property.relation;
20
+ const rawTarget = config.target;
21
+ const target = rawTarget.startsWith('$') ? rawTarget.slice(1) : rawTarget;
20
22
  const kind = config.kind ?? 'many-to-one';
21
23
  const collection = isCollectionRelationship(kind);
22
24
  const relationName = config.relationName
23
- ?? (collection ? property.name : config.target);
25
+ ?? (collection ? property.name : target);
24
26
  const control = config.control
25
27
  ?? (kind === 'one-to-many' ? 'table' : kind === 'many-to-many' ? 'multi-select' : 'select');
26
28
  const foreignKey = config.foreignKey
27
29
  ?? (isSingularRelationship(kind) ? property.name : undefined);
28
30
  return {
29
31
  property,
30
- target: config.target,
32
+ target,
31
33
  kind,
32
34
  control,
33
35
  displayField: config.displayField ?? 'name',
@@ -61,7 +63,8 @@ function validateRelationships(entities) {
61
63
  if (property.type !== 'relationship')
62
64
  continue;
63
65
  const relationship = normalizeRelationship(property);
64
- if (!entityNames.has(relationship.target)) {
66
+ const targetIsNative = ['user', 'role'].includes(relationship.target);
67
+ if (!entityNames.has(relationship.target) && !targetIsNative) {
65
68
  throw new Error(`Entity "${entity.name}" relationship "${property.name}" targets unknown entity "${relationship.target}".`);
66
69
  }
67
70
  if (isSingularRelationship(relationship.kind) && relationship.foreignKey === relationship.relationName) {
@@ -76,7 +79,7 @@ function validateRelationships(entities) {
76
79
  if (relationship.kind === 'one-to-many' && !relationship.foreignKey) {
77
80
  throw new Error(`Entity "${entity.name}" one-to-many relationship "${property.name}" must define relation.foreignKey.`);
78
81
  }
79
- if (relationship.kind === 'one-to-many') {
82
+ if (relationship.kind === 'one-to-many' && !targetIsNative) {
80
83
  const target = entities.find((candidate) => candidate.name === relationship.target);
81
84
  const targetHasForeignKey = target?.properties.some((candidate) => candidate.name === relationship.foreignKey
82
85
  || (candidate.type === 'relationship'
@@ -8,3 +8,4 @@ export * from './simple-list.template';
8
8
  export * from './dialog.template';
9
9
  export * from './badge.template';
10
10
  export * from './avatar.template';
11
+ export * from './textarea.template';
@@ -24,3 +24,4 @@ __exportStar(require("./simple-list.template"), exports);
24
24
  __exportStar(require("./dialog.template"), exports);
25
25
  __exportStar(require("./badge.template"), exports);
26
26
  __exportStar(require("./avatar.template"), exports);
27
+ __exportStar(require("./textarea.template"), exports);
@@ -25,6 +25,7 @@ export class DevkitInputComponent implements ControlValueAccessor {
25
25
  @Input() label = '';
26
26
  @Input() placeholder = '';
27
27
  @Input() type = 'text';
28
+ @Input() prefix = '';
28
29
  @Input() required = false;
29
30
  @Input() disabled = false;
30
31
 
@@ -60,15 +61,22 @@ export class DevkitInputComponent implements ControlValueAccessor {
60
61
  <label *ngIf="label" class="text-xs font-semibold text-muted-foreground">
61
62
  {{ label }}<span *ngIf="required" class="text-destructive ml-0.5">*</span>
62
63
  </label>
63
- <input
64
- hlmInput
65
- [type]="type"
66
- [value]="value"
67
- [placeholder]="placeholder"
68
- [disabled]="disabled"
69
- (input)="onInput($event)"
70
- (blur)="onTouched()"
71
- />
64
+ <div class="relative flex items-center w-full">
65
+ <span *ngIf="prefix" class="absolute left-3 text-sm text-muted-foreground select-none pointer-events-none">
66
+ {{ prefix }}
67
+ </span>
68
+ <input
69
+ hlmInput
70
+ [type]="type"
71
+ [value]="value"
72
+ [placeholder]="placeholder"
73
+ [disabled]="disabled"
74
+ (input)="onInput($event)"
75
+ (blur)="onTouched()"
76
+ [class.pl-9]="prefix"
77
+ class="w-full"
78
+ />
79
+ </div>
72
80
  </div>
73
81
  `
74
82
  };
@@ -0,0 +1,4 @@
1
+ export declare function devkitTextareaTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitTextareaTemplate = devkitTextareaTemplate;
4
+ function devkitTextareaTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, forwardRef } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
9
+ import { HlmInput } from '@spartan-ng/helm/input';
10
+
11
+ @Component({
12
+ selector: 'devkit-textarea',
13
+ standalone: true,
14
+ imports: [CommonModule, FormsModule, HlmInput],
15
+ templateUrl: './textarea.component.html',
16
+ providers: [
17
+ {
18
+ provide: NG_VALUE_ACCESSOR,
19
+ useExisting: forwardRef(() => DevkitTextareaComponent),
20
+ multi: true
21
+ }
22
+ ]
23
+ })
24
+ export class DevkitTextareaComponent implements ControlValueAccessor {
25
+ @Input() label = '';
26
+ @Input() placeholder = '';
27
+ @Input() rows = 3;
28
+ @Input() required = false;
29
+ @Input() disabled = false;
30
+
31
+ value: string = '';
32
+
33
+ onChange: any = () => {};
34
+ onTouched: any = () => {};
35
+
36
+ writeValue(value: any): void {
37
+ this.value = value || '';
38
+ }
39
+
40
+ registerOnChange(fn: any): void {
41
+ this.onChange = fn;
42
+ }
43
+
44
+ registerOnTouched(fn: any): void {
45
+ this.onTouched = fn;
46
+ }
47
+
48
+ setDisabledState(isDisabled: boolean): void {
49
+ this.disabled = isDisabled;
50
+ }
51
+
52
+ onInput(event: Event): void {
53
+ const val = (event.target as HTMLTextAreaElement).value;
54
+ this.value = val;
55
+ this.onChange(val);
56
+ }
57
+ }
58
+ `,
59
+ html: `<div class="flex flex-col space-y-1.5 w-full">
60
+ <label *ngIf="label" class="text-xs font-semibold text-muted-foreground">
61
+ {{ label }}<span *ngIf="required" class="text-destructive ml-0.5">*</span>
62
+ </label>
63
+ <textarea
64
+ hlmInput
65
+ [rows]="rows"
66
+ [value]="value"
67
+ [placeholder]="placeholder"
68
+ [disabled]="disabled"
69
+ (input)="onInput($event)"
70
+ (blur)="onTouched()"
71
+ class="min-h-[80px]"
72
+ ></textarea>
73
+ </div>
74
+ `
75
+ };
76
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devstroupe/devkit-cli",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
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": [
@@ -34,9 +34,9 @@
34
34
  "devstroupe": "./dist/index.js"
35
35
  },
36
36
  "dependencies": {
37
- "@devstroupe/devkit-core": "^1.0.0",
38
37
  "commander": "^12.0.0",
39
- "fs-extra": "^11.2.0"
38
+ "fs-extra": "^11.2.0",
39
+ "@devstroupe/devkit-core": "1.1.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/fs-extra": "^11.0.4",