@devmed555/angular-clean-architecture-cli 0.0.2 → 0.0.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.
Files changed (56) hide show
  1. package/README.md +425 -0
  2. package/bin/index.js +100 -2
  3. package/generators.json +19 -9
  4. package/package.json +1 -1
  5. package/src/generators/core/files/auth/auth.guard.ts.template +14 -0
  6. package/src/generators/core/files/auth/auth.service.ts.template +137 -0
  7. package/src/generators/core/files/auth/login.component.ts.template +165 -0
  8. package/src/generators/core/files/auth/signup.component.ts.template +171 -0
  9. package/src/generators/core/files/guard/__name__.guard.ts.template +6 -0
  10. package/src/generators/core/files/interceptor/__name__.interceptor.ts.template +6 -0
  11. package/src/generators/core/files/language-selector/language-selector.component.ts.template +82 -0
  12. package/src/generators/core/files/menu/__name__.component.html.template +14 -0
  13. package/src/generators/core/files/menu/__name__.component.scss.template +66 -0
  14. package/src/generators/core/files/menu/__name__.component.ts.template +24 -0
  15. package/src/generators/core/files/navbar/__name__.component.html.template +45 -0
  16. package/src/generators/core/files/navbar/__name__.component.scss.template +134 -0
  17. package/src/generators/core/files/navbar/__name__.component.ts.template +38 -0
  18. package/src/generators/core/files/service/__name__.service.ts.template +26 -0
  19. package/src/generators/core/files/theme-selector/theme-selector.component.ts.template +49 -0
  20. package/src/generators/core/files/translate/translate.pipe.ts.template +15 -0
  21. package/src/generators/core/files/translate/translate.service.ts.template +24 -0
  22. package/src/generators/core/generator.d.ts +7 -0
  23. package/src/generators/core/generator.js +49 -0
  24. package/src/generators/core/generator.js.map +1 -0
  25. package/src/generators/core/schema.json +34 -0
  26. package/src/generators/feature/blueprint.schema.json +34 -0
  27. package/src/generators/feature/files/application/store.ts.template +135 -0
  28. package/src/generators/feature/files/domain/model.ts.template +9 -0
  29. package/src/generators/{clean-feature → feature}/files/infrastructure/service.ts.template +5 -5
  30. package/src/generators/feature/files/ui/__singularName__.component.html.template +109 -0
  31. package/src/generators/feature/files/ui/__singularName__.component.scss.template +162 -0
  32. package/src/generators/feature/files/ui/__singularName__.component.ts.template +131 -0
  33. package/src/generators/feature/files/ui/_theme.scss.template +35 -0
  34. package/src/generators/feature/files/ui/form/form.component.ts.template +122 -0
  35. package/src/generators/feature/generator.d.ts +4 -0
  36. package/src/generators/feature/generator.js +209 -0
  37. package/src/generators/feature/generator.js.map +1 -0
  38. package/src/generators/feature/schema.d.ts +5 -0
  39. package/src/generators/{clean-feature → feature}/schema.json +25 -21
  40. package/src/generators/shared/files/ui/__name__.component.ts.template +57 -0
  41. package/src/generators/shared/files/util/__name__.ts.template +7 -0
  42. package/src/generators/shared/generator.d.ts +7 -0
  43. package/src/generators/shared/generator.js +31 -0
  44. package/src/generators/shared/generator.js.map +1 -0
  45. package/src/generators/shared/schema.json +23 -0
  46. package/src/index.js +1 -0
  47. package/src/utils/string-utils.d.ts +16 -0
  48. package/src/utils/string-utils.js +33 -0
  49. package/src/utils/string-utils.js.map +1 -0
  50. package/src/generators/clean-feature/files/application/store.ts.template +0 -6
  51. package/src/generators/clean-feature/files/domain/model.ts.template +0 -4
  52. package/src/generators/clean-feature/files/ui/component.ts.template +0 -44
  53. package/src/generators/clean-feature/generator.d.ts +0 -4
  54. package/src/generators/clean-feature/generator.js +0 -89
  55. package/src/generators/clean-feature/generator.js.map +0 -1
  56. package/src/generators/clean-feature/schema.d.ts +0 -4
