@ngflow/ng-architect 1.2.4 → 1.2.5

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.5",
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,6 +4,8 @@ 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) {
8
10
  const featureKebab = (0, string_utils_1.toKebabCase)(options.name);
9
11
  const featurePascal = (0, string_utils_1.toPascalCase)(options.name);
@@ -35,9 +37,13 @@ function default_1(options) {
35
37
  throw new Error(`Invalid structure: ${options.structure}`);
36
38
  }
37
39
  return (0, schematics_1.chain)([
38
- (_tree, context) => {
40
+ (tree, context) => {
39
41
  context.logger.info(`🟢 Creating feature: ${featurePascal} (${featureKebab})`);
40
42
  context.logger.info(`Structure: ${options.structure}`);
43
+ const resolved = (0, structure_resolver_1.resolveStructure)(tree, options);
44
+ options.structure = resolved;
45
+ context.logger.info(`📐 Structure resolved to: ${resolved}`);
46
+ (0, options_validator_1.validateOptions)(options, resolved);
41
47
  },
42
48
  (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [(0, schematics_1.template)({ featureKebab, featurePascal }), (0, schematics_1.move)(basePath)])),
43
49
  (_tree, context) => {
@@ -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,6 +11,8 @@ 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 {
16
18
  const featureKebab = toKebabCase(options.name);
@@ -50,9 +52,15 @@ export default function (options: any): Rule {
50
52
  }
51
53
 
52
54
  return chain([
53
- (_tree: Tree, context: SchematicContext) => {
55
+ (tree: Tree, context: SchematicContext) => {
54
56
  context.logger.info(`🟢 Creating feature: ${featurePascal} (${featureKebab})`);
55
57
  context.logger.info(`Structure: ${options.structure}`);
58
+ const resolved = resolveStructure(tree, options);
59
+ options.structure = resolved;
60
+
61
+ context.logger.info(`📐 Structure resolved to: ${resolved}`);
62
+
63
+ validateOptions(options, resolved);
56
64
  },
57
65
 
58
66
  mergeWith(apply(url('./files'), [template({ featureKebab, featurePascal }), move(basePath)])),
@@ -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
+ }