@azure-net/cli 2.0.5 → 2.0.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/bin/azure-net.js CHANGED
@@ -18,7 +18,10 @@ import {
18
18
  generateSchema,
19
19
  generatePresenter,
20
20
  generateModule,
21
- generateCrud
21
+ generateCrudBase,
22
+ generateCrudPresenter,
23
+ generatePresenterByService,
24
+ generateServiceByRepo
22
25
  } from '../src/commands/generate/index.js';
23
26
 
24
27
  const program = new Command();
@@ -32,7 +35,7 @@ program
32
35
  program
33
36
  .command('init:lint')
34
37
  .description('Setup linting and commit tools')
35
- .action(initLint)
38
+ .action(initLint);
36
39
 
37
40
  program
38
41
  .command('init:structure')
@@ -113,8 +116,23 @@ program
113
116
  .action(generateModule);
114
117
 
115
118
  program
116
- .command('make:crud')
117
- .description('Generate CRUD module')
118
- .action(generateCrud);
119
+ .command('make:crud-base')
120
+ .description('Generate CRUD repository and service')
121
+ .action(generateCrudBase);
122
+
123
+ program
124
+ .command('make:crud-presenter')
125
+ .description('Generate CRUD presenter for existing service')
126
+ .action(generateCrudPresenter);
127
+
128
+ program
129
+ .command('make:presenter-by-service')
130
+ .description('Generate presenter from existing service')
131
+ .action(generatePresenterByService);
132
+
133
+ program
134
+ .command('make:service-by-repo')
135
+ .description('Generate service from existing repository')
136
+ .action(generateServiceByRepo);
119
137
 
