@ngflow/ng-architect 1.2.4 → 1.2.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngflow/ng-architect",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Angular schematics to generate files and maintain clean architecture",
5
5
  "scripts": {
6
6
  "build": "tsc -p tsconfig.json",
@@ -8,9 +8,9 @@
8
8
  "name": { "type": "string", "description": "Component name" },
9
9
  "structure": {
10
10
  "type": "string",
11
- "enum": ["flat", "domain-driven", "module-driven", "monorepo"],
12
- "default": "domain-driven"
13
- },
11
+ "enum": ["auto", "flat", "domain-driven", "module-driven", "monorepo"],
12
+ "default": "auto"
13
+ },
14
14
  "module": { "type": "string", "description": "Module name (for module-driven structure)" },
15
15
  "app": { "type": "string", "description": "App name (for monorepo)" },
16
16
  "lib": { "type": "string", "description": "Lib name (for monorepo)" }
@@ -4,7 +4,24 @@ exports.default = default_1;
4
4
  const schematics_1 = require("@angular-devkit/schematics");
5
5
  const string_utils_1 = require("../utils/string-utils");
6
6
  const routes_utils_1 = require("../utils/routes-utils");
7
+ const structure_resolver_1 = require("../utils/structure-resolver");
8
+ const options_validator_1 = require("../utils/options-validator");
7
9
  function default_1(options) {
10
+ return (tree, context) => {
11
+ // 🔹 Resolver a structure antes de qualquer lógica
12
+ const resolvedStructure = (0, structure_resolver_1.resolveStructure)(tree, options);
13
+ options.structure = resolvedStructure;
14
+ context.logger.info(`📐 Structure resolved to: ${resolvedStructure}`);
15
+ // 🔹 Validar flags e opções obrigatórias
16
+ (0, options_validator_1.validateOptions)(options, resolvedStructure);
17
+ // 🔹 Continuar com a geração real da feature
18
+ return featureRule(options)(tree, context);
19
+ };
20
+ }
21
+ ;
22
+ // ------------------------------------------------------
23
+ // Função interna que gera a feature de forma limpa
24
+ function featureRule(options) {
8
25
  const featureKebab = (0, string_utils_1.toKebabCase)(options.name);
9
26
  const featurePascal = (0, string_utils_1.toPascalCase)(options.name);
10
27
  let basePath;
@@ -31,40 +48,45 @@ function default_1(options) {
31
48
  : `libs/${options.lib}/src/lib/${featureKebab}`;
32
49
  subFolders = ['pages', 'data', 'models'];
33
50
  break;
34
- default:
35
- throw new Error(`Invalid structure: ${options.structure}`);
36
51
  }
37
52
  return (0, schematics_1.chain)([
38
53
  (_tree, context) => {
39
54
  context.logger.info(`🟢 Creating feature: ${featurePascal} (${featureKebab})`);
40
55
  context.logger.info(`Structure: ${options.structure}`);
41
56
  },
42
- (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [(0, schematics_1.template)({ featureKebab, featurePascal }), (0, schematics_1.move)(basePath)])),
57
+ // 🔹 Gerar ficheiros a partir do template
58
+ (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [
59
+ (0, schematics_1.template)({ featureKebab, featurePascal }),
60
+ (0, schematics_1.move)(basePath),
61
+ ])),
62
+ // 🔹 Atualizar routes.ts (standalone + lazy loading quando necessário)
43
63
  (_tree, context) => {
44
64
  context.logger.info(`🟢 Updating app.routes.ts with ${featurePascal}Page...`);
45
65
  (0, routes_utils_1.updateAppRoutes)(_tree, featureKebab, featurePascal, options.structure, options);
46
66
  },
67
+ // 🔹 Criar subpastas e barrels (index.ts)
47
68
  (_tree) => {
48
- // Cria subpastas e barrels
49
69
  subFolders.forEach((folder) => {
50
70
  const folderPath = `${basePath}/${folder}`;
51
71
  if (!_tree.exists(folderPath))
52
72
  _tree.create(folderPath + '/.gitkeep', '');
53
- // Gera barrel index.ts automaticamente
54
- const files = _tree.getDir(folderPath).subfiles.filter(f => f.endsWith('.ts'));
55
- const barrelContent = files.map(f => {
73
+ // Criar barrel index.ts automaticamente
74
+ const files = _tree.getDir(folderPath).subfiles.filter((f) => f.endsWith('.ts'));
75
+ const barrelContent = files
76
+ .map((f) => {
56
77
  const name = f.replace('.ts', '');
57
78
  return `export * from './${name}';`;
58
- }).join('\n');
79
+ })
80
+ .join('\n');
59
81
  if (!_tree.exists(`${folderPath}/index.ts`)) {
60
82
  _tree.create(`${folderPath}/index.ts`, barrelContent);
61
83
  }
62
84
  else {
63
- // Se já existe index.ts, adiciona novos exports sem duplicar
85
+ // Adiciona novos exports sem duplicar
64
86
  const existing = _tree.read(`${folderPath}/index.ts`).toString('utf-8');
65
87
  const newExports = files
66
- .map(f => `export * from './${f.replace('.ts', '')}';`)
67
- .filter(line => !existing.includes(line))
88
+ .map((f) => `export * from './${f.replace('.ts', '')}';`)
89
+ .filter((line) => !existing.includes(line))
68
90
  .join('\n');
69
91
  if (newExports)
70
92
  _tree.overwrite(`${folderPath}/index.ts`, existing + '\n' + newExports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
@@ -11,17 +11,36 @@ import {
11
11
  } from '@angular-devkit/schematics';
12
12
  import { toKebabCase, toPascalCase } from '../utils/string-utils';
13
13
  import { updateAppRoutes } from '../utils/routes-utils';
14
+ import { resolveStructure } from '../utils/structure-resolver';
15
+ import { validateOptions } from '../utils/options-validator';
14
16
 
15
17
  export default function (options: any): Rule {
18
+ return (tree: Tree, context: SchematicContext) => {
19
+ // 🔹 Resolver a structure antes de qualquer lógica
20
+ const resolvedStructure = resolveStructure(tree, options);
21
+ options.structure = resolvedStructure;
22
+
23
+ context.logger.info(`📐 Structure resolved to: ${resolvedStructure}`);
24
+
25
+ // 🔹 Validar flags e opções obrigatórias
26
+ validateOptions(options, resolvedStructure);
27
+
28
+ // 🔹 Continuar com a geração real da feature
29
+ return featureRule(options)(tree, context);
30
+ };
31
+ };
32
+
33
+ // ------------------------------------------------------
34
+ // Função interna que gera a feature de forma limpa
35
+ function featureRule(options: any): Rule {
16
36
  const featureKebab = toKebabCase(options.name);
17
37
  const featurePascal = toPascalCase(options.name);
18
38
 
19
- let basePath: string;
39
+ let basePath!: string;
20
40
  let subFolders: string[] = [];
21
41
 
22
42
  switch (options.structure) {
23
43
  case 'flat':
24
-
25
44
  basePath = `src/app/${featureKebab}`;
26
45
  break;
27
46
 
@@ -44,9 +63,6 @@ export default function (options: any): Rule {
44
63
  : `libs/${options.lib}/src/lib/${featureKebab}`;
45
64
  subFolders = ['pages', 'data', 'models'];
46
65
  break;
47
-
48
- default:
49
- throw new Error(`Invalid structure: ${options.structure}`);
50
66
  }
51
67
 
52
68
  return chain([
@@ -55,35 +71,43 @@ export default function (options: any): Rule {
55
71
  context.logger.info(`Structure: ${options.structure}`);
56
72
  },
57
73
 
58
- mergeWith(apply(url('./files'), [template({ featureKebab, featurePascal }), move(basePath)])),
74
+ // 🔹 Gerar ficheiros a partir do template
75
+ mergeWith(
76
+ apply(url('./files'), [
77
+ template({ featureKebab, featurePascal }),
78
+ move(basePath),
79
+ ])
80
+ ),
59
81
 
82
+ // 🔹 Atualizar routes.ts (standalone + lazy loading quando necessário)
60
83
  (_tree: Tree, context: SchematicContext) => {
61
84
  context.logger.info(`🟢 Updating app.routes.ts with ${featurePascal}Page...`);
62
-
63
85
  updateAppRoutes(_tree, featureKebab, featurePascal, options.structure, options);
64
86
  },
65
87
 
88
+ // 🔹 Criar subpastas e barrels (index.ts)
66
89
  (_tree: Tree) => {
67
- // Cria subpastas e barrels
68
90
  subFolders.forEach((folder) => {
69
91
  const folderPath = `${basePath}/${folder}`;
70
92
  if (!_tree.exists(folderPath)) _tree.create(folderPath + '/.gitkeep', '');
71
93
 
72
- // Gera barrel index.ts automaticamente
73
- const files = _tree.getDir(folderPath).subfiles.filter(f => f.endsWith('.ts'));
74
- const barrelContent = files.map(f => {
75
- const name = f.replace('.ts', '');
76
- return `export * from './${name}';`;
77
- }).join('\n');
94
+ // Criar barrel index.ts automaticamente
95
+ const files = _tree.getDir(folderPath).subfiles.filter((f) => f.endsWith('.ts'));
96
+ const barrelContent = files
97
+ .map((f) => {
98
+ const name = f.replace('.ts', '');
99
+ return `export * from './${name}';`;
100
+ })
101
+ .join('\n');
78
102
 
79
103
  if (!_tree.exists(`${folderPath}/index.ts`)) {
80
104
  _tree.create(`${folderPath}/index.ts`, barrelContent);
81
105
  } else {
82
- // Se já existe index.ts, adiciona novos exports sem duplicar
106
+ // Adiciona novos exports sem duplicar
83
107
  const existing = _tree.read(`${folderPath}/index.ts`)!.toString('utf-8');
84
108
  const newExports = files
85
- .map(f => `export * from './${f.replace('.ts','')}';`)
86
- .filter(line => !existing.includes(line))
109
+ .map((f) => `export * from './${f.replace('.ts', '')}';`)
110
+ .filter((line) => !existing.includes(line))
87
111
  .join('\n');
88
112
  if (newExports) _tree.overwrite(`${folderPath}/index.ts`, existing + '\n' + newExports);
89
113
  }
@@ -11,8 +11,8 @@
11
11
  },
12
12
  "structure": {
13
13
  "type": "string",
14
- "enum": ["flat", "domain-driven", "module-driven", "monorepo"],
15
- "default": "domain-driven",
14
+ "enum": ["auto", "flat", "domain-driven", "module-driven", "monorepo"],
15
+ "default": "auto",
16
16
  "description": "Project structure for feature"
17
17
  },
18
18
  "module": {
@@ -8,8 +8,8 @@
8
8
  "name": { "type": "string", "description": "Service name" },
9
9
  "structure": {
10
10
  "type": "string",
11
- "enum": ["flat", "domain-driven", "module-driven", "monorepo"],
12
- "default": "domain-driven"
11
+ "enum": ["auto", "flat", "domain-driven", "module-driven", "monorepo"],
12
+ "default": "auto"
13
13
  },
14
14
  "module": { "type": "string", "description": "Module name (for module-driven structure)" },
15
15
  "app": { "type": "string", "description": "App name (for monorepo)" },
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateOptions = validateOptions;
4
+ function validateOptions(options, structure) {
5
+ if (structure === 'module-driven' && !options.module) {
6
+ throw new Error('❌ structure=module-driven requires --module=<moduleName>');
7
+ }
8
+ if (structure === 'monorepo' && !options.app && !options.lib) {
9
+ throw new Error('❌ structure=monorepo requires --app or --lib');
10
+ }
11
+ }
12
+ //# sourceMappingURL=options-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options-validator.js","sourceRoot":"","sources":["options-validator.ts"],"names":[],"mappings":";;AAEA,0CAeC;AAfD,SAAgB,eAAe,CAC7B,OAAY,EACZ,SAAoB;IAEpB,IAAI,SAAS,KAAK,eAAe,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,8CAA8C,CAC/C,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Structure } from './structure-resolver';
2
+
3
+ export function validateOptions(
4
+ options: any,
5
+ structure: Structure
6
+ ) {
7
+ if (structure === 'module-driven' && !options.module) {
8
+ throw new Error(
9
+ '❌ structure=module-driven requires --module=<moduleName>'
10
+ );
11
+ }
12
+
13
+ if (structure === 'monorepo' && !options.app && !options.lib) {
14
+ throw new Error(
15
+ '❌ structure=monorepo requires --app or --lib'
16
+ );
17
+ }
18
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveStructure = resolveStructure;
4
+ function resolveStructure(tree, options) {
5
+ if (options.structure && options.structure !== 'auto') {
6
+ return options.structure;
7
+ }
8
+ // Monorepo
9
+ if (tree.exists('apps') || tree.exists('libs')) {
10
+ return 'monorepo';
11
+ }
12
+ // Domain-driven
13
+ if (tree.exists('src/app/features')) {
14
+ return 'domain-driven';
15
+ }
16
+ // Flat standalone
17
+ if (tree.exists('src/app/app.routes.ts')) {
18
+ return 'flat';
19
+ }
20
+ // Fallback seguro
21
+ return 'domain-driven';
22
+ }
23
+ //# sourceMappingURL=structure-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure-resolver.js","sourceRoot":"","sources":["structure-resolver.ts"],"names":[],"mappings":";;AAQA,4CAyBC;AAzBD,SAAgB,gBAAgB,CAC9B,IAAU,EACV,OAAY;IAEZ,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QACtD,OAAO,OAAO,CAAC,SAAS,CAAC;IAC3B,CAAC;IAED,WAAW;IACX,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,gBAAgB;IAChB,IAAI,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACpC,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,kBAAkB;IAClB,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB;IAClB,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { Tree } from '@angular-devkit/schematics';
2
+
3
+ export type Structure =
4
+ | 'flat'
5
+ | 'domain-driven'
6
+ | 'module-driven'
7
+ | 'monorepo';
8
+
9
+ export function resolveStructure(
10
+ tree: Tree,
11
+ options: any
12
+ ): Structure {
13
+ if (options.structure && options.structure !== 'auto') {
14
+ return options.structure;
15
+ }
16
+
17
+ // Monorepo
18
+ if (tree.exists('apps') || tree.exists('libs')) {
19
+ return 'monorepo';
20
+ }
21
+
22
+ // Domain-driven
23
+ if (tree.exists('src/app/features')) {
24
+ return 'domain-driven';
25
+ }
26
+
27
+ // Flat standalone
28
+ if (tree.exists('src/app/app.routes.ts')) {
29
+ return 'flat';
30
+ }
31
+
32
+ // Fallback seguro
33
+ return 'domain-driven';
34
+ }