@@ -0,0 +1,209 @@
1
+ import { formatFiles, generateFiles, joinPathFragments, } from '@nx/devkit';
2
+ import inquirer from 'inquirer';
3
+ import { toPascalCase, pluralize } from '../../utils/string-utils';
4
+ /**
5
+ * Load or create feature schema for persistence
6
+ */
7
+ function loadFeatureSchema(tree) {
8
+ const schemaPath = 'feature-schema.json';
9
+ if (tree.exists(schemaPath)) {
10
+ const content = tree.read(schemaPath);
11
+ if (content) {
12
+ return JSON.parse(content.toString());
13
+ }
14
+ }
15
+ return {
16
+ version: '1.0',
17
+ lastUpdated: new Date().toISOString(),
18
+ features: {},
19
+ };
20
+ }
21
+ /**
22
+ * Save feature schema
23
+ */
24
+ function saveFeatureSchema(tree, schema) {
25
+ schema.lastUpdated = new Date().toISOString();
26
+ tree.write('feature-schema.json', JSON.stringify(schema, null, 2));
27
+ }
28
+ /**
29
+ * Updates app.routes.ts to include the new feature
30
+ */
31
+ function updateAppRoutes(tree, featureName, folderName, pascalName) {
32
+ const routesPath = 'apps/sandbox/src/app/app.routes.ts';
33
+ if (!tree.exists(routesPath))
34
+ return;
35
+ let content = tree.read(routesPath).toString();
36
+ // Check if route already exists
37
+ if (content.includes(`path: '${folderName}'`))
38
+ return;
39
+ const newRoute = ` {
40
+ path: '${folderName}',
41
+ loadComponent: () => import('./features/${folderName}/ui/${featureName}.component').then(m => m.${pascalName}Component),
42
+ data: { label: '${pascalName}s' }
43
+ },`;
44
+ // Find the appRoutes array
45
+ const routesArrayRegex = /export const appRoutes: Route\[\] = \[([\s\S]*?)\];/;
46
+ const match = content.match(routesArrayRegex);
47
+ if (match) {
48
+ const existingRoutes = match[1].trim();
49
+ let updatedRoutes = existingRoutes;
50
+ if (existingRoutes && !existingRoutes.endsWith(',')) {
51
+ updatedRoutes += ',';
52
+ }
53
+ updatedRoutes += `\n${newRoute}`;
54
+ content = content.replace(routesArrayRegex, `export const appRoutes: Route[] = [${updatedRoutes}\n];`);
55
+ tree.write(routesPath, content);
56
+ }
57
+ }
58
+ export async function featureGenerator(tree, options) {
59
+ // 0. Bulk Generation from Schema
60
+ if (!options.name && !options.blueprint) {
61
+ const schema = loadFeatureSchema(tree);
62
+ const featureNames = Object.keys(schema.features || {});
63
+ if (featureNames.length > 0) {
64
+ console.log(`\n🚀 Found ${featureNames.length} features in feature-schema.json. Generating...`);
65
+ for (const name of featureNames) {
66
+ const feature = schema.features[name];
67
+ // Convert stored attributes back to string format for recursivity or handle manually
68
+ const attributesStr = feature.attributes
69
+ .map((a) => `${a.name}:${a.type}`)
70
+ .join(',');
71
+ console.log(`Generating feature: ${name}`);
72
+ await featureGenerator(tree, {
73
+ ...options,
74
+ name: feature.name,
75
+ attributes: attributesStr,
76
+ });
77
+ }
78
+ return;
79
+ }
80
+ }
81
+ let featureName = options.name; // Keep original singular name
82
+ let attributes = [];
83
+ let models = [];
84
+ // Load existing schema
85
+ const featureSchema = loadFeatureSchema(tree);
86
+ // 1. Blueprint Mode
87
+ if (options.blueprint) {
88
+ try {
89
+ const blueprintContent = tree.read(options.blueprint);
90
+ if (!blueprintContent) {
91
+ throw new Error(`Blueprint file not found at ${options.blueprint}`);
92
+ }
93
+ const blueprint = JSON.parse(blueprintContent.toString());
94
+ if (!blueprint.name) {
95
+ throw new Error('Blueprint is missing "name" property.');
96
+ }
97
+ featureName = blueprint.name;
98
+ if (blueprint.models && Array.isArray(blueprint.models)) {
99
+ models = blueprint.models.map((m) => ({
100
+ name: toPascalCase(m.name),
101
+ attributes: m.attributes || [],
102
+ }));
103
+ }
104
+ else {
105
+ models = [
106
+ {
107
+ name: toPascalCase(featureName),
108
+ attributes: [],
109
+ },
110
+ ];
111
+ }
112
+ console.log(`Loaded feature "${featureName}" from blueprint.`);
113
+ }
114
+ catch (e) {
115
+ console.error(`Error reading blueprint: ${e}`);
116
+ throw e;
117
+ }
118
+ }
119
+ // 3. Interactive/Manual Mode
120
+ if (!featureName) {
121
+ const questions = [
122
+ {
123
+ type: 'input',
124
+ name: 'name',
125
+ message: 'What is the name of the feature (singular)?',
126
+ validate: (input) => input.length > 0 ? true : 'Name is required',
127
+ },
128
+ ];
129
+ const answers = await inquirer.prompt(questions);
130
+ featureName = answers.name;
131
+ }
132
+ // Get attributes if not already loaded
133
+ if (attributes.length === 0 && models.length === 0) {
134
+ if (options.attributes) {
135
+ attributes = options.attributes.split(',').map((attr) => {
136
+ const [n, t] = attr.split(':');
137
+ return { name: n.trim(), type: t?.trim() || 'string' };
138
+ });
139
+ }
140
+ else {
141
+ console.log("Let's add some attributes (property fields).");
142
+ let addingAttributes = true;
143
+ while (addingAttributes) {
144
+ const { attrName } = await inquirer.prompt([
145
+ {
146
+ type: 'input',
147
+ name: 'attrName',
148
+ message: 'Enter attribute name (or press enter to finish):',
149
+ },
150
+ ]);
151
+ if (!attrName || attrName.trim() === '') {
152
+ addingAttributes = false;
153
+ break;
154
+ }
155
+ const { attrType } = await inquirer.prompt([
156
+ {
157
+ type: 'list',
158
+ name: 'attrType',
159
+ message: 'Select type:',
160
+ choices: ['string', 'number', 'boolean', 'Date', 'any'],
161
+ default: 'string',
162
+ },
163
+ ]);
164
+ attributes.push({ name: attrName, type: attrType });
165
+ }
166
+ }
167
+ // Save to schema for future use
168
+ if (attributes.length > 0) {
169
+ featureSchema.features[featureName] = {
170
+ name: featureName,
171
+ attributes: attributes,
172
+ };
173
+ saveFeatureSchema(tree, featureSchema);
174
+ console.log(`✓ Feature schema saved for future use`);
175
+ }
176
+ }
177
+ // Build models if not from blueprint
178
+ if (models.length === 0) {
179
+ models = [
180
+ {
181
+ name: toPascalCase(featureName), // Singular PascalCase (e.g., "Order")
182
+ attributes: attributes,
183
+ },
184
+ ];
185
+ }
186
+ // Generate folder name (pluralized)
187
+ const folderName = pluralize(featureName);
188
+ const targetPath = joinPathFragments('apps/sandbox/src/app/features', folderName);
189
+ // Use singular PascalCase for class names
190
+ const singularPascalName = toPascalCase(featureName);
191
+ // Extract attributes from the primary model
192
+ const primaryAttributes = models.length > 0 ? models[0].attributes : [];
193
+ // Generate files from templates
194
+ generateFiles(tree, joinPathFragments(__dirname, 'files'), targetPath, {
195
+ ...options,
196
+ name: folderName, // Pluralized for folder
197
+ singularName: featureName, // Original singular name
198
+ pascalName: singularPascalName, // Singular PascalCase for classes
199
+ models,
200
+ attributes: primaryAttributes,
201
+ tmpl: '',
202
+ });
203
+ // 4. Update Routes
204
+ updateAppRoutes(tree, featureName, folderName, singularPascalName);
205
+ await formatFiles(tree);
206
+ console.log(`\n✓ Generated feature "${featureName}" in ${targetPath}`);
207
+ }
208
+ export default featureGenerator;
209
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../apps/cli/src/generators/feature/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface FeatureGeneratorSchema {
2
+ name: string;
3
+ attributes?: string;
4
+ blueprint?: string;
5
+ }
@@ -1,21 +1,25 @@
1
- {
2
- "$schema": "https://json-schema.org/schema",
3
- "$id": "CleanFeature",
4
- "title": "",
5
- "type": "object",
6
- "properties": {
7
- "name": {
8
- "type": "string",
9
- "description": "The name of the feature to generate",
10
- "$default": {
11
- "$source": "argv",
12
- "index": 0
13
- }
14
- },
15
- "attributes": {
16
- "type": "string",
17
- "description": "Comma-separated list of attributes (e.g., name:string,age:number)"
18
- }
19
- },
20
- "required": []
21
- }
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "CleanFeature",
4
+ "title": "",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "The name of the feature to generate",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ }
14
+ },
15
+ "attributes": {
16
+ "type": "string",
17
+ "description": "Comma-separated list of attributes (e.g., name:string,age:number)"
18
+ },
19
+ "blueprint": {
20
+ "type": "string",
21
+ "description": "Path to a JSON blueprint file defining the feature"
22
+ }
23
+ },
24
+ "required": []
25
+ }
@@ -0,0 +1,57 @@
1
+ <% if (name === 'confirm-dialog') { %>
2
+ import { Component, inject, ChangeDetectionStrategy } from '@angular/core';
3
+ import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
4
+ import { MatButtonModule } from '@angular/material/button';
5
+
6
+ export interface ConfirmDialogData {
7
+ title: string;
8
+ message: string;
9
+ }
10
+
11
+ @Component({
12
+ selector: 'app-<%= name %>',
13
+ imports: [MatDialogModule, MatButtonModule],
14
+ template: `
15
+ <h2 mat-dialog-title>{{ data.title }}</h2>
16
+ <mat-dialog-content>
17
+ <p>{{ data.message }}</p>
18
+ </mat-dialog-content>
19
+ <mat-dialog-actions align="end">
20
+ <button mat-button (click)="onCancel()">Cancel</button>
21
+ <button mat-raised-button color="warn" (click)="onConfirm()">Confirm</button>
22
+ </mat-dialog-actions>
23
+ `,
24
+ styles: `
25
+ mat-dialog-content p {
26
+ margin: 1rem 0;
27
+ }
28
+ `,
29
+ changeDetection: ChangeDetectionStrategy.OnPush
30
+ })
31
+ export class <%= pascalName %>Component {
32
+ private readonly dialogRef = inject(MatDialogRef<<%= pascalName %>Component>);
33
+ protected readonly data = inject<ConfirmDialogData>(MAT_DIALOG_DATA);
34
+
35
+ onCancel(): void {
36
+ this.dialogRef.close(false);
37
+ }
38
+
39
+ onConfirm(): void {
40
+ this.dialogRef.close(true);
41
+ }
42
+ }
43
+ <% } else { %>
44
+ import { Component, ChangeDetectionStrategy } from '@angular/core';
45
+ import { CommonModule } from '@angular/common';
46
+
47
+ @Component({
48
+ selector: 'app-<%= name %>',
49
+ imports: [CommonModule],
50
+ template: `
51
+ <p><%= name %> works!</p>
52
+ `,
53
+ styles: ``,
54
+ changeDetection: ChangeDetectionStrategy.OnPush,
55
+ })
56
+ export class <%= pascalName %>Component {}
57
+ <% } %>
@@ -0,0 +1,7 @@
1
+ /**
2
+ * <%= pascalName %> utility function
3
+ */
4
+ export function <%= camelName %>() {
5
+ // TODO: Implement utility logic
6
+ return true;
7
+ }
@@ -0,0 +1,7 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export declare function sharedGenerator(tree: Tree, options: SharedGeneratorSchema): Promise<void>;
3
+ export default sharedGenerator;
4
+ export interface SharedGeneratorSchema {
5
+ name?: string;
6
+ type: 'all' | 'ui' | 'util';
7
+ }
@@ -0,0 +1,31 @@
1
+ import { formatFiles, generateFiles, joinPathFragments, } from '@nx/devkit';
2
+ import { toPascalCase, toCamelCase } from '../../utils/string-utils';
3
+ export async function sharedGenerator(tree, options) {
4
+ if (options.type === 'all') {
5
+ // Generate a standard set of UI components
6
+ const commonComponents = ['confirm-dialog'];
7
+ console.log(`\n🚀 Generating standard shared UI components: ${commonComponents.join(', ')}...`);
8
+ for (const name of commonComponents) {
9
+ await sharedGenerator(tree, { ...options, type: 'ui', name });
10
+ }
11
+ return;
12
+ }
13
+ if (!options.name) {
14
+ if (options.type === 'ui')
15
+ options.name = 'button'; // default
16
+ if (options.type === 'util')
17
+ options.name = 'format'; // default
18
+ }
19
+ const targetPath = joinPathFragments('apps/sandbox/src/app/shared', options.type, options.name);
20
+ const pascalName = toPascalCase(options.name);
21
+ generateFiles(tree, joinPathFragments(__dirname, 'files', options.type), targetPath, {
22
+ ...options,
23
+ pascalName,
24
+ camelName: toCamelCase(options.name),
25
+ tmpl: '',
26
+ });
27
+ await formatFiles(tree);
28
+ console.log(`✓ Generated shared ${options.type} "${options.name}" in ${targetPath}`);
29
+ }
30
+ export default sharedGenerator;
31
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../apps/cli/src/generators/shared/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EACb,iBAAiB,GAElB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAU,EACV,OAA8B;IAE9B,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,2CAA2C;QAC3C,MAAM,gBAAgB,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CACT,kDAAkD,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CACnF,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;YACpC,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC,UAAU;QAC9D,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC,UAAU;IAClE,CAAC;IAED,MAAM,UAAU,GAAG,iBAAiB,CAClC,6BAA6B,EAC7B,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,IAAK,CACd,CAAC;IAEF,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,IAAK,CAAC,CAAC;IAE/C,aAAa,CACX,IAAI,EACJ,iBAAiB,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,EACnD,UAAU,EACV;QACE,GAAG,OAAO;QACV,UAAU;QACV,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,IAAK,CAAC;QACrC,IAAI,EAAE,EAAE;KACT,CACF,CAAC;IAEF,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IAExB,OAAO,CAAC,GAAG,CACT,sBAAsB,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,QAAQ,UAAU,EAAE,CACxE,CAAC;AACJ,CAAC;AAED,eAAe,eAAe,CAAC"}
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "CleanSharedGenerator",
4
+ "title": "Clean Shared Generator",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "Name of the shared asset",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ }
14
+ },
15
+ "type": {
16
+ "type": "string",
17
+ "description": "Type of shared asset (defaults to 'all' if not specified)",
18
+ "enum": ["all", "ui", "util"],
19
+ "default": "all"
20
+ }
21
+ },
22
+ "required": []
23
+ }
package/src/index.js CHANGED
@@ -1 +1,2 @@
1
+ "use strict";
1
2
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Capitalizes the first letter of a string
3
+ */
4
+ export declare function capitalizeFirst(str: string): string;
5
+ /**
6
+ * Converts a string to PascalCase
7
+ */
8
+ export declare function toPascalCase(str: string): string;
9
+ /**
10
+ * Converts a string to camelCase
11
+ */
12
+ export declare function toCamelCase(str: string): string;
13
+ /**
14
+ * Pluralizes a word (simple implementation)
15
+ */
16
+ export declare function pluralize(word: string): string;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Capitalizes the first letter of a string
3
+ */
4
+ export function capitalizeFirst(str) {
5
+ return str.charAt(0).toUpperCase() + str.slice(1);
6
+ }
7
+ /**
8
+ * Converts a string to PascalCase
9
+ */
10
+ export function toPascalCase(str) {
11
+ return str
12
+ .split('-')
13
+ .map((part) => capitalizeFirst(part))
14
+ .join('');
15
+ }
16
+ /**
17
+ * Converts a string to camelCase
18
+ */
19
+ export function toCamelCase(str) {
20
+ const pascal = toPascalCase(str);
21
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
22
+ }
23
+ /**
24
+ * Pluralizes a word (simple implementation)
25
+ */
26
+ export function pluralize(word) {
27
+ if (word.endsWith('s'))
28
+ return word;
29
+ if (word.endsWith('y'))
30
+ return word.slice(0, -1) + 'ies';
31
+ return word + 's';
32
+ }
33
+ //# sourceMappingURL=string-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-utils.js","sourceRoot":"","sources":["../../../../../apps/cli/src/utils/string-utils.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,GAAG;SACP,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;SACpC,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACzD,OAAO,IAAI,GAAG,GAAG,CAAC;AACpB,CAAC"}
@@ -1,6 +0,0 @@
1
- import { signalStore, withState } from '@ngrx/signals';
2
-
3
- export const <%= pascalName %>Store = signalStore(
4
- { providedIn: 'root' },
5
- withState({ loading: false })
6
- );
@@ -1,4 +0,0 @@
1
- export interface <%= pascalName %> {
2
- id: string;
3
- <% attributes.forEach(function(attr) { %> <%= attr.name %>: <%= attr.type %>;
4
- <% }); %>}
@@ -1,44 +0,0 @@
1
- import { Component, inject } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { <%= pascalName %>Store } from '../application/store';
4
-
5
- @Component({
6
- selector: 'app-<%= name %>-feature',
7
- standalone: true,
8
- imports: [CommonModule],
9
- template: `
10
- <div class="<%= name %>-feature">
11
- <h1><%= pascalName %> Feature</h1>
12
-
13
- @if (store.loading()) {
14
- <p>Loading...</p>
15
- } @else {
16
- <p>Ready to build your <%= name %> feature!</p>
17
-
18
- <!-- Example list of <%= name %> items -->
19
- <ul>
20
- @for (item of []; track item.id) {
21
- <li>
22
- <% attributes.forEach(function(attr) { %>
23
- <strong><%= attr.name %>:</strong> {{ item.<%= attr.name %> }}<br/>
24
- <% }); %>
25
- </li>
26
- }
27
- </ul>
28
- }
29
- </div>
30
- `,
31
- styles: `
32
- .<%= name %>-feature {
33
- padding: 1rem;
34
- }
35
-
36
- h1 {
37
- color: #333;
38
- margin-bottom: 1rem;
39
- }
40
- `,
41
- })
42
- export class <%= pascalName %>Component {
43
- protected readonly store = inject(<%= pascalName %>Store);
44
- }
@@ -1,4 +0,0 @@
1
- import { Tree } from '@nx/devkit';
2
- import { CleanFeatureGeneratorSchema } from './schema';
3
- export declare function cleanFeatureGenerator(tree: Tree, options: CleanFeatureGeneratorSchema): Promise<void>;
4
- export default cleanFeatureGenerator;
@@ -1,89 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cleanFeatureGenerator = cleanFeatureGenerator;
4
- const tslib_1 = require("tslib");
5
- const devkit_1 = require("@nx/devkit");
6
- const inquirer = require("inquirer");
7
- /**
8
- * Capitalizes the first letter of a string
9
- */
10
- function capitalizeFirst(str) {
11
- return str.charAt(0).toUpperCase() + str.slice(1);
12
- }
13
- /**
14
- * Converts a kebab-case or camelCase string to PascalCase
15
- */
16
- function toPascalCase(str) {
17
- return str
18
- .split('-')
19
- .map((part) => capitalizeFirst(part))
20
- .join('');
21
- }
22
- function cleanFeatureGenerator(tree, options) {
23
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
24
- let name = options.name;
25
- let attributes = [];
26
- // Interactive mode if no name provided or explicit interactive flag (though we don't have a specific flag in schema, strict missing name is enough)
27
- if (!name) {
28
- const questions = [
29
- {
30
- type: 'input',
31
- name: 'name',
32
- message: 'What is the name of the feature (singular)?',
33
- validate: (input) => input.length > 0 ? true : 'Name is required',
34
- },
35
- ];
36
- const answers = yield inquirer.prompt(questions);
37
- name = answers.name;
38
- }
39
- // Auto-pluralize: simply add 's' for now as requested
40
- // Ideally use a pluralize library, but sticking to simple requirement
41
- if (!name.endsWith('s')) {
42
- name = name + 's';
43
- }
44
- const targetPath = (0, devkit_1.joinPathFragments)('apps/sandbox/src/app/features', name);
45
- // Format names for templates
46
- const pascalName = toPascalCase(name);
47
- if (options.attributes) {
48
- attributes = options.attributes.split(',').map((attr) => {
49
- const [n, t] = attr.split(':');
50
- return { name: n, type: t || 'string' };
51
- });
52
- }
53
- else {
54
- // Interactive attribute prompting
55
- console.log('Let\'s add some attributes (property fields).');
56
- let addingAttributes = true;
57
- while (addingAttributes) {
58
- const { attrName } = yield inquirer.prompt([
59
- {
60
- type: 'input',
61
- name: 'attrName',
62
- message: 'Enter attribute name (or press enter to finish):',
63
- },
64
- ]);
65
- if (!attrName || attrName.trim() === '') {
66
- addingAttributes = false;
67
- break;
68
- }
69
- const { attrType } = yield inquirer.prompt([
70
- {
71
- type: 'list',
72
- name: 'attrType',
73
- message: 'Select type:',
74
- choices: ['string', 'number', 'boolean', 'Date', 'any'],
75
- default: 'string',
76
- },
77
- ]);
78
- attributes.push({ name: attrName, type: attrType });
79
- }
80
- }
81
- // Generate files from templates
82
- (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files'), targetPath, Object.assign(Object.assign({}, options), { name,
83
- pascalName,
84
- attributes, tmpl: '' }));
85
- yield (0, devkit_1.formatFiles)(tree);
86
- });
87
- }
88
- exports.default = cleanFeatureGenerator;
89
- //# sourceMappingURL=generator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../apps/cli/src/generators/clean-feature/generator.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- export interface CleanFeatureGeneratorSchema {
2
- name: string;
3
- attributes?: string;
4
- }