120
138
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-net/cli",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "azure-net": "bin/azure-net.js"
@@ -0,0 +1,188 @@
1
+ import prompts from 'prompts';
2
+ import path from 'path';
3
+ import { selectContext, getContextPath, toPascalCase, toCamelCase, getAvailableFiles } from '../../utils/contextUtils.js';
4
+ import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
5
+
6
+ // Templates for CRUD base generation
7
+ const entityTemplate = `export interface I{{name}} {
8
+ \tid: number;
9
+ \t// Add entity fields here
10
+ \tcreated_at: string;
11
+ \tupdated_at: string;
12
+ }`;
13
+
14
+ const portsIndexTemplate = `import type { I{{name}} } from '\${{context}}/Domain/Entities/{{name}}';
15
+
16
+ export interface I{{name}}Collection {
17
+ \tdata: I{{name}}[];
18
+ \ttotal: number;
19
+ }
20
+
21
+ export interface I{{name}}CollectionQuery {
22
+ \tpage?: number;
23
+ \tperPage?: number;
24
+ \t[key: string]: unknown;
25
+ }
26
+
27
+ export interface I{{name}}CreateRequest {
28
+ \t// Add request fields here
29
+ \t[key: string]: unknown;
30
+ }
31
+
32
+ export interface I{{name}}UpdateRequest {
33
+ \t// Add request fields here
34
+ \t[key: string]: unknown;
35
+ }`;
36
+
37
+ const repositoryTemplate = `import { {{datasource}} } from '{{datasourceImport}}';
38
+ import type { I{{name}} } from '\${{context}}/Domain/Entities/{{name}}';
39
+ import type {
40
+ \tI{{name}}Collection,
41
+ \tI{{name}}CollectionQuery,
42
+ \tI{{name}}CreateRequest,
43
+ \tI{{name}}UpdateRequest
44
+ } from '\${{context}}/Domain/Ports/{{name}}';
45
+
46
+ export class {{name}}Repository {
47
+ \tprivate endpoint = '{{endpoint}}';
48
+ \t
49
+ \tconstructor(private {{datasourceVar}}: {{datasource}}) {}
50
+ \t
51
+ \tpublic async collection(query?: I{{name}}CollectionQuery) {
52
+ \t\treturn this.{{datasourceVar}}.createRequest<I{{name}}Collection>(({ http, query: q }) =>
53
+ \t\t\thttp.get(\`\${this.endpoint}\${q.build(query || {})}\`)
54
+ \t\t).then(res => res.getData());
55
+ \t}
56
+ \t
57
+ \tpublic async resource(id: number) {
58
+ \t\treturn this.{{datasourceVar}}.createRequest<I{{name}}>(({ http }) =>
59
+ \t\t\thttp.get(\`\${this.endpoint}/\${id}\`)
60
+ \t\t).then(res => res.getData());
61
+ \t}
62
+ \t
63
+ \tpublic async create(data: I{{name}}CreateRequest) {
64
+ \t\treturn this.{{datasourceVar}}.createRequest<I{{name}}>(({ http }) =>
65
+ \t\t\thttp.post(this.endpoint, { json: data })
66
+ \t\t).then(res => res.getData());
67
+ \t}
68
+ \t
69
+ \tpublic async update(id: number, data: I{{name}}UpdateRequest) {
70
+ \t\treturn this.{{datasourceVar}}.createRequest<I{{name}}>(({ http }) =>
71
+ \t\t\thttp.put(\`\${this.endpoint}/\${id}\`, { json: data })
72
+ \t\t).then(res => res.getData());
73
+ \t}
74
+ \t
75
+ \tpublic async remove(id: number) {
76
+ \t\treturn this.{{datasourceVar}}.createRequest<void>(({ http }) =>
77
+ \t\t\thttp.delete(\`\${this.endpoint}/\${id}\`)
78
+ \t\t).then(() => undefined);
79
+ \t}
80
+ }`;
81
+
82
+ const serviceTemplate = `import { ClassMirror } from '@azure-net/kit';
83
+ import { {{name}}Repository } from '\${{context}}/Infrastructure/Http/Repositories';
84
+
85
+ export class {{name}}Service extends ClassMirror<{{name}}Repository> {
86
+ \tconstructor(private {{camelName}}Repository: {{name}}Repository) {
87
+ \t\tsuper({{camelName}}Repository);
88
+ \t}
89
+ \t
90
+ \tdeclare collection: {{name}}Repository['collection'];
91
+ \tdeclare resource: {{name}}Repository['resource'];
92
+ \tdeclare create: {{name}}Repository['create'];
93
+ \tdeclare update: {{name}}Repository['update'];
94
+ \tdeclare remove: {{name}}Repository['remove'];
95
+ }`;
96
+
97
+ export default async function generateCrudBase() {
98
+ const context = await selectContext('Select context for CRUD base:');
99
+
100
+ const { name } = await prompts({
101
+ type: 'text',
102
+ name: 'name',
103
+ message: 'Entity name (PascalCase):'
104
+ });
105
+
106
+ const { endpoint } = await prompts({
107
+ type: 'text',
108
+ name: 'endpoint',
109
+ message: 'API endpoint (e.g. /api/users):'
110
+ });
111
+
112
+ // Get available datasources
113
+ const contextPath = getContextPath(context);
114
+ const sharedDatasources = await getAvailableFiles(
115
+ path.join(process.cwd(), 'src/app/shared/Datasource')
116
+ );
117
+ const contextDatasources = await getAvailableFiles(
118
+ path.join(contextPath, 'Infrastructure/Http/Datasource')
119
+ );
120
+
121
+ const allDatasources = [
122
+ ...sharedDatasources.map(d => ({ title: `${d} (shared)`, value: { name: d, from: 'shared' } })),
123
+ ...contextDatasources.map(d => ({ title: `${d} (${context})`, value: { name: d, from: context } }))
124
+ ];
125
+
126
+ const { datasource } = await prompts({
127
+ type: 'select',
128
+ name: 'datasource',
129
+ message: 'Select datasource:',
130
+ choices: allDatasources
131
+ });
132
+
133
+ const pascalName = toPascalCase(name);
134
+ const camelName = toCamelCase(name);
135
+
136
+ console.log('\n🚀 Generating CRUD base (repository & service)...\n');
137
+
138
+ // 1. Create Entity
139
+ const entityPath = path.join(contextPath, 'Domain/Entities', pascalName);
140
+ await writeIfNotExists(
141
+ path.join(entityPath, 'index.ts'),
142
+ entityTemplate.replace(/{{name}}/g, pascalName)
143
+ );
144
+
145
+ // 2. Create Ports
146
+ const portsPath = path.join(contextPath, 'Domain/Ports', pascalName);
147
+ await writeIfNotExists(
148
+ path.join(portsPath, 'index.ts'),
149
+ portsIndexTemplate
150
+ .replace(/{{name}}/g, pascalName)
151
+ .replace(/{{context}}/g, context)
152
+ );
153
+
154
+ // 3. Create Repository
155
+ const repoPath = path.join(contextPath, 'Infrastructure/Http/Repositories');
156
+ const datasourceImport = datasource.from === 'shared'
157
+ ? '$shared/Datasource'
158
+ : `\$${context}/Infrastructure/Http/Datasource`;
159
+
160
+ await writeIfNotExists(
161
+ path.join(repoPath, `${pascalName}Repository.ts`),
162
+ repositoryTemplate
163
+ .replace(/{{name}}/g, pascalName)
164
+ .replace(/{{context}}/g, context)
165
+ .replace(/{{endpoint}}/g, endpoint)
166
+ .replace(/{{datasource}}/g, datasource.name)
167
+ .replace(/{{datasourceImport}}/g, datasourceImport)
168
+ .replace(/{{datasourceVar}}/g, toCamelCase(datasource.name))
169
+ );
170
+ await updateIndexTs(repoPath);
171
+
172
+ // 4. Create Service
173
+ const servicePath = path.join(contextPath, 'Application/Services');
174
+ await writeIfNotExists(
175
+ path.join(servicePath, `${pascalName}Service.ts`),
176
+ serviceTemplate
177
+ .replace(/{{name}}/g, pascalName)
178
+ .replace(/{{camelName}}/g, camelName)
179
+ .replace(/{{context}}/g, context)
180
+ );
181
+ await updateIndexTs(servicePath);
182
+
183
+ console.log(`✅ CRUD base for ${pascalName} created successfully!`);
184
+ console.log(`\n💡 Remember to:`);
185
+ console.log(` 1. Add ${pascalName}Repository to InfrastructureProvider`);
186
+ console.log(` 2. Add ${pascalName}Service to ApplicationProvider`);
187
+ console.log(` 3. Use 'make:crud-presenter' to create the CRUD presenter`);
188
+ }
@@ -0,0 +1,220 @@
1
+ import prompts from 'prompts';
2
+ import path from 'path';
3
+ import fs from 'fs/promises';
4
+ import { selectContext, getContextPath, toPascalCase, getAvailableFiles, getApplicationProviderServices } from '../../utils/contextUtils.js';
5
+ import { writeIfNotExists } from '../../utils/fileUtils.js';
6
+
7
+ const createSchemaTemplate = `import { {{schemaFactory}} } from '{{schemaImport}}';
8
+ import type { I{{name}}CreateRequest } from '\${{context}}/Domain/Ports/{{entity}}';
9
+
10
+ export const Create{{name}}Schema = {{schemaFactory}}<I{{name}}CreateRequest>()
11
+ \t.rules((rules) => ({
12
+ \t\t// Add validation rules here
13
+ \t}))
14
+ \t.create();`;
15
+
16
+ const updateSchemaTemplate = `import { {{schemaFactory}} } from '{{schemaImport}}';
17
+ import type { I{{name}}UpdateRequest } from '\${{context}}/Domain/Ports/{{entity}}';
18
+
19
+ export const Update{{name}}Schema = {{schemaFactory}}<I{{name}}UpdateRequest>()
20
+ \t.rules((rules) => ({
21
+ \t\t// Add validation rules here
22
+ \t}))
23
+ \t.create();`;
24
+
25
+ const presenterWithSharedTemplate = `import { {{presenterFactory}} } from '$shared/Presenter';
26
+ import { ApplicationProvider } from '\${{context}}/Application';
27
+ import { Create{{name}}Schema, Update{{name}}Schema } from './Schema';
28
+ import type {
29
+ \tI{{name}}CollectionQuery,
30
+ \tI{{name}}CreateRequest,
31
+ \tI{{name}}UpdateRequest
32
+ } from '\${{context}}/Domain/Ports/{{name}}';
33
+
34
+ export const {{name}}Presenter = {{presenterFactory}}('{{name}}Presenter', ({ createAsyncResource, createAsyncAction }) => {
35
+ \tconst { {{serviceName}} } = ApplicationProvider();
36
+ \t
37
+ \tconst collection = async (query?: I{{name}}CollectionQuery) =>
38
+ \t\tawait createAsyncResource({{serviceName}}.collection(query));
39
+ \t
40
+ \tconst resource = async (id: number) =>
41
+ \t\tawait createAsyncResource({{serviceName}}.resource(id));
42
+ \t
43
+ \tconst create = async (request: I{{name}}CreateRequest) =>
44
+ \t\tawait createAsyncAction({{serviceName}}.create(Create{{name}}Schema.from(request).json()));
45
+ \t
46
+ \tconst update = async (id: number, request: I{{name}}UpdateRequest) =>
47
+ \t\tawait createAsyncAction({{serviceName}}.update(id, Update{{name}}Schema.from(request).json()));
48
+ \t
49
+ \tconst remove = async (id: number) =>
50
+ \t\tawait createAsyncAction({{serviceName}}.remove(id));
51
+ \t
52
+ \treturn { collection, resource, create, update, remove };
53
+ });`;
54
+
55
+ const presenterWithoutSharedTemplate = `import { createPresenter } from '@azure-net/kit';
56
+ import { ApplicationProvider } from '\${{context}}/Application';
57
+ import { Create{{name}}Schema, Update{{name}}Schema } from './Schema';
58
+ import type {
59
+ \tI{{name}}CollectionQuery,
60
+ \tI{{name}}CreateRequest,
61
+ \tI{{name}}UpdateRequest
62
+ } from '\${{context}}/Domain/Ports/{{name}}';
63
+
64
+ export const {{name}}Presenter = createPresenter('{{name}}Presenter', () => {
65
+ \tconst { {{serviceName}} } = ApplicationProvider();
66
+ \t
67
+ \tconst collection = async (query?: I{{name}}CollectionQuery) =>
68
+ \t\tawait {{serviceName}}.collection(query);
69
+ \t
70
+ \tconst resource = async (id: number) =>
71
+ \t\tawait {{serviceName}}.resource(id);
72
+ \t
73
+ \tconst create = async (request: I{{name}}CreateRequest) =>
74
+ \t\tawait {{serviceName}}.create(Create{{name}}Schema.from(request).json());
75
+ \t
76
+ \tconst update = async (id: number, request: I{{name}}UpdateRequest) =>
77
+ \t\tawait {{serviceName}}.update(id, Update{{name}}Schema.from(request).json());
78
+ \t
79
+ \tconst remove = async (id: number) =>
80
+ \t\tawait {{serviceName}}.remove(id);
81
+ \t
82
+ \treturn { collection, resource, create, update, remove };
83
+ });`;
84
+
85
+ export default async function generateCrudPresenter() {
86
+ const context = await selectContext('Select context for CRUD presenter:');
87
+
88
+ // Get available services from ApplicationProvider
89
+ const services = await getApplicationProviderServices(context);
90
+
91
+ if (services.length === 0) {
92
+ console.error('❌ No services found in ApplicationProvider. Add services manually first.');
93
+ return;
94
+ }
95
+
96
+ const { service } = await prompts({
97
+ type: 'select',
98
+ name: 'service',
99
+ message: 'Select service for CRUD:',
100
+ choices: services.map(s => ({ title: s, value: s }))
101
+ });
102
+
103
+ // Extract entity name from service name
104
+ const entityName = service.replace('Service', '');
105
+ const pascalName = toPascalCase(entityName);
106
+
107
+ // Get schema factory
108
+ const sharedSchemas = await getAvailableFiles(
109
+ path.join(process.cwd(), 'src/app/shared/Schema')
110
+ );
111
+
112
+ const { schemaType } = await prompts({
113
+ type: 'select',
114
+ name: 'schemaType',
115
+ message: 'Select schema factory:',
116
+ choices: [
117
+ { title: 'Use createSchemaFactory from package', value: 'package' },
118
+ ...sharedSchemas.map(s => ({ title: `Use ${s} from shared`, value: s }))
119
+ ]
120
+ });
121
+
122
+ // Get presenter factory
123
+ const sharedPresenters = await getAvailableFiles(
124
+ path.join(process.cwd(), 'src/app/shared/Presenter')
125
+ );
126
+
127
+ const { presenterType } = await prompts({
128
+ type: 'select',
129
+ name: 'presenterType',
130
+ message: 'Select presenter factory:',
131
+ choices: [
132
+ { title: 'Use createPresenter from package', value: 'package' },
133
+ ...sharedPresenters.map(p => ({ title: `Use ${p} from shared`, value: p }))
134
+ ]
135
+ });
136
+
137
+ const contextPath = getContextPath(context);
138
+ const deliveryModulePath = path.join(contextPath, 'Delivery', pascalName);
139
+ const schemaPath = path.join(deliveryModulePath, 'Schema');
140
+
141
+ console.log('\n🚀 Generating CRUD presenter...\n');
142
+
143
+ // Create schemas
144
+ const schemaFactory = schemaType === 'package' ? 'Schema' : schemaType;
145
+ const schemaImport = schemaType === 'package'
146
+ ? '@azure-net/kit'
147
+ : '$shared/Schema';
148
+
149
+ if (schemaType === 'package') {
150
+ const schemaImportFull = `import { createSchemaFactory } from '@azure-net/kit';
151
+ import { createRules, validationMessagesI18n } from '@azure-net/kit/schema';
152
+
153
+ const Schema = createSchemaFactory(createRules(validationMessagesI18n));`;
154
+
155
+ await writeIfNotExists(
156
+ path.join(schemaPath, `Create${pascalName}Schema.ts`),
157
+ schemaImportFull + '\n' + createSchemaTemplate
158
+ .replace('import { {{schemaFactory}} } from \'{{schemaImport}}\';\n', '')
159
+ .replace(/{{name}}/g, pascalName)
160
+ .replace(/{{context}}/g, context)
161
+ .replace(/{{entity}}/g, pascalName)
162
+ .replace(/{{schemaFactory}}/g, 'Schema')
163
+ );
164
+
165
+ await writeIfNotExists(
166
+ path.join(schemaPath, `Update${pascalName}Schema.ts`),
167
+ schemaImportFull + '\n' + updateSchemaTemplate
168
+ .replace('import { {{schemaFactory}} } from \'{{schemaImport}}\';\n', '')
169
+ .replace(/{{name}}/g, pascalName)
170
+ .replace(/{{context}}/g, context)
171
+ .replace(/{{entity}}/g, pascalName)
172
+ .replace(/{{schemaFactory}}/g, 'Schema')
173
+ );
174
+ } else {
175
+ await writeIfNotExists(
176
+ path.join(schemaPath, `Create${pascalName}Schema.ts`),
177
+ createSchemaTemplate
178
+ .replace(/{{name}}/g, pascalName)
179
+ .replace(/{{context}}/g, context)
180
+ .replace(/{{entity}}/g, pascalName)
181
+ .replace(/{{schemaFactory}}/g, schemaFactory)
182
+ .replace(/{{schemaImport}}/g, schemaImport)
183
+ );
184
+
185
+ await writeIfNotExists(
186
+ path.join(schemaPath, `Update${pascalName}Schema.ts`),
187
+ updateSchemaTemplate
188
+ .replace(/{{name}}/g, pascalName)
189
+ .replace(/{{context}}/g, context)
190
+ .replace(/{{entity}}/g, pascalName)
191
+ .replace(/{{schemaFactory}}/g, schemaFactory)
192
+ .replace(/{{schemaImport}}/g, schemaImport)
193
+ );
194
+ }
195
+ await updateIndexTs(schemaPath);
196
+
197
+ // Create Presenter
198
+ const presenterTemplate = presenterType === 'package'
199
+ ? presenterWithoutSharedTemplate
200
+ : presenterWithSharedTemplate;
201
+
202
+ const presenterFactory = presenterType === 'package' ? 'createPresenter' : presenterType;
203
+
204
+ await writeIfNotExists(
205
+ path.join(deliveryModulePath, `${pascalName}Presenter.ts`),
206
+ presenterTemplate
207
+ .replace(/{{name}}/g, pascalName)
208
+ .replace(/{{context}}/g, context)
209
+ .replace(/{{serviceName}}/g, service)
210
+ .replace(/{{presenterFactory}}/g, presenterFactory)
211
+ );
212
+
213
+ // Create module index
214
+ await writeIfNotExists(
215
+ path.join(deliveryModulePath, 'index.ts'),
216
+ `export * from './${pascalName}Presenter';\nexport * from './Schema';`
217
+ );
218
+
219
+ console.log(`✅ CRUD presenter for ${pascalName} created successfully!`);
220
+ }
@@ -1,6 +1,5 @@
1
1
  import prompts from 'prompts';
