generator-codedesignplus 0.1.0 → 0.2.0-alpha.2

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.
@@ -39,15 +39,16 @@ export default class AppSettingsGenerator {
39
39
  });
40
40
 
41
41
  try {
42
- this.updateConfigVault(path.join('tools', 'vault','config-vault.ps1'), options);
43
- this.updateConfigVault(path.join('tools', 'vault','config-vault.sh'), options);
42
+ this._updateConfigVault(path.join('tools', 'vault','config-vault.ps1'), options);
43
+ this._updateConfigVault(path.join('tools', 'vault','config-vault.sh'), options);
44
+ this._updateReadme(options);
44
45
  } catch (error) {
45
46
  console.log('The vault configuration could not be updated.');
46
47
  console.log(error);
47
48
  }
48
49
  }
49
50
 
50
- updateConfigVault(file, options) {
51
+ _updateConfigVault(file, options) {
51
52
  const configFile = this._generator.destinationPath(file);
52
53
 
53
54
  let config = this._generator.fs.read(configFile);
@@ -64,6 +65,16 @@ export default class AppSettingsGenerator {
64
65
  this._generator.fs.write(configFile, config);
65
66
  }
66
67
 
68
+ _updateReadme(options) {
69
+ const readmeFile = this._generator.destinationPath('README.md');
70
+
71
+ let readme = this._generator.fs.read(readmeFile);
72
+
73
+ readme = readme.replace(/\bms-archetype\b/g, options.appSettings.appName);
74
+
75
+ this._generator.fs.write(readmeFile, readme);
76
+ }
77
+
67
78
  getArguments() {
68
79
  this._generator.option('description', { type: String, alias: 'd', required: true, description: 'A detailed description of the microservice providing clear context about its purpose.' });
69
80
  this._generator.option('contact-name', { type: String, alias: 'cn', required: true, description: 'Name of the contact person responsible for the microservice.' });
@@ -1,5 +1,6 @@
1
1
  import path from 'path';
2
2
  import AppSettingsGenerator from './appsettings.mjs';
3
+ import ConsumerGenerator from './consumer.mjs';
3
4
  import fsSync from 'fs';
4
5
  import fs from 'fs/promises';
5
6
  import { glob } from 'glob';
@@ -8,6 +9,7 @@ export default class AsyncWorkerGenerator {
8
9
 
9
10
  constructor(utils, generator) {
10
11
  this._appsettings = new AppSettingsGenerator(utils, generator);
12
+ this._consumerGenerator = new ConsumerGenerator(utils, generator);
11
13
 
12
14
  this._utils = utils;
13
15
  this._generator = generator;
@@ -44,6 +46,9 @@ export default class AsyncWorkerGenerator {
44
46
 
45
47
  await this._generateFiles(templateAsyncWorkerProject, ignores, options, asyncWorkerIntegrationTestProjectPathDestination);
46
48
  }
49
+
50
+
51
+ this._consumerGenerator.generate(options);
47
52
 
48
53
  await this._generator.spawnCommand('dotnet', ['sln', `${destination}/${options.solution}.sln`, 'add', `${asyncWorkerProjectPathDestination}`, '--solution-folder', 'src/entrypoints']);
49
54
  await this._generator.spawnCommand('dotnet', ['sln', `${destination}/${options.solution}.sln`, 'add', `${asyncWorkerTestProjectPathDestination}`, '--solution-folder', 'tests/unit']);
@@ -60,27 +65,15 @@ export default class AsyncWorkerGenerator {
60
65
  }
61
66
 
62
67
  getArguments() {
63
-
68
+ this._consumerGenerator.getArguments();
64
69
  }
65
70
 
66
71
  _getIgnores() {
67
- const ignores = ['**/bin/**', '**/obj/**'];
68
-
69
- const items = {
70
- entryPoints_asyncWorker: [
71
- 'src/entrypoints/CodeDesignPlus.Net.Microservice.AsyncWorker/Consumers/**'
72
- ],
73
- integrationTest_asyncWorker: [
74
- 'tests/integration/CodeDesignPlus.Net.Microservice.AsyncWorker.Test/Consumers/**'
75
- ],
76
- unitTest_asyncWorker: [
77
- 'tests/unit/CodeDesignPlus.Net.Microservice.AsyncWorker.Test/Consumers/*.cs',
78
- ]
79
- }
80
-
81
- for (const key in items) {
82
- ignores.push(...items[key]);
83
- }
72
+ const ignores = [
73
+ '**/bin/**',
74
+ '**/obj/**',
75
+ '**/Consumers/**'
76
+ ];
84
77
 
85
78
  return ignores;
86
79
  }
@@ -51,14 +51,15 @@ export default class ConsumerGenerator {
51
51
 
52
52
  await this._commandGenerator.generate(options);
53
53
 
54
- await this._domainEventGenerator.generate(options);
54
+ await this._domainEventGenerator.generate(options, options.consumer.microservice);
55
55
  }
56
56
  }
57
57
 
58
58
  getArguments() {
59
59
  this._generator.option('consumer-name', { type: String, required: true, description: 'Name of the event consumer, specifying the type of event it consumes.' });
60
60
  this._generator.option('consumer-aggregate', { type: String, required: true, description: 'Aggregate to which the consumer belongs, defining the context of the event.' });
61
- this._generator.option('consumer-action', { type: String, required: true, description: 'Action to be performed in the consumer when it receives an event.' });
61
+ this._generator.option('consumer-action', { type: String, required: true, description: 'Action to be performed in the consumer when it receives an event.' });
62
+ this._generator.option('consumer-microservice', { type: String, required: true, description: 'Name of the microservice that publishes the event.' });
62
63
 
63
64
  this._generator.options = {
64
65
  ...this._generator.options,
@@ -66,6 +67,7 @@ export default class ConsumerGenerator {
66
67
  aggregate: this._generator.options['consumerAggregate'],
67
68
  consumer: this._generator.options['consumerName'],
68
69
  action: this._generator.options['consumerAction'],
70
+ microservice: this._generator.options['consumerMicroservice']
69
71
  },
70
72
  enableAsyncWorker: this._generator.options.consumerName !== undefined && this._generator.options.consumerName !== null
71
73
  };
@@ -9,8 +9,7 @@ export default class DomainEventGenerator {
9
9
  this.name = 'domainEvent';
10
10
  }
11
11
 
12
- async generate(options) {
13
-
12
+ async generate(options, microservice) {
14
13
  const to = options.isConsumer ? options.paths.src.asyncWorker : options.paths.src.domain;
15
14
  const ns = options.isConsumer ? `${options.solution}.AsyncWorker.DomainEvents` : `${options.solution}.Domain.DomainEvents`;
16
15
 
@@ -18,12 +17,13 @@ export default class DomainEventGenerator {
18
17
  const domainEvent = options.domainEvents[key];
19
18
 
20
19
  await this._generator.fs.copyTplAsync(
21
- this._generator.templatePath('domain-event/ItemDomainEvent.cs'),
20
+ this._generator.templatePath(`domain-event/${options.isConsumer ? 'ItemListenerDomainEvent' : 'ItemDomainEvent'}.cs`),
22
21
  this._generator.destinationPath(path.join(to, `DomainEvents`, domainEvent.file)),
23
22
  {
24
23
  ns: ns,
25
24
  name: domainEvent.fullname,
26
- entity: options.aggregate.fullname
25
+ entity: options.aggregate.fullname,
26
+ microservice: microservice,
27
27
  }
28
28
  );
29
29
  }
@@ -59,6 +59,8 @@ export default class GrpcGenerator {
59
59
 
60
60
  const files = glob.sync('**', { dot: true, nodir: true, cwd: templateGrpcProject, ignore: ignores });
61
61
 
62
+ console.log(templateGrpcProject, files);
63
+
62
64
  await this._utils.generateFiles(options, options.solution, templateGrpcProject, grpcProjectPathDestination, files);
63
65
 
64
66
  await this._appsettings.generate(options, [options.paths.src.grpc]);
@@ -72,25 +74,12 @@ export default class GrpcGenerator {
72
74
  }
73
75
 
74
76
  _getIgnores() {
75
- const ignores = ['**/bin/**', '**/obj/**'];
76
-
77
- const items = {
78
- entryPoints_gRpc: [
79
- 'src/entrypoints/CodeDesignPlus.Net.Microservice.gRpc/Protos/*.proto',
80
- 'src/entrypoints/CodeDesignPlus.Net.Microservice.gRpc/Services/*.cs'
81
- ],
82
- integrationTest_gRpc: [
83
- 'tests/integration/CodeDesignPlus.Net.Microservice.gRpc.Test/Protos/**',
84
- 'tests/integration/CodeDesignPlus.Net.Microservice.gRpc.Test/Services/**'
85
- ],
86
- unitTest_gRpc: [
87
- 'tests/unit/CodeDesignPlus.Net.Microservice.gRpc.Test/Services/*.cs',
88
- ]
89
- }
90
-
91
- for (const key in items) {
92
- ignores.push(...items[key]);
93
- }
77
+ const ignores = [
78
+ '**/bin/**',
79
+ '**/obj/**',
80
+ '**/Protos/**',
81
+ '**/Services/**'
82
+ ];
94
83
 
95
84
  return ignores;
96
85
  }
@@ -1,5 +1,6 @@
1
1
  import { findUp } from 'find-up';
2
2
  import fs from 'fs/promises';
3
+ import fsSync from 'fs';
3
4
  import path from 'path';
4
5
  import {
5
6
  AggregateModel,
@@ -16,8 +17,6 @@ import {
16
17
  } from '../types/index.mjs';
17
18
  import { AppSettingsModel } from '../types/appsettings.mjs';
18
19
 
19
-
20
-
21
20
  export default class Utils {
22
21
  constructor(generator) {
23
22
  this._generator = generator;
@@ -35,28 +34,24 @@ export default class Utils {
35
34
  this._generator.destinationRoot(pathBaseDir);
36
35
  }
37
36
 
38
- async readArchetypeMetadata() {
39
- const archetypeFile = await findUp('archetype.json');
40
-
41
- if (!archetypeFile)
42
- throw new Error('No se encontró el archivo archetype.json');
43
-
44
- return await this._generator.fs.readJSON(archetypeFile);
45
- }
46
-
47
37
  async getOptions(answers) {
48
- const archetypeValues = this._generator.fs.readJSON(`${path.join(this._generator.destinationRoot())}/archetype.json`);
49
-
50
- answers = {
51
- ...answers,
52
- organization: archetypeValues.organization,
53
- microservice: archetypeValues.microservice,
54
- description: archetypeValues.description,
55
- organization: archetypeValues.organization,
56
- aggregate: answers.aggregate ?? archetypeValues.aggregate,
57
- vault: archetypeValues.vault,
58
- contactName: archetypeValues.contactName,
59
- contactEmail: archetypeValues.contactEmail
38
+ const pathJson = path.join(this._generator.destinationRoot(), 'archetype.json');
39
+
40
+ if (!fsSync.existsSync(pathJson))
41
+ throw new Error('⚠️ File archetype.json not found, using the answers provided.');
42
+
43
+ const archetypeValues = this._generator.fs.readJSON(pathJson);
44
+
45
+ answers = {
46
+ ...answers,
47
+ organization: archetypeValues?.organization ?? answers.organization,
48
+ microservice: archetypeValues?.microservice ?? answers.microservice,
49
+ description: archetypeValues?.description ?? answers.description,
50
+ organization: archetypeValues?.organization ?? answers.organization,
51
+ aggregate: answers.aggregate ?? archetypeValues?.aggregate,
52
+ vault: archetypeValues?.vault ?? answers.vault,
53
+ contactName: archetypeValues?.contactName ?? answers.contactName,
54
+ contactEmail: archetypeValues?.contactEmail ?? answers.contactEmail
60
55
  };
61
56
 
62
57
  const organization = this.toPascalCase(answers.organization);
@@ -4,7 +4,7 @@
4
4
  public class <%= name %>(
5
5
  Guid aggregateId,
6
6
  Guid? eventId = null,
7
- DateTime? occurredAt = null,
7
+ Instant? occurredAt = null,
8
8
  Dictionary<string, object>? metadata = null
9
9
  ) : DomainEvent(aggregateId, eventId, occurredAt, metadata)
10
10
  {
@@ -0,0 +1,15 @@
1
+ namespace <%= ns %>;
2
+
3
+ [EventKey<<%= entity %>>(1, "<%= name %>", "<%= microservice %>")]
4
+ public class <%= name %>(
5
+ Guid aggregateId,
6
+ Guid? eventId = null,
7
+ Instant? occurredAt = null,
8
+ Dictionary<string, object>? metadata = null
9
+ ) : DomainEvent(aggregateId, eventId, occurredAt, metadata)
10
+ {
11
+ public static <%= name %> Create(Guid aggregateId)
12
+ {
13
+ return new <%= name %>(aggregateId);
14
+ }
15
+ }
@@ -4,15 +4,17 @@ export class ConsumerModel extends BaseModel {
4
4
  constructor(data) {
5
5
  super();
6
6
 
7
+
7
8
  this.sufix = 'Handler';
8
9
  this.name = this._validate(data.consumer, this.sufix);
9
10
  this.fullname = `${this.name}${this.sufix}`;
10
11
  this.file = `${this.fullname}.cs`;
11
-
12
+
12
13
  this.aggregate = `${this._validate(toPascalCase(data.aggregate), 'Aggregate')}`;
13
14
  this.action = data.action.toLowerCase();
14
15
  this.domainEvent = `${this._validate(toPascalCase(this.name), 'DomainEvent')}`;
15
16
  this.command = toPascalCase(data.action);
17
+ this.microservice = data.microservice.toLowerCase();
16
18
  }
17
19
 
18
20
  static from(data) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generator-codedesignplus",
3
- "version": "0.1.0",
3
+ "version": "0.2.0-alpha.2",
4
4
  "description": "Yeoman generator for creating microservices based on the CodeDesignPlus.Net.Microservice archetype.",
5
5
  "private": false,
6
6
  "main": "generators/index.mjs",