@ngflow/ng-architect 1.0.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.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Getting Started With Schematics
2
+
3
+ This repository is a basic Schematic implementation that serves as a starting point to create and publish Schematics to NPM.
4
+
5
+ ### Testing
6
+
7
+ To test locally, install `@angular-devkit/schematics-cli` globally and use the `schematics` command line tool. That tool acts the same as the `generate` command of the Angular CLI, but also has a debug mode.
8
+
9
+ Check the documentation with
10
+
11
+ ```bash
12
+ schematics --help
13
+ ```
14
+
15
+ ### Unit Testing
16
+
17
+ `npm run test` will run the unit tests, using Jasmine as a runner and test framework.
18
+
19
+ ### Publishing
20
+
21
+ To publish, simply do:
22
+
23
+ ```bash
24
+ npm run build
25
+ npm publish
26
+ ```
27
+
28
+ That's it!
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@ngflow/ng-architect",
3
+ "version": "1.0.0",
4
+ "description": "Angular schematics to generate files and maintain clean architecture",
5
+ "scripts": {
6
+ "build": "tsc -p tsconfig.json",
7
+ "test": "npm run build && jasmine src/**/*_spec.js"
8
+ },
9
+ "keywords": ["schematics", "angular", "automation", "architecture"],
10
+ "author": "João Fernandes",
11
+ "license": "MIT",
12
+ "schematics": "./src/collection.json",
13
+ "dependencies": {
14
+ "@angular-devkit/core": "^21.0.4",
15
+ "@angular-devkit/schematics": "^21.0.4"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^20.17.19",
19
+ "@types/jasmine": "~5.1.0",
20
+ "jasmine": "~5.12.0",
21
+ "typescript": "~5.9.2"
22
+ }
23
+ }
@@ -0,0 +1,28 @@
1
+ // By default, collection.json is a Loose-format JSON5 format, which means it's loaded using a
2
+ // special loader and you can use comments, as well as single quotes or no-quotes for standard
3
+ // JavaScript identifiers.
4
+ // Note that this is only true for collection.json and it depends on the tooling itself.
5
+ // We read package.json using a require() call, which is standard JSON.
6
+ {
7
+ // This is just to indicate to your IDE that there is a schema for collection.json.
8
+ "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
9
+
10
+ // Schematics are listed as a map of schematicName => schematicDescription.
11
+ // Each description contains a description field which is required, a factory reference,
12
+ // an extends field and a schema reference.
13
+ // The extends field points to another schematic (either in the same collection or a
14
+ // separate collection using the format collectionName:schematicName).
15
+ // The factory is required, except when using the extends field. Then the factory can
16
+ // overwrite the extended schematic factory.
17
+ "schematics": {
18
+ "ng-architect": {
19
+ "description": "Gera uma feature Angular completa com rotas e arquivos",
20
+ "factory": "./ng-architect/index#default",
21
+ "schema": "./ng-architect/schema.json"
22
+ },
23
+ "my-extend-schematic": {
24
+ "description": "A schematic that extends another schematic.",
25
+ "extends": "my-full-schematic"
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,2 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ export default function (options: any): Rule;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ // Helper functions
6
+ const toKebabCase = (value) => value
7
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
8
+ .replace(/_/g, '-')
9
+ .toLowerCase();
10
+ const toPascalCase = (value) => value
11
+ .split(/[-_]/)
12
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
13
+ .join('');
14
+ function default_1(options) {
15
+ const featureKebab = toKebabCase(options.name);
16
+ const featurePascal = toPascalCase(options.name);
17
+ return (0, schematics_1.chain)([
18
+ (_tree, context) => {
19
+ context.logger.info(`✅ Criando feature: ${featurePascal} (${featureKebab})`);
20
+ },
21
+ // Generate files from templates
22
+ (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [
23
+ (0, schematics_1.filter)(path => !path.endsWith('.swp')),
24
+ (0, schematics_1.template)({
25
+ featureKebab,
26
+ featurePascal,
27
+ }),
28
+ ])),
29
+ // Update app.routes.ts if it exists
30
+ (tree, context) => {
31
+ const appRoutesPath = 'src/app/app.routes.ts';
32
+ if (tree.exists(appRoutesPath)) {
33
+ let content = tree.read(appRoutesPath)?.toString('utf-8') || '';
34
+ const routePattern = new RegExp(`path:\\s*['"]${featureKebab}['"]`);
35
+ if (!routePattern.test(content)) {
36
+ const routeBlock = ` {
37
+ path: '${featureKebab}',
38
+ loadChildren: () =>
39
+ import('./features/${featureKebab}/${featureKebab}.routes')
40
+ .then(m => m.${featurePascal}Routes),
41
+ },`;
42
+ // Insert before the closing bracket
43
+ content = content.replace(/\n\];\s*$/, `\n${routeBlock}\n];`);
44
+ tree.overwrite(appRoutesPath, content);
45
+ context.logger.info(`➕ Rota "${featureKebab}" registada em app.routes.ts`);
46
+ }
47
+ else {
48
+ context.logger.warn(`ℹ️ Rota "${featureKebab}" já existe em app.routes.ts`);
49
+ }
50
+ }
51
+ else {
52
+ context.logger.warn('⚠️ app.routes.ts não encontrado, rota não registada automaticamente');
53
+ }
54
+ return tree;
55
+ },
56
+ ]);
57
+ }
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;AAyBA,4BAkDC;AA3ED,2DAUoC;AAEpC,mBAAmB;AACnB,MAAM,WAAW,GAAG,CAAC,KAAa,EAAU,EAAE,CAC5C,KAAK;KACF,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;KACnC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;KAClB,WAAW,EAAE,CAAC;AAEnB,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CAC7C,KAAK;KACF,KAAK,CAAC,MAAM,CAAC;KACb,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACzD,IAAI,CAAC,EAAE,CAAC,CAAC;AAEd,mBAAyB,OAAY;IACnC,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,OAAO,IAAA,kBAAK,EAAC;QACX,CAAC,KAAW,EAAE,OAAyB,EAAE,EAAE;YACzC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,aAAa,KAAK,YAAY,GAAG,CAAC,CAAC;QAC/E,CAAC;QAED,gCAAgC;QAChC,IAAA,sBAAS,EACP,IAAA,kBAAK,EAAC,IAAA,gBAAG,EAAC,SAAS,CAAC,EAAE;YACpB,IAAA,mBAAM,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACtC,IAAA,qBAAQ,EAAC;gBACP,YAAY;gBACZ,aAAa;aACd,CAAC;SACH,CAAC,CACH;QAED,oCAAoC;QACpC,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;YACxC,MAAM,aAAa,GAAG,uBAAuB,CAAC;YAE9C,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC/B,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAEhE,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,gBAAgB,YAAY,MAAM,CAAC,CAAC;gBACpE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBAChC,MAAM,UAAU,GAAG;aAChB,YAAY;;2BAEE,YAAY,IAAI,YAAY;uBAChC,aAAa;KAC/B,CAAC;oBAEI,oCAAoC;oBACpC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,UAAU,MAAM,CAAC,CAAC;oBAC9D,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;oBACvC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,YAAY,8BAA8B,CAAC,CAAC;gBAC7E,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,YAAY,8BAA8B,CAAC,CAAC;gBAC9E,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;YAC7F,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schematics_1 = require("@angular-devkit/schematics");
4
+ const testing_1 = require("@angular-devkit/schematics/testing");
5
+ const path = require("path");
6
+ // SchematicTestRunner needs an absolute path to the collection to test.
7
+ const collectionPath = path.join(__dirname, '../collection.json');
8
+ describe('my-full-schematic', () => {
9
+ it('requires required option', async () => {
10
+ // We test that
11
+ const runner = new testing_1.SchematicTestRunner('schematics', collectionPath);
12
+ await expectAsync(runner.runSchematic('my-full-schematic', {}, schematics_1.Tree.empty())).toBeRejected();
13
+ });
14
+ it('works', async () => {
15
+ const runner = new testing_1.SchematicTestRunner('schematics', collectionPath);
16
+ const tree = await runner.runSchematic('my-full-schematic', { name: 'str' }, schematics_1.Tree.empty());
17
+ // Listing files
18
+ expect(tree.files.sort()).toEqual(['/allo', '/hola', '/test1', '/test2']);
19
+ });
20
+ });
21
+ //# sourceMappingURL=index_spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index_spec.js","sourceRoot":"","sources":["index_spec.ts"],"names":[],"mappings":";;AAAA,2DAAkD;AAClD,gEAAyE;AACzE,6BAA6B;AAE7B,wEAAwE;AACxE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAElE,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,eAAe;QACf,MAAM,MAAM,GAAG,IAAI,6BAAmB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACrE,MAAM,WAAW,CACf,MAAM,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE,EAAE,iBAAI,CAAC,KAAK,EAAE,CAAC,CAC3D,CAAC,YAAY,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;QACrB,MAAM,MAAM,GAAG,IAAI,6BAAmB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,iBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAE3F,gBAAgB;QAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "MyFullSchematicsSchema",
4
+ "title": "Angular Feature Generator",
5
+ "description": "Generates a complete Angular feature with pages, services, store, models and routes",
6
+ "type": "object",
7
+ "properties": {
8
+ "name": {
9
+ "type": "string",
10
+ "description": "The name of the feature (e.g., user-profile, product-list)",
11
+ "minLength": 1
12
+ }
13
+ },
14
+ "required": ["name"]
15
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": "tsconfig",
4
+ "lib": ["es2018", "dom"],
5
+ "module": "commonjs",
6
+ "moduleResolution": "node",
7
+ "noEmitOnError": true,
8
+ "noFallthroughCasesInSwitch": true,
9
+ "noImplicitAny": true,
10
+ "noImplicitThis": true,
11
+ "noUnusedParameters": true,
12
+ "noUnusedLocals": true,
13
+ "rootDir": "src/",
14
+ "skipDefaultLibCheck": true,
15
+ "skipLibCheck": true,
16
+ "sourceMap": true,
17
+ "strictNullChecks": true,
18
+ "target": "es6",
19
+ "types": ["jasmine", "node"]
20
+ },
21
+ "include": ["src/**/*"],
22
+ "exclude": ["src/*/files/**/*"]
23
+ }