2
2
  import path from 'path';
3
- import fs from 'fs/promises';
4
3
  import { selectContext, getContextPath, toPascalCase, getAvailableFiles } from '../../utils/contextUtils.js';
5
4
  import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
6
5
 
@@ -9,22 +8,13 @@ import { {{responseClass}}, type {{responseInterface}} } from '{{responseImport}
9
8
  import { HttpService } from '@azure-net/kit/infra';
10
9
 
11
10
  export class {{name}}Datasource extends BaseHttpDatasource {
12
- \tconstructor(config?: { baseUrl?: string; [key: string]: unknown }) {
13
- \t\tsuper({
14
- \t\t\thttp: new HttpService({
15
- \t\t\t\tbaseUrl: config?.baseUrl || 'https://api.example.com',
16
- \t\t\t\t...config
17
- \t\t\t})
18
- \t\t});
19
- \t}
20
-
21
11
  \tasync createRequest<T>(callback: CreateRequestCallbackType<{{responseInterface}}<T>>) {
22
12
  \t\treturn new {{responseClass}}<T>(await this.createRawRequest<{{responseInterface}}<T>>(callback));
23
13
  \t}
24
14
  }`;
25
15
 
26
16
  export default async function generateDatasource() {
27
- const context = await selectContext();
17
+ const context = await selectContext('Select context for datasource (or shared):');
28
18
 
29
19
  const { name } = await prompts({
30
20
  type: 'text',
@@ -33,21 +23,23 @@ export default async function generateDatasource() {
33
23
  });
34
24
 
35
25
  const pascalName = toPascalCase(name);
36
- const contextPath = getContextPath(context);
26
+ const contextPath = context === 'shared'
27
+ ? path.join(process.cwd(), 'src/app/shared')
28
+ : getContextPath(context);
37
29
 
38
30
  // Get available responses
39
- const coreResponses = await getAvailableFiles(
40
- path.join(process.cwd(), 'src/app/core/Response')
31
+ const sharedResponses = await getAvailableFiles(
32
+ path.join(process.cwd(), 'src/app/shared/Response')
41
33
  );
42
34
 
43
- const contextResponses = context !== 'core'
35
+ const contextResponses = context !== 'shared'
44
36
  ? await getAvailableFiles(path.join(contextPath, 'Infrastructure/Response'))
45
37
  : [];
46
38
 
47
39
  const allResponses = [
48
- ...coreResponses.map(r => ({
49
- title: `${r} (core)`,
50
- value: { name: r, from: 'core' }
40
+ ...sharedResponses.map(r => ({
41
+ title: `${r} (shared)`,
42
+ value: { name: r, from: 'shared' }
51
43
  })),
52
44
  ...contextResponses.map(r => ({
53
45
  title: `${r} (${context})`,
@@ -70,15 +62,13 @@ export default async function generateDatasource() {
70
62
  // Determine interface name
71
63
  const responseInterface = `I${response.name.replace('Response', '')}Response`;
72
64
 
73
- const datasourcePath = context === 'core'
65
+ const datasourcePath = context === 'shared'
74
66
  ? path.join(contextPath, 'Datasource')
75
67
  : path.join(contextPath, 'Infrastructure/Http/Datasource');
76
68
 
77
- const responseImport = response.from === 'core'
78
- ? context === 'core' ? '../Response' : '$core/Response'
79
- : context === 'core'
80
- ? `../contexts/${context}/Infrastructure/Response`
81
- : '../../Response';
69
+ const responseImport = response.from === 'shared'
70
+ ? context === 'shared' ? '../Response' : '$shared/Response'
71
+ : `\$${context}/Infrastructure/Response`;
82
72
 
83
73
  const content = datasourceWithResponseTemplate
84
74
  .replace(/{{name}}/g, pascalName)
@@ -91,5 +81,4 @@ export default async function generateDatasource() {
91
81
  await updateIndexTs(datasourcePath);
92
82
 
93
83
  console.log(`✅ Datasource created at ${filePath}`);
94
- console.log(`\n💡 Remember to configure the datasource in DatasourceProvider when using it in repositories.`);
95
84
  }
@@ -6,11 +6,13 @@ import generateSchema from './generateSchema.js';
6
6
 
7
7
  export default async function generateModule() {
8
8
  console.log('🚀 Generating complete module...\n');
9
+ console.log('⚠️ Note: This will create repository, service, presenter and schemas.');
10
+ console.log(' You will need to manually wire them in the providers.\n');
9
11
 
10
12
  const { confirm } = await prompts({
11
13
  type: 'confirm',
12
14
  name: 'confirm',
13
- message: 'This will create repository, service, presenter and schemas. Continue?'
15
+ message: 'Continue?'
14
16
  });
15
17
 
16
18
  if (confirm) {
@@ -19,5 +21,11 @@ export default async function generateModule() {
19
21
  await generatePresenter();
20
22
  await generateSchema(); // Create schema
21
23
  await generateSchema(); // Update schema
24
+
25
+ console.log('\n✅ Module generation complete!');
26
+ console.log('\n💡 Remember to:');
27
+ console.log(' 1. Add repository to InfrastructureProvider');
28
+ console.log(' 2. Add service to ApplicationProvider');
29
+ console.log(' 3. Update presenter to use the service from ApplicationProvider');
22
30
  }
23
31
  }