ngine-component 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.
Files changed (36) hide show
  1. package/collection.json +19 -0
  2. package/dist/base-component/files/__name@dasherize__.component.html.template +0 -0
  3. package/dist/base-component/files/__name@dasherize__.component.scss.template +0 -0
  4. package/dist/base-component/files/__name@dasherize__.component.spec.ts.template +22 -0
  5. package/dist/base-component/files/__name@dasherize__.component.ts.template +13 -0
  6. package/dist/base-component/index.js +49 -0
  7. package/dist/base-component/index.js.map +1 -0
  8. package/dist/base-component/schema.js +3 -0
  9. package/dist/base-component/schema.js.map +1 -0
  10. package/dist/management-base-component/files/__name@dasherize__.component.html.template +0 -0
  11. package/dist/management-base-component/files/__name@dasherize__.component.scss.template +0 -0
  12. package/dist/management-base-component/files/__name@dasherize__.component.spec.ts.template +22 -0
  13. package/dist/management-base-component/files/__name@dasherize__.component.ts.template +13 -0
  14. package/dist/management-base-component/index.js +49 -0
  15. package/dist/management-base-component/index.js.map +1 -0
  16. package/dist/management-base-component/schema.js +3 -0
  17. package/dist/management-base-component/schema.js.map +1 -0
  18. package/dist/ng-add/index.js +43 -0
  19. package/dist/ng-add/index.js.map +1 -0
  20. package/package.json +20 -0
  21. package/src/base-component/files/__name@dasherize__.component.html.template +0 -0
  22. package/src/base-component/files/__name@dasherize__.component.scss.template +0 -0
  23. package/src/base-component/files/__name@dasherize__.component.spec.ts.template +22 -0
  24. package/src/base-component/files/__name@dasherize__.component.ts.template +13 -0
  25. package/src/base-component/index.ts +71 -0
  26. package/src/base-component/schema.json +27 -0
  27. package/src/base-component/schema.ts +5 -0
  28. package/src/management-base-component/files/__name@dasherize__.component.html.template +0 -0
  29. package/src/management-base-component/files/__name@dasherize__.component.scss.template +0 -0
  30. package/src/management-base-component/files/__name@dasherize__.component.spec.ts.template +22 -0
  31. package/src/management-base-component/files/__name@dasherize__.component.ts.template +13 -0
  32. package/src/management-base-component/index.ts +71 -0
  33. package/src/management-base-component/schema.json +27 -0
  34. package/src/management-base-component/schema.ts +5 -0
  35. package/src/ng-add/index.ts +59 -0
  36. package/tsconfig.json +23 -0
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
3
+ "schematics": {
4
+ "ng-add": {
5
+ "description": "Registers ngine-component in angular.json so you can run `ng generate base-component <name>` and `ng generate management-base-component <name>`.",
6
+ "factory": "./dist/ng-add/index#ngAdd"
7
+ },
8
+ "base-component": {
9
+ "description": "A base component to build any features.",
10
+ "factory": "./dist/base-component/index#baseComponent",
11
+ "schema": "./src/base-component/schema.json"
12
+ },
13
+ "management-base-component": {
14
+ "description": "A base component with management options already integrated (form, add, edit, delete...)",
15
+ "factory": "./dist/management-base-component/index#managementBaseComponent",
16
+ "schema": "./src/management-base-component/schema.json"
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';
4
+
5
+ describe('<%= classify(name) %>Component', () => {
6
+ let component: <%= classify(name) %>Component;
7
+ let fixture: ComponentFixture<<%= classify(name) %>Component>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [<%= classify(name) %>Component],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(<%= classify(name) %>Component);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { NavigationBaseComponent } from '../../core/components/navigation-base/navigation-base.component';
3
+
4
+ @Component({
5
+ selector: '<%= prefix %>-<%= dasherize(name) %>',
6
+ templateUrl: './<%= dasherize(name) %>.component.html',
7
+ styleUrls: ['./<%= dasherize(name) %>.component.scss'],
8
+ })
9
+ export class <%= classify(name) %>Component extends NavigationBaseComponent {
10
+
11
+ constructor() { super(); }
12
+
13
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.baseComponent = baseComponent;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ function baseComponent(options) {
6
+ return (0, schematics_1.chain)([
7
+ _createComponent(options),
8
+ _addToComponentStore(options),
9
+ ]);
10
+ }
11
+ function _createComponent(options) {
12
+ return (tree, context) => {
13
+ context.logger.info(`Generating base component: ${schematics_1.strings.classify(options.name)}Component`);
14
+ const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
15
+ (0, schematics_1.template)({
16
+ ...schematics_1.strings,
17
+ ...options,
18
+ classify: schematics_1.strings.classify,
19
+ dasherize: schematics_1.strings.dasherize,
20
+ }),
21
+ (0, schematics_1.renameTemplateFiles)(),
22
+ (0, schematics_1.move)(`src/app/${options.path}/${schematics_1.strings.dasherize(options.name)}`),
23
+ ]);
24
+ return (0, schematics_1.mergeWith)(templateSource, schematics_1.MergeStrategy.Overwrite);
25
+ };
26
+ }
27
+ function _addToComponentStore(options) {
28
+ return (tree, context) => {
29
+ context.logger.info(`Adding component: ${schematics_1.strings.classify(options.name)}Component to the component store`);
30
+ const servicePath = 'src/app/components/component.service.ts';
31
+ const buffer = tree.read(servicePath);
32
+ if (!buffer) {
33
+ throw new Error(`File not found: ${servicePath}`);
34
+ }
35
+ const content = buffer.toString('utf-8');
36
+ const componentName = schematics_1.strings.dasherize(options.name);
37
+ const newEntry = `'${componentName}': () => import('./${componentName}/${componentName}.component')`;
38
+ const updated = content.replace(/componentStore\s*:\s*Record<string,\s*\(\)\s*=>\s*Promise<any>>\s*=\s*\{([\s\S]*?)\}/, (_, objectContent) => {
39
+ const trimmed = objectContent.trim();
40
+ if (!trimmed) {
41
+ return `componentStore: Record<string, () => Promise<any>> = {\n ${newEntry},\n}`;
42
+ }
43
+ return `componentStore: Record<string, () => Promise<any>> = {${objectContent.trimEnd()}\n ${newEntry},\n}`;
44
+ });
45
+ tree.overwrite(servicePath, updated);
46
+ return tree;
47
+ };
48
+ }
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/base-component/index.ts"],"names":[],"mappings":";;AAgBA,sCAKC;AArBD,2DAaoC;AAGpC,SAAgB,aAAa,CAAC,OAA4B;IACxD,OAAO,IAAA,kBAAK,EAAC;QACX,gBAAgB,CAAC,OAAO,CAAC;QACzB,oBAAoB,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA4B;IACpD,OAAO,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;QAC/C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,oBAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE7F,MAAM,cAAc,GAAG,IAAA,kBAAK,EAAC,IAAA,gBAAG,EAAC,SAAS,CAAC,EAAE;YAC3C,IAAA,qBAAQ,EAAC;gBACP,GAAG,oBAAO;gBACV,GAAG,OAAO;gBACV,QAAQ,EAAE,oBAAO,CAAC,QAAQ;gBAC1B,SAAS,EAAE,oBAAO,CAAC,SAAS;aAC7B,CAAC;YACF,IAAA,gCAAmB,GAAE;YACrB,IAAA,iBAAI,EAAC,WAAW,OAAO,CAAC,IAAI,IAAI,oBAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;SACnE,CAAC,CAAC;QAEH,OAAO,IAAA,sBAAS,EAAC,cAAc,EAAE,0BAAa,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,OAA4B;IACxD,OAAO,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;QAC/C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,oBAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAE3G,MAAM,WAAW,GAAG,yCAAyC,CAAC;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,oBAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,aAAa,sBAAsB,aAAa,IAAI,aAAa,cAAc,CAAC;QAErG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAC7B,sFAAsF,EACtF,CAAC,CAAM,EAAE,aAAkB,EAAE,EAAE;YAC7B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,+DAA+D,QAAQ,MAAM,CAAC;YACvF,CAAC;YACD,OAAO,yDAAyD,aAAa,CAAC,OAAO,EAAE,SAAS,QAAQ,MAAM,CAAC;QACjH,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/base-component/schema.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';
4
+
5
+ describe('<%= classify(name) %>Component', () => {
6
+ let component: <%= classify(name) %>Component;
7
+ let fixture: ComponentFixture<<%= classify(name) %>Component>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [<%= classify(name) %>Component],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(<%= classify(name) %>Component);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { ManagementBaseComponent } from '../../core/components/management-base/management-base.component';
3
+
4
+ @Component({
5
+ selector: '<%= prefix %>-<%= dasherize(name) %>',
6
+ templateUrl: './<%= dasherize(name) %>.component.html',
7
+ styleUrls: ['./<%= dasherize(name) %>.component.scss'],
8
+ })
9
+ export class <%= classify(name) %>Component extends ManagementBaseComponent<any /* Replace with your type */> {
10
+
11
+ constructor() { super(); }
12
+
13
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.managementBaseComponent = managementBaseComponent;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ function managementBaseComponent(options) {
6
+ return (0, schematics_1.chain)([
7
+ _createComponent(options),
8
+ _addToComponentStore(options),
9
+ ]);
10
+ }
11
+ function _createComponent(options) {
12
+ return (tree, context) => {
13
+ context.logger.info(`Generating management base component: ${schematics_1.strings.classify(options.name)}Component`);
14
+ const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
15
+ (0, schematics_1.template)({
16
+ ...schematics_1.strings,
17
+ ...options,
18
+ classify: schematics_1.strings.classify,
19
+ dasherize: schematics_1.strings.dasherize,
20
+ }),
21
+ (0, schematics_1.renameTemplateFiles)(),
22
+ (0, schematics_1.move)(`src/app/${options.path}/${schematics_1.strings.dasherize(options.name)}`),
23
+ ]);
24
+ return (0, schematics_1.mergeWith)(templateSource, schematics_1.MergeStrategy.Overwrite);
25
+ };
26
+ }
27
+ function _addToComponentStore(options) {
28
+ return (tree, context) => {
29
+ context.logger.info(`Adding component: ${schematics_1.strings.classify(options.name)}Component to the component store`);
30
+ const servicePath = 'src/app/components/component.service.ts';
31
+ const buffer = tree.read(servicePath);
32
+ if (!buffer) {
33
+ throw new Error(`File not found: ${servicePath}`);
34
+ }
35
+ const content = buffer.toString('utf-8');
36
+ const componentName = schematics_1.strings.dasherize(options.name);
37
+ const newEntry = `'${componentName}': () => import('./${componentName}/${componentName}.component')`;
38
+ const updated = content.replace(/componentStore\s*:\s*Record<string,\s*\(\)\s*=>\s*Promise<any>>\s*=\s*\{([\s\S]*?)\}/, (_, objectContent) => {
39
+ const trimmed = objectContent.trim();
40
+ if (!trimmed) {
41
+ return `componentStore: Record<string, () => Promise<any>> = {\n ${newEntry},\n}`;
42
+ }
43
+ return `componentStore: Record<string, () => Promise<any>> = {${objectContent.trimEnd()}\n ${newEntry},\n}`;
44
+ });
45
+ tree.overwrite(servicePath, updated);
46
+ return tree;
47
+ };
48
+ }
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/management-base-component/index.ts"],"names":[],"mappings":";;AAgBA,0DAKC;AArBD,2DAaoC;AAGpC,SAAgB,uBAAuB,CAAC,OAAsC;IAC5E,OAAO,IAAA,kBAAK,EAAC;QACX,gBAAgB,CAAC,OAAO,CAAC;QACzB,oBAAoB,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAsC;IAC9D,OAAO,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;QAC/C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,oBAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAExG,MAAM,cAAc,GAAG,IAAA,kBAAK,EAAC,IAAA,gBAAG,EAAC,SAAS,CAAC,EAAE;YAC3C,IAAA,qBAAQ,EAAC;gBACP,GAAG,oBAAO;gBACV,GAAG,OAAO;gBACV,QAAQ,EAAE,oBAAO,CAAC,QAAQ;gBAC1B,SAAS,EAAE,oBAAO,CAAC,SAAS;aAC7B,CAAC;YACF,IAAA,gCAAmB,GAAE;YACrB,IAAA,iBAAI,EAAC,WAAW,OAAO,CAAC,IAAI,IAAI,oBAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;SACnE,CAAC,CAAC;QAEH,OAAO,IAAA,sBAAS,EAAC,cAAc,EAAE,0BAAa,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAsC;IAClE,OAAO,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;QAC/C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,oBAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAE3G,MAAM,WAAW,GAAG,yCAAyC,CAAC;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,oBAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,aAAa,sBAAsB,aAAa,IAAI,aAAa,cAAc,CAAC;QAErG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAC7B,sFAAsF,EACtF,CAAC,CAAM,EAAE,aAAkB,EAAE,EAAE;YAC7B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,+DAA+D,QAAQ,MAAM,CAAC;YACvF,CAAC;YACD,OAAO,yDAAyD,aAAa,CAAC,OAAO,EAAE,SAAS,QAAQ,MAAM,CAAC;QACjH,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/management-base-component/schema.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ngAdd = ngAdd;
4
+ const PACKAGE_NAME = 'ngine-component';
5
+ function ngAdd() {
6
+ return (tree, context) => {
7
+ const angularJsonPath = 'angular.json';
8
+ if (!tree.exists(angularJsonPath)) {
9
+ context.logger.warn('Could not find angular.json. Please add the collection manually.');
10
+ return tree;
11
+ }
12
+ const angularJsonContent = tree.read(angularJsonPath);
13
+ if (!angularJsonContent) {
14
+ context.logger.warn('Could not read angular.json.');
15
+ return tree;
16
+ }
17
+ const angularJson = JSON.parse(angularJsonContent.toString('utf-8'));
18
+ // Ensure cli section exists
19
+ if (!angularJson['cli']) {
20
+ angularJson['cli'] = {};
21
+ }
22
+ // Ensure schematicCollections array exists
23
+ if (!angularJson['cli']['schematicCollections']) {
24
+ angularJson['cli']['schematicCollections'] = ['@schematics/angular'];
25
+ }
26
+ const collections = angularJson['cli']['schematicCollections'];
27
+ if (collections.includes(PACKAGE_NAME)) {
28
+ context.logger.info(`✅ "${PACKAGE_NAME}" is already registered in angular.json.`);
29
+ return tree;
30
+ }
31
+ // Add our package to the list
32
+ collections.push(PACKAGE_NAME);
33
+ angularJson['cli']['schematicCollections'] = collections;
34
+ tree.overwrite(angularJsonPath, JSON.stringify(angularJson, null, 2));
35
+ context.logger.info(`✅ "${PACKAGE_NAME}" added to schematicCollections in angular.json.`);
36
+ context.logger.info(`👉 You can now run the two following commands:
37
+ - ng generate base-component <name>
38
+ - ng generate management-base-component <name>
39
+ `);
40
+ return tree;
41
+ };
42
+ }
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ng-add/index.ts"],"names":[],"mappings":";;AAIA,sBAsDC;AAxDD,MAAM,YAAY,GAAG,iBAAiB,CAAC;AAEvC,SAAgB,KAAK;IACnB,OAAO,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;QAC/C,MAAM,eAAe,GAAG,cAAc,CAAC;QAEvC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,kEAAkE,CACnE,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACtD,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAErE,4BAA4B;QAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC1B,CAAC;QAED,2CAA2C;QAC3C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAChD,WAAW,CAAC,KAAK,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,WAAW,GAAa,WAAW,CAAC,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC;QAEzE,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,MAAM,YAAY,0CAA0C,CAC7D,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,8BAA8B;QAC9B,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/B,WAAW,CAAC,KAAK,CAAC,CAAC,sBAAsB,CAAC,GAAG,WAAW,CAAC;QAEzD,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEtE,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,MAAM,YAAY,kDAAkD,CACrE,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;;;KAGnB,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "ngine-component",
3
+ "version": "1.0.0",
4
+ "description": "Angular schematics for the SE Intel Web Portal",
5
+ "keywords": ["schematics", "angular", "se-intel"],
6
+ "schematics": "./collection.json",
7
+ "main": "./src/index.js",
8
+ "scripts": {
9
+ "build": "tsc -p tsconfig.json && npm run copy:files",
10
+ "build:watch": "tsc -p tsconfig.json --watch",
11
+ "copy:files": "xcopy /E /I /Y src\\base-component\\files dist\\base-component\\files && xcopy /E /I /Y src\\management-base-component\\files dist\\management-base-component\\files"
12
+ },
13
+ "dependencies": {
14
+ "@angular-devkit/core": "^17.0.0",
15
+ "@angular-devkit/schematics": "^17.0.0"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "^5.0.0"
19
+ }
20
+ }
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';
4
+
5
+ describe('<%= classify(name) %>Component', () => {
6
+ let component: <%= classify(name) %>Component;
7
+ let fixture: ComponentFixture<<%= classify(name) %>Component>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [<%= classify(name) %>Component],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(<%= classify(name) %>Component);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { NavigationBaseComponent } from '../../core/components/navigation-base/navigation-base.component';
3
+
4
+ @Component({
5
+ selector: '<%= prefix %>-<%= dasherize(name) %>',
6
+ templateUrl: './<%= dasherize(name) %>.component.html',
7
+ styleUrls: ['./<%= dasherize(name) %>.component.scss'],
8
+ })
9
+ export class <%= classify(name) %>Component extends NavigationBaseComponent {
10
+
11
+ constructor() { super(); }
12
+
13
+ }
@@ -0,0 +1,71 @@
1
+ import {
2
+ apply,
3
+ chain,
4
+ MergeStrategy,
5
+ mergeWith,
6
+ move,
7
+ renameTemplateFiles,
8
+ Rule,
9
+ SchematicContext,
10
+ strings,
11
+ template,
12
+ Tree,
13
+ url,
14
+ } from '@angular-devkit/schematics';
15
+ import { BaseComponentSchema } from './schema';
16
+
17
+ export function baseComponent(options: BaseComponentSchema): Rule {
18
+ return chain([
19
+ _createComponent(options),
20
+ _addToComponentStore(options),
21
+ ]);
22
+ }
23
+
24
+ function _createComponent(options: BaseComponentSchema): Rule {
25
+ return (tree: Tree, context: SchematicContext) => {
26
+ context.logger.info(`Generating base component: ${strings.classify(options.name)}Component`);
27
+
28
+ const templateSource = apply(url('./files'), [
29
+ template({
30
+ ...strings,
31
+ ...options,
32
+ classify: strings.classify,
33
+ dasherize: strings.dasherize,
34
+ }),
35
+ renameTemplateFiles(),
36
+ move(`src/app/${options.path}/${strings.dasherize(options.name)}`),
37
+ ]);
38
+
39
+ return mergeWith(templateSource, MergeStrategy.Overwrite);
40
+ };
41
+ }
42
+
43
+ function _addToComponentStore(options: BaseComponentSchema): Rule {
44
+ return (tree: Tree, context: SchematicContext) => {
45
+ context.logger.info(`Adding component: ${strings.classify(options.name)}Component to the component store`);
46
+
47
+ const servicePath = 'src/app/components/component.service.ts';
48
+ const buffer = tree.read(servicePath);
49
+ if (!buffer) {
50
+ throw new Error(`File not found: ${servicePath}`);
51
+ }
52
+
53
+ const content = buffer.toString('utf-8');
54
+ const componentName = strings.dasherize(options.name);
55
+ const newEntry = `'${componentName}': () => import('./${componentName}/${componentName}.component')`;
56
+
57
+ const updated = content.replace(
58
+ /componentStore\s*:\s*Record<string,\s*\(\)\s*=>\s*Promise<any>>\s*=\s*\{([\s\S]*?)\}/,
59
+ (_: any, objectContent: any) => {
60
+ const trimmed = objectContent.trim();
61
+ if (!trimmed) {
62
+ return `componentStore: Record<string, () => Promise<any>> = {\n ${newEntry},\n}`;
63
+ }
64
+ return `componentStore: Record<string, () => Promise<any>> = {${objectContent.trimEnd()}\n ${newEntry},\n}`;
65
+ }
66
+ );
67
+
68
+ tree.overwrite(servicePath, updated);
69
+ return tree;
70
+ };
71
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "BaseComponentSchema",
4
+ "title": "Base Component Options",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "The name of the component (e.g. 'my-feature' → MyFeatureComponent).",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ }
14
+ },
15
+ "path": {
16
+ "type": "string",
17
+ "description": "The path to create the component in, relative to src/app.",
18
+ "default": "components"
19
+ },
20
+ "prefix": {
21
+ "type": "string",
22
+ "description": "The selector prefix (e.g. 'app' → app-my-feature).",
23
+ "default": "app"
24
+ }
25
+ },
26
+ "required": ["name"]
27
+ }
@@ -0,0 +1,5 @@
1
+ export interface BaseComponentSchema {
2
+ name: string;
3
+ path: string;
4
+ prefix: string;
5
+ }
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';
4
+
5
+ describe('<%= classify(name) %>Component', () => {
6
+ let component: <%= classify(name) %>Component;
7
+ let fixture: ComponentFixture<<%= classify(name) %>Component>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [<%= classify(name) %>Component],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(<%= classify(name) %>Component);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { ManagementBaseComponent } from '../../core/components/management-base/management-base.component';
3
+
4
+ @Component({
5
+ selector: '<%= prefix %>-<%= dasherize(name) %>',
6
+ templateUrl: './<%= dasherize(name) %>.component.html',
7
+ styleUrls: ['./<%= dasherize(name) %>.component.scss'],
8
+ })
9
+ export class <%= classify(name) %>Component extends ManagementBaseComponent<any /* Replace with your type */> {
10
+
11
+ constructor() { super(); }
12
+
13
+ }
@@ -0,0 +1,71 @@
1
+ import {
2
+ apply,
3
+ chain,
4
+ MergeStrategy,
5
+ mergeWith,
6
+ move,
7
+ renameTemplateFiles,
8
+ Rule,
9
+ SchematicContext,
10
+ strings,
11
+ template,
12
+ Tree,
13
+ url,
14
+ } from '@angular-devkit/schematics';
15
+ import { ManagementBaseComponentSchema } from './schema';
16
+
17
+ export function managementBaseComponent(options: ManagementBaseComponentSchema): Rule {
18
+ return chain([
19
+ _createComponent(options),
20
+ _addToComponentStore(options),
21
+ ]);
22
+ }
23
+
24
+ function _createComponent(options: ManagementBaseComponentSchema): Rule {
25
+ return (tree: Tree, context: SchematicContext) => {
26
+ context.logger.info(`Generating management base component: ${strings.classify(options.name)}Component`);
27
+
28
+ const templateSource = apply(url('./files'), [
29
+ template({
30
+ ...strings,
31
+ ...options,
32
+ classify: strings.classify,
33
+ dasherize: strings.dasherize,
34
+ }),
35
+ renameTemplateFiles(),
36
+ move(`src/app/${options.path}/${strings.dasherize(options.name)}`),
37
+ ]);
38
+
39
+ return mergeWith(templateSource, MergeStrategy.Overwrite);
40
+ };
41
+ }
42
+
43
+ function _addToComponentStore(options: ManagementBaseComponentSchema): Rule {
44
+ return (tree: Tree, context: SchematicContext) => {
45
+ context.logger.info(`Adding component: ${strings.classify(options.name)}Component to the component store`);
46
+
47
+ const servicePath = 'src/app/components/component.service.ts';
48
+ const buffer = tree.read(servicePath);
49
+ if (!buffer) {
50
+ throw new Error(`File not found: ${servicePath}`);
51
+ }
52
+
53
+ const content = buffer.toString('utf-8');
54
+ const componentName = strings.dasherize(options.name);
55
+ const newEntry = `'${componentName}': () => import('./${componentName}/${componentName}.component')`;
56
+
57
+ const updated = content.replace(
58
+ /componentStore\s*:\s*Record<string,\s*\(\)\s*=>\s*Promise<any>>\s*=\s*\{([\s\S]*?)\}/,
59
+ (_: any, objectContent: any) => {
60
+ const trimmed = objectContent.trim();
61
+ if (!trimmed) {
62
+ return `componentStore: Record<string, () => Promise<any>> = {\n ${newEntry},\n}`;
63
+ }
64
+ return `componentStore: Record<string, () => Promise<any>> = {${objectContent.trimEnd()}\n ${newEntry},\n}`;
65
+ }
66
+ );
67
+
68
+ tree.overwrite(servicePath, updated);
69
+ return tree;
70
+ };
71
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "ManagementBaseComponentSchema",
4
+ "title": "Management Base Component Options",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "The name of the component (e.g. 'my-feature' → MyFeatureComponent).",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ }
14
+ },
15
+ "path": {
16
+ "type": "string",
17
+ "description": "The path to create the component in, relative to src/app.",
18
+ "default": "components"
19
+ },
20
+ "prefix": {
21
+ "type": "string",
22
+ "description": "The selector prefix (e.g. 'app' → app-my-feature).",
23
+ "default": "app"
24
+ }
25
+ },
26
+ "required": ["name"]
27
+ }
@@ -0,0 +1,5 @@
1
+ export interface ManagementBaseComponentSchema {
2
+ name: string;
3
+ path: string;
4
+ prefix: string;
5
+ }
@@ -0,0 +1,59 @@
1
+ import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
2
+
3
+ const PACKAGE_NAME = 'ngine-component';
4
+
5
+ export function ngAdd(): Rule {
6
+ return (tree: Tree, context: SchematicContext) => {
7
+ const angularJsonPath = 'angular.json';
8
+
9
+ if (!tree.exists(angularJsonPath)) {
10
+ context.logger.warn(
11
+ 'Could not find angular.json. Please add the collection manually.',
12
+ );
13
+ return tree;
14
+ }
15
+
16
+ const angularJsonContent = tree.read(angularJsonPath);
17
+ if (!angularJsonContent) {
18
+ context.logger.warn('Could not read angular.json.');
19
+ return tree;
20
+ }
21
+
22
+ const angularJson = JSON.parse(angularJsonContent.toString('utf-8'));
23
+
24
+ // Ensure cli section exists
25
+ if (!angularJson['cli']) {
26
+ angularJson['cli'] = {};
27
+ }
28
+
29
+ // Ensure schematicCollections array exists
30
+ if (!angularJson['cli']['schematicCollections']) {
31
+ angularJson['cli']['schematicCollections'] = ['@schematics/angular'];
32
+ }
33
+
34
+ const collections: string[] = angularJson['cli']['schematicCollections'];
35
+
36
+ if (collections.includes(PACKAGE_NAME)) {
37
+ context.logger.info(
38
+ `✅ "${PACKAGE_NAME}" is already registered in angular.json.`,
39
+ );
40
+ return tree;
41
+ }
42
+
43
+ // Add our package to the list
44
+ collections.push(PACKAGE_NAME);
45
+ angularJson['cli']['schematicCollections'] = collections;
46
+
47
+ tree.overwrite(angularJsonPath, JSON.stringify(angularJson, null, 2));
48
+
49
+ context.logger.info(
50
+ `✅ "${PACKAGE_NAME}" added to schematicCollections in angular.json.`,
51
+ );
52
+ context.logger.info(`👉 You can now run the two following commands:
53
+ - ng generate base-component <name>
54
+ - ng generate management-base-component <name>
55
+ `);
56
+
57
+ return tree;
58
+ };
59
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "lib": ["es2020", "dom"],
5
+ "module": "commonjs",
6
+ "moduleResolution": "node",
7
+ "noEmitOnError": true,
8
+ "noFallthroughCasesInSwitch": true,
9
+ "noImplicitAny": true,
10
+ "noImplicitOverride": true,
11
+ "noImplicitReturns": true,
12
+ "noPropertyAccessFromIndexSignature": true,
13
+ "outDir": "./dist",
14
+ "rootDir": "./src",
15
+ "skipDefaultLibCheck": true,
16
+ "skipLibCheck": true,
17
+ "sourceMap": true,
18
+ "strict": true,
19
+ "target": "ES2020"
20
+ },
21
+ "include": ["src/**/*.ts"],
22
+ "exclude": ["src/**/files/**/*"]
23
+ }