@azure-net/cli 2.0.5 → 2.0.7

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.
@@ -1,16 +1,17 @@
1
1
  import prompts from 'prompts';
2
2
  import path from 'path';
3
+ import fs from 'fs/promises';
3
4
  import { selectContext, getContextPath, toPascalCase, getAvailableFiles } from '../../utils/contextUtils.js';
4
- import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
5
+ import { writeIfNotExists } from '../../utils/fileUtils.js';
5
6
 
6
- const presenterWithCoreTemplate = `import { {{corePresenter}} } from '\$core/Presenter';
7
- {{serviceImport}}
7
+ const presenterWithSharedTemplate = `import { {{sharedPresenter}} } from '$shared/Presenter';
8
+ import { ApplicationProvider } from '\${{context}}/Application';
8
9
 
9
- export const {{name}}Presenter = {{corePresenter}}('{{name}}Presenter', ({ createAsyncResource, createAsyncAction }) => {
10
- \t{{serviceInit}}
10
+ export const {{name}}Presenter = {{sharedPresenter}}('{{name}}Presenter', ({ createAsyncResource, createAsyncAction }) => {
11
+ \tconst { /* extract services from ApplicationProvider */ } = ApplicationProvider();
11
12
  \t
12
13
  \tconst example = async () => {
13
- \t\t// Using async helpers from core presenter factory
14
+ \t\t// Using async helpers from shared presenter factory
14
15
  \t\treturn await createAsyncResource(Promise.resolve({}));
15
16
  \t};
16
17
  \t
@@ -18,10 +19,10 @@ export const {{name}}Presenter = {{corePresenter}}('{{name}}Presenter', ({ creat
18
19
  });`;
19
20
 
20
21
  const presenterWithPackageTemplate = `import { createPresenter } from '@azure-net/kit';
21
- {{serviceImport}}
22
+ import { ApplicationProvider } from '\${{context}}/Application';
22
23
 
23
24
  export const {{name}}Presenter = createPresenter('{{name}}Presenter', () => {
24
- \t{{serviceInit}}
25
+ \tconst { /* extract services from ApplicationProvider */ } = ApplicationProvider();
25
26
  \t
26
27
  \tconst example = async () => {
27
28
  \t\t// Direct method without async helpers
@@ -34,25 +35,20 @@ export const {{name}}Presenter = createPresenter('{{name}}Presenter', () => {
34
35
  export default async function generatePresenter() {
35
36
  const context = await selectContext('Select context for presenter:');
36
37
 
37
- if (context === 'core') {
38
- console.error('❌ Cannot create presenter in core. Choose a specific context.');
39
- return;
40
- }
41
-
42
38
  const { name } = await prompts({
43
39
  type: 'text',
44
40
  name: 'name',
45
41
  message: 'Module name (will create folder in Delivery):'
46
42
  });
47
43
 
48
- // Check for core presenters
49
- const corePresenters = await getAvailableFiles(
50
- path.join(process.cwd(), 'src/app/core/Presenter')
44
+ // Check for shared presenters
45
+ const sharedPresenters = await getAvailableFiles(
46
+ path.join(process.cwd(), 'src/app/shared/Presenter')
51
47
  );
52
48
 
53
49
  const presenterChoices = [
54
50
  { title: 'Use createPresenter from package', value: 'package' },
55
- ...corePresenters.map(p => ({ title: `Use ${p} from core`, value: p }))
51
+ ...sharedPresenters.map(p => ({ title: `Use ${p} from shared`, value: p }))
56
52
  ];
57
53
 
58
54
  const { presenterType } = await prompts({
@@ -62,46 +58,19 @@ export default async function generatePresenter() {
62
58
  choices: presenterChoices
63
59
  });
64
60
 
65
- // Get available services
66
- const contextPath = getContextPath(context);
67
- const services = await getAvailableFiles(
68
- path.join(contextPath, 'Application/Services')
69
- );
70
-
71
- const serviceChoices = [
72
- { title: 'Without service', value: null },
73
- ...services.map(s => ({ title: s, value: s }))
74
- ];
75
-
76
- const { service } = await prompts({
77
- type: 'select',
78
- name: 'service',
79
- message: 'Select service (optional):',
80
- choices: serviceChoices
81
- });
82
-
83
61
  const pascalName = toPascalCase(name);
62
+ const contextPath = getContextPath(context);
84
63
  const modulePath = path.join(contextPath, 'Delivery', pascalName);
85
64
  const filePath = path.join(modulePath, `${pascalName}Presenter.ts`);
86
65
 
87
- const serviceImport = service
88
- ? `import { ApplicationProvider } from '\$${context}/Application';`
89
- : '';
90
-
91
- const serviceInit = service
92
- ? `const { ${service} } = ApplicationProvider();`
93
- : '';
94
-
95
66
  const content = presenterType === 'package'
96
67
  ? presenterWithPackageTemplate
97
68
  .replace(/{{name}}/g, pascalName)
98
- .replace(/{{serviceImport}}/g, serviceImport)
99
- .replace(/{{serviceInit}}/g, serviceInit)
100
- : presenterWithCoreTemplate
69
+ .replace(/{{context}}/g, context)
70
+ : presenterWithSharedTemplate
101
71
  .replace(/{{name}}/g, pascalName)
102
- .replace(/{{corePresenter}}/g, presenterType)
103
- .replace(/{{serviceImport}}/g, serviceImport)
104
- .replace(/{{serviceInit}}/g, serviceInit);
72
+ .replace(/{{sharedPresenter}}/g, presenterType)
73
+ .replace(/{{context}}/g, context);
105
74
 
106
75
  await writeIfNotExists(filePath, content);
107
76
  await writeIfNotExists(
@@ -110,4 +79,5 @@ export default async function generatePresenter() {
110
79
  );
111
80
 
112
81
  console.log(`✅ Presenter created at ${filePath}`);
82
+ console.log(`\n💡 Remember to extract needed services from ApplicationProvider in the presenter.`);
113
83
  }
@@ -0,0 +1,102 @@
1
+ import prompts from 'prompts';
2
+ import path from 'path';
3
+ import { selectContext, getContextPath, toPascalCase, getApplicationProviderServices, getAvailableFiles } from '../../utils/contextUtils.js';
4
+ import { writeIfNotExists } from '../../utils/fileUtils.js';
5
+
6
+ const presenterWithSharedTemplate = `import { {{presenterFactory}} } from '$shared/Presenter';
7
+ import { ApplicationProvider } from '\${{context}}/Application';
8
+
9
+ export const {{name}}Presenter = {{presenterFactory}}('{{name}}Presenter', ({ createAsyncResource, createAsyncAction }) => {
10
+ \tconst { {{serviceName}} } = ApplicationProvider();
11
+ \t
12
+ {{methods}}
13
+ \t
14
+ \treturn { {{exports}} };
15
+ });`;
16
+
17
+ const presenterWithPackageTemplate = `import { createPresenter } from '@azure-net/kit';
18
+ import { ApplicationProvider } from '\${{context}}/Application';
19
+
20
+ export const {{name}}Presenter = createPresenter('{{name}}Presenter', () => {
21
+ \tconst { {{serviceName}} } = ApplicationProvider();
22
+ \t
23
+ {{methods}}
24
+ \t
25
+ \treturn { {{exports}} };
26
+ });`;
27
+
28
+ export default async function generatePresenterByService() {
29
+ const context = await selectContext('Select context:');
30
+
31
+ // Get available services from ApplicationProvider
32
+ const services = await getApplicationProviderServices(context);
33
+
34
+ if (services.length === 0) {
35
+ console.error('❌ No services found in ApplicationProvider. Add services manually first.');
36
+ return;
37
+ }
38
+
39
+ const { service } = await prompts({
40
+ type: 'select',
41
+ name: 'service',
42
+ message: 'Select service to create presenter from:',
43
+ choices: services.map(s => ({ title: s, value: s }))
44
+ });
45
+
46
+ // Get presenter factory
47
+ const sharedPresenters = await getAvailableFiles(
48
+ path.join(process.cwd(), 'src/app/shared/Presenter')
49
+ );
50
+
51
+ const { presenterType } = await prompts({
52
+ type: 'select',
53
+ name: 'presenterType',
54
+ message: 'Select presenter factory:',
55
+ choices: [
56
+ { title: 'Use createPresenter from package', value: 'package' },
57
+ ...sharedPresenters.map(p => ({ title: `Use ${p} from shared`, value: p }))
58
+ ]
59
+ });
60
+
61
+ const entityName = service.replace('Service', '');
62
+ const pascalName = toPascalCase(entityName);
63
+ const contextPath = getContextPath(context);
64
+ const deliveryModulePath = path.join(contextPath, 'Delivery', pascalName);
65
+
66
+ // Generate method declarations based on common service patterns
67
+ const commonMethods = ['collection', 'resource', 'create', 'update', 'remove'];
68
+
69
+ const methods = presenterType === 'package'
70
+ ? commonMethods.map(m => `\tconst ${m} = async (...args: Parameters<typeof ${service}['${m}']>) =>
71
+ \t\tawait ${service}.${m}(...args);`).join('\n\n')
72
+ : commonMethods.map(m => `\tconst ${m} = async (...args: Parameters<typeof ${service}['${m}']>) =>
73
+ \t\tawait createAsyncResource(${service}.${m}(...args));`).join('\n\n');
74
+
75
+ const exports = commonMethods.join(', ');
76
+
77
+ const template = presenterType === 'package'
78
+ ? presenterWithPackageTemplate
79
+ : presenterWithSharedTemplate;
80
+
81
+ const presenterFactory = presenterType === 'package' ? 'createPresenter' : presenterType;
82
+
83
+ await writeIfNotExists(
84
+ path.join(deliveryModulePath, `${pascalName}Presenter.ts`),
85
+ template
86
+ .replace(/{{name}}/g, pascalName)
87
+ .replace(/{{context}}/g, context)
88
+ .replace(/{{serviceName}}/g, service)
89
+ .replace(/{{presenterFactory}}/g, presenterFactory)
90
+ .replace(/{{methods}}/g, methods)
91
+ .replace(/{{exports}}/g, exports)
92
+ );
93
+
94
+ // Create module index
95
+ await writeIfNotExists(
96
+ path.join(deliveryModulePath, 'index.ts'),
97
+ `export * from './${pascalName}Presenter';`
98
+ );
99
+
100
+ console.log(`✅ Presenter for ${service} created successfully!`);
101
+ console.log(`\n💡 Note: Methods are based on common patterns. Adjust them to match your actual service methods.`);
102
+ }
@@ -1,9 +1,7 @@
1
1
  import prompts from 'prompts';
2
- import fs from 'fs/promises';
3
2
  import path from 'path';
4
3
  import { selectContext, getContextPath, toPascalCase, getAvailableFiles, toCamelCase } from '../../utils/contextUtils.js';
5
4
  import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
6
- import { ensureProvider, addToProvider, ensureDatasourceProvider } from '../../utils/providerUtils.js';
7
5
 
8
6
  const repositoryTemplate = `import { {{datasource}} } from '{{datasourceImport}}';
9
7
 
@@ -20,11 +18,6 @@ export class {{name}}Repository {
20
18
  export default async function generateRepository() {
21
19
  const context = await selectContext('Select context for repository:');
22
20
 
23
- if (context === 'core') {
24
- console.error('❌ Cannot create repository in core. Choose a specific context.');
25
- return;
26
- }
27
-
28
21
  const { name } = await prompts({
29
22
  type: 'text',
30
23
  name: 'name',
@@ -33,15 +26,15 @@ export default async function generateRepository() {
33
26
 
34
27
  // Get available datasources
35
28
  const contextPath = getContextPath(context);
36
- const coreDatasources = await getAvailableFiles(
37
- path.join(process.cwd(), 'src/app/core/Datasource')
29
+ const sharedDatasources = await getAvailableFiles(
30
+ path.join(process.cwd(), 'src/app/shared/Datasource')
38
31
  );
39
32
  const contextDatasources = await getAvailableFiles(
40
33
  path.join(contextPath, 'Infrastructure/Http/Datasource')
41
34
  );
42
35
 
43
36
  const allDatasources = [
44
- ...coreDatasources.map(d => ({ title: `${d} (core)`, value: { name: d, from: 'core' } })),
37
+ ...sharedDatasources.map(d => ({ title: `${d} (shared)`, value: { name: d, from: 'shared' } })),
45
38
  ...contextDatasources.map(d => ({ title: `${d} (${context})`, value: { name: d, from: context } }))
46
39
  ];
47
40
 
@@ -58,14 +51,13 @@ export default async function generateRepository() {
58
51
  });
59
52
 
60
53
  const pascalName = toPascalCase(name);
61
- const contextName = toPascalCase(context);
62
54
  const repoPath = path.join(contextPath, 'Infrastructure/Http/Repositories');
63
55
  const filePath = path.join(repoPath, `${pascalName}Repository.ts`);
64
56
 
65
57
  // Generate repository
66
- const datasourceImport = datasource.from === 'core'
67
- ? '$core/Datasource'
68
- : '../Datasource';
58
+ const datasourceImport = datasource.from === 'shared'
59
+ ? '$shared/Datasource'
60
+ : `\$${context}/Infrastructure/Http/Datasource`;
69
61
 
70
62
  const content = repositoryTemplate
71
63
  .replace(/{{name}}/g, pascalName)
@@ -76,17 +68,6 @@ export default async function generateRepository() {
76
68
  await writeIfNotExists(filePath, content);
77
69
  await updateIndexTs(repoPath);
78
70
 
79
- // Ensure DatasourceProvider exists
80
- await ensureDatasourceProvider(context, datasource.name, datasource.from === 'core');
81
-
82
- // Ensure InfrastructureProvider and add repository
83
- const infraProvider = await ensureProvider(context, 'Infrastructure', { hasDatasource: true });
84
- await addToProvider(
85
- infraProvider.path,
86
- `${pascalName}Repository`,
87
- `\$${context}/Infrastructure/Http/Repositories`,
88
- `DatasourceProvider.${datasource.name}`
89
- );
90
-
91
71
  console.log(`✅ Repository created at ${filePath}`);
72
+ console.log(`\n💡 Remember to manually add this repository to InfrastructureProvider when needed.`);
92
73
  }
@@ -18,7 +18,7 @@ export class {{name}}Response<TData = unknown, TMeta = unknown> extends Response
18
18
  }`;
19
19
 
20
20
  export default async function generateResponse() {
21
- const context = await selectContext();
21
+ const context = await selectContext('Select context for response (or shared):');
22
22
 
23
23
  const { name } = await prompts({
24
24
  type: 'text',
@@ -27,8 +27,11 @@ export default async function generateResponse() {
27
27
  });
28
28
 
29
29
  const pascalName = toPascalCase(name);
30
- const contextPath = getContextPath(context);
31
- const responsePath = context === 'core'
30
+ const contextPath = context === 'shared'
31
+ ? path.join(process.cwd(), 'src/app/shared')
32
+ : getContextPath(context);
33
+
34
+ const responsePath = context === 'shared'
32
35
  ? path.join(contextPath, 'Response')
33
36
  : path.join(contextPath, 'Infrastructure/Response');
34
37
 
@@ -1,12 +1,10 @@
1
1
  import prompts from 'prompts';
2
- import fs from 'fs/promises';
3
2
  import path from 'path';
4
3
  import { selectContext, getContextPath, toPascalCase, getAvailableFiles } from '../../utils/contextUtils.js';
5
4
  import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
6
- import { ensureProvider, addToProvider } from '../../utils/providerUtils.js';
7
5
 
8
6
  const serviceTemplate = `import { ClassMirror } from '@azure-net/kit';
9
- import { {{repository}} } from '../../Infrastructure/Http/Repositories';
7
+ import { {{repository}} } from '\${{context}}/Infrastructure/Http/Repositories';
10
8
 
11
9
  export class {{name}}Service extends ClassMirror<{{repository}}> {
12
10
  \tconstructor(private {{repositoryVar}}: {{repository}}) {
@@ -28,11 +26,6 @@ const serviceWithoutRepoTemplate = `export class {{name}}Service {
28
26
  export default async function generateService() {
29
27
  const context = await selectContext('Select context for service:');
30
28
 
31
- if (context === 'core') {
32
- console.error('❌ Cannot create service in core. Choose a specific context.');
33
- return;
34
- }
35
-
36
29
  const { name } = await prompts({
37
30
  type: 'text',
38
31
  name: 'name',
@@ -67,28 +60,12 @@ export default async function generateService() {
67
60
  .replace(/{{name}}/g, pascalName)
68
61
  .replace(/{{repository}}/g, repository)
69
62
  .replace(/{{repositoryVar}}/g, repository.charAt(0).toLowerCase() + repository.slice(1))
63
+ .replace(/{{context}}/g, context)
70
64
  : serviceWithoutRepoTemplate.replace(/{{name}}/g, pascalName);
71
65
 
72
66
  await writeIfNotExists(filePath, content);
73
67
  await updateIndexTs(servicePath);
74
68
 
75
- // Ensure ApplicationProvider exists and add service
76
- const appProvider = await ensureProvider(context, 'Application', { infrastructure: true });
77
-
78
- if (repository) {
79
- await addToProvider(
80
- appProvider.path,
81
- `${pascalName}Service`,
82
- '../Services',
83
- `InfrastructureProvider.${repository}`
84
- );
85
- } else {
86
- await addToProvider(
87
- appProvider.path,
88
- `${pascalName}Service`,
89
- '../Services'
90
- );
91
- }
92
-
93
69
  console.log(`✅ Service created at ${filePath}`);
70
+ console.log(`\n💡 Remember to manually add this service to ApplicationProvider when needed.`);
94
71
  }
@@ -0,0 +1,86 @@
1
+ import prompts from 'prompts';
2
+ import path from 'path';
3
+ import fs from 'fs/promises';
4
+ import { selectContext, getContextPath, toPascalCase, getAvailableFiles } from '../../utils/contextUtils.js';
5
+ import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
6
+
7
+ const serviceTemplate = `import { ClassMirror } from '@azure-net/kit';
8
+ import { {{repository}} } from '\${{context}}/Infrastructure/Http/Repositories';
9
+
10
+ export class {{name}}Service extends ClassMirror<{{repository}}> {
11
+ \tconstructor(private {{repositoryVar}}: {{repository}}) {
12
+ \t\tsuper({{repositoryVar}});
13
+ \t}
14
+ \t
15
+ {{methodDeclarations}}
16
+ }`;
17
+
18
+ export default async function generateServiceByRepo() {
19
+ const context = await selectContext('Select context:');
20
+
21
+ const contextPath = getContextPath(context);
22
+ const repositories = await getAvailableFiles(
23
+ path.join(contextPath, 'Infrastructure/Http/Repositories')
24
+ );
25
+
26
+ if (repositories.length === 0) {
27
+ console.error('❌ No repositories available. Create a repository first.');
28
+ return;
29
+ }
30
+
31
+ const { repository } = await prompts({
32
+ type: 'select',
33
+ name: 'repository',
34
+ message: 'Select repository to create service from:',
35
+ choices: repositories.map(r => ({ title: r, value: r }))
36
+ });
37
+
38
+ const serviceName = repository.replace('Repository', 'Service');
39
+ const servicePath = path.join(contextPath, 'Application/Services');
40
+ const filePath = path.join(servicePath, `${serviceName}.ts`);
41
+
42
+ // Try to get repository file to extract methods
43
+ const repoFilePath = path.join(contextPath, 'Infrastructure/Http/Repositories', `${repository}.ts`);
44
+ let methodDeclarations = '';
45
+
46
+ try {
47
+ const repoContent = await fs.readFile(repoFilePath, 'utf-8');
48
+ // Extract public methods from repository
49
+ const methodRegex = /public async (\w+)\([^)]*\)(?:\s*:\s*[^{]+)?/g;
50
+ const methods = [];
51
+ let match;
52
+
53
+ while ((match = methodRegex.exec(repoContent)) !== null) {
54
+ methods.push(match[1]);
55
+ }
56
+
57
+ if (methods.length > 0) {
58
+ methodDeclarations = methods
59
+ .map(m => `\tdeclare ${m}: ${repository}['${m}'];`)
60
+ .join('\n');
61
+ } else {
62
+ // Fallback to common CRUD methods
63
+ methodDeclarations = [
64
+ 'collection', 'resource', 'create', 'update', 'remove'
65
+ ].map(m => `\tdeclare ${m}: ${repository}['${m}'];`).join('\n');
66
+ }
67
+ } catch (error) {
68
+ // Fallback if can't read repository file
69
+ methodDeclarations = [
70
+ 'collection', 'resource', 'create', 'update', 'remove'
71
+ ].map(m => `\tdeclare ${m}: ${repository}['${m}'];`).join('\n');
72
+ }
73
+
74
+ const content = serviceTemplate
75
+ .replace(/{{name}}/g, serviceName.replace('Service', ''))
76
+ .replace(/{{repository}}/g, repository)
77
+ .replace(/{{repositoryVar}}/g, repository.charAt(0).toLowerCase() + repository.slice(1))
78
+ .replace(/{{context}}/g, context)
79
+ .replace(/{{methodDeclarations}}/g, methodDeclarations);
80
+
81
+ await writeIfNotExists(filePath, content);
82
+ await updateIndexTs(servicePath);
83
+
84
+ console.log(`✅ Service created at ${filePath}`);
85
+ console.log(`\n💡 Remember to manually add this service to ApplicationProvider when needed.`);
86
+ }
@@ -5,4 +5,7 @@ export { default as generateService } from './generateService.js';
5
5
  export { default as generateSchema } from './generateSchema.js';
6
6
  export { default as generatePresenter } from './generatePresenter.js';
7
7
  export { default as generateModule } from './generateModule.js';
8
- export { default as generateCrud } from './generateCrud.js';
8
+ export { default as generateCrudBase } from './generateCrudBase.js';
9
+ export { default as generateCrudPresenter } from './generateCrudPresenter.js';
10
+ export { default as generatePresenterByService } from './generatePresenterByService.js';
11
+ export { default as generateServiceByRepo } from './generateServiceByRepo.js';
@@ -10,7 +10,7 @@ function generateAliases(config) {
10
10
 
11
11
  return Object.fromEntries([
12
12
  ...contexts.map(c => [`$${c}`, `./src/app/contexts/${c}`]),
13
- ['$core', './src/app/core'],
13
+ ['$shared', './src/app/shared'],
14
14
  ['$lib', './src/lib']
15
15
  ]);
16
16
  }
@@ -1,7 +1,7 @@
1
1
  import { writeIfNotExists, injectIntoFile } from '../../utils/fileUtils.js';
2
2
  import path from 'path';
3
3
 
4
- const middlewarePath = path.join(process.cwd(), 'src/app/core/Middleware/MiddlewareManager.ts');
4
+ const middlewarePath = path.join(process.cwd(), 'src/app/shared/Middleware/MiddlewareManager.ts');
5
5
  const hooksServerPath = path.join(process.cwd(), 'src/hooks.server.ts');
6
6
  const layoutPath = path.join(process.cwd(), 'src/routes/+layout.svelte');
7
7
 
@@ -12,7 +12,7 @@ export const { clientMiddleware, serverMiddleware } = createMiddlewareManager([]
12
12
  export default async function initMiddleware() {
13
13
  await writeIfNotExists(middlewarePath, middlewareTemplate);
14
14
  await writeIfNotExists(
15
- path.join(process.cwd(), 'src/app/core/Middleware/index.ts'),
15
+ path.join(process.cwd(), 'src/app/shared/Middleware/index.ts'),
16
16
  `export * from './MiddlewareManager';`
17
17
  );
18
18
 
@@ -20,7 +20,7 @@ export default async function initMiddleware() {
20
20
  await injectIntoFile(
21
21
  hooksServerPath,
22
22
  'import',
23
- `import { serverMiddleware } from '$core';`,
23
+ `import { serverMiddleware } from '$shared';`,
24
24
  'before'
25
25
  );
26
26
 
@@ -35,7 +35,7 @@ export default async function initMiddleware() {
35
35
  await injectIntoFile(
36
36
  layoutPath,
37
37
  '<script',
38
- `\timport { clientMiddleware } from '$core';\n\tclientMiddleware();`,
38
+ `\timport { clientMiddleware } from '$shared';\n\tclientMiddleware();`,
39
39
  'after'
40
40
  );
41
41
 
@@ -1,7 +1,7 @@
1
1
  import { writeIfNotExists } from '../../utils/fileUtils.js';
2
2
  import path from 'path';
3
3
 
4
- const schemaPath = path.join(process.cwd(), 'src/app/core/Schema/Schema.ts');
4
+ const schemaPath = path.join(process.cwd(), 'src/app/shared/Schema/Schema.ts');
5
5
 
6
6
  const schemaTemplate = `import { createSchemaFactory } from '@azure-net/kit';
7
7
  import { createRules, validationMessagesI18n } from '@azure-net/kit/schema';
@@ -11,7 +11,7 @@ export const Schema = createSchemaFactory(createRules(validationMessagesI18n));`
11
11
  export default async function initSchema() {
12
12
  await writeIfNotExists(schemaPath, schemaTemplate);
13
13
  await writeIfNotExists(
14
- path.join(process.cwd(), 'src/app/core/Schema/index.ts'),
14
+ path.join(process.cwd(), 'src/app/shared/Schema/index.ts'),
15
15
  `export * from './Schema';`
16
16
  );
17
17
 
@@ -4,7 +4,7 @@ import { loadUserConfig } from '../../utils/loadConfig.js';
4
4
 
5
5
  const APP_ROOT = path.join(process.cwd(), 'src', 'app');
6
6
  const CONTEXTS_PATH = path.join(APP_ROOT, 'contexts');
7
- const CORE_PATH = path.join(APP_ROOT, 'core');
7
+ const SHARED_PATH = path.join(APP_ROOT, 'shared');
8
8
 
9
9
  async function createDirIfNotExists(dirPath) {
10
10
  try {
@@ -23,7 +23,7 @@ async function createIndexFile(dirPath, exportPatterns = []) {
23
23
  }
24
24
  }
25
25
 
26
- async function createBaseStructure(root) {
26
+ async function createBaseStructure(root, contextName) {
27
27
  // Domain
28
28
  const domainPath = path.join(root, 'Domain');
29
29
  await createDirIfNotExists(path.join(domainPath, 'Entities'));
@@ -35,12 +35,72 @@ async function createBaseStructure(root) {
35
35
  await createDirIfNotExists(path.join(infraPath, 'Http', 'Datasource'));
36
36
  await createDirIfNotExists(path.join(infraPath, 'Providers'));
37
37
 
38
+ // Create empty InfrastructureProvider
39
+ const infraProviderContent = `import { createBoundaryProvider } from '@azure-net/kit';
40
+
41
+ export const InfrastructureProvider = createBoundaryProvider(
42
+ \t'${contextName}InfrastructureProvider',
43
+ \t() => ({
44
+ \t\t// Infrastructure services will be added here manually
45
+ \t})
46
+ );`;
47
+
48
+ await fs.writeFile(
49
+ path.join(infraPath, 'Providers', 'InfrastructureProvider.ts'),
50
+ infraProviderContent,
51
+ 'utf-8'
52
+ );
53
+
54
+ await fs.writeFile(
55
+ path.join(infraPath, 'Providers', 'index.ts'),
56
+ `export * from './InfrastructureProvider';`,
57
+ 'utf-8'
58
+ );
59
+
60
+ // Create Infrastructure index
61
+ await fs.writeFile(
62
+ path.join(infraPath, 'index.ts'),
63
+ `export * from './Providers';`,
64
+ 'utf-8'
65
+ );
66
+
38
67
  // Application
39
68
  const appPath = path.join(root, 'Application');
40
69
  await createDirIfNotExists(path.join(appPath, 'Services'));
41
70
  await createDirIfNotExists(path.join(appPath, 'Providers'));
42
71
 
43
- // Delivery - organized by modules, not by type
72
+ // Create empty ApplicationProvider
73
+ const appProviderContent = `import { createBoundaryProvider } from '@azure-net/kit';
74
+ import { InfrastructureProvider } from '../Infrastructure';
75
+
76
+ export const ApplicationProvider = createBoundaryProvider(
77
+ \t'${contextName}ApplicationProvider',
78
+ \t({ InfrastructureProvider }) => ({
79
+ \t\t// Application services will be added here manually
80
+ \t}),
81
+ \t{ dependsOn: { InfrastructureProvider } }
82
+ );`;
83
+
84
+ await fs.writeFile(
85
+ path.join(appPath, 'Providers', 'ApplicationProvider.ts'),
86
+ appProviderContent,
87
+ 'utf-8'
88
+ );
89
+
90
+ await fs.writeFile(
91
+ path.join(appPath, 'Providers', 'index.ts'),
92
+ `export * from './ApplicationProvider';`,
93
+ 'utf-8'
94
+ );
95
+
96
+ // Create Application index
97
+ await fs.writeFile(
98
+ path.join(appPath, 'index.ts'),
99
+ `export * from './Providers';`,
100
+ 'utf-8'
101
+ );
102
+
103
+ // Delivery - organized by modules
44
104
  const deliveryPath = path.join(root, 'Delivery');
45
105
  await createDirIfNotExists(deliveryPath);
46
106
  }
@@ -54,20 +114,21 @@ export default async function initStructure() {
54
114
  // Create contexts
55
115
  for (const context of contexts) {
56
116
  const contextPath = path.join(CONTEXTS_PATH, context);
57
- await createBaseStructure(contextPath);
117
+ const contextName = context.charAt(0).toUpperCase() + context.slice(1);
118
+ await createBaseStructure(contextPath, contextName);
58
119
  }
59
120
 
60
- // Create core structure
61
- await createDirIfNotExists(CORE_PATH);
62
- await createDirIfNotExists(path.join(CORE_PATH, 'Datasource'));
63
- await createDirIfNotExists(path.join(CORE_PATH, 'Response'));
64
- await createDirIfNotExists(path.join(CORE_PATH, 'Schema'));
65
- await createDirIfNotExists(path.join(CORE_PATH, 'Middleware'));
66
- await createDirIfNotExists(path.join(CORE_PATH, 'Presenter'));
67
- await createDirIfNotExists(path.join(CORE_PATH, 'Translation'));
68
-
69
- // Create core index.ts that exports all subdirectories
70
- await createIndexFile(CORE_PATH, [
121
+ // Create shared structure (former core)
122
+ await createDirIfNotExists(SHARED_PATH);
123
+ await createDirIfNotExists(path.join(SHARED_PATH, 'Datasource'));
124
+ await createDirIfNotExists(path.join(SHARED_PATH, 'Response'));
125
+ await createDirIfNotExists(path.join(SHARED_PATH, 'Schema'));
126
+ await createDirIfNotExists(path.join(SHARED_PATH, 'Middleware'));
127
+ await createDirIfNotExists(path.join(SHARED_PATH, 'Presenter'));
128
+ await createDirIfNotExists(path.join(SHARED_PATH, 'Translation'));
129
+
130
+ // Create shared index.ts that exports all subdirectories
131
+ await createIndexFile(SHARED_PATH, [
71
132
  './Schema',
72
133
  './Datasource',
73
134
  './Response',