@azure-net/cli 5.1.0 → 6.0.0-next.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.
Files changed (176) hide show
  1. package/README.md +189 -0
  2. package/bin/azure-net.js +236 -221
  3. package/dist/bin/azure-net.d.ts +2 -0
  4. package/dist/src/checks/architecture.d.ts +20 -0
  5. package/dist/src/checks/checkDomain.d.ts +1 -0
  6. package/dist/src/checks/checkFoldersStructure.d.ts +1 -0
  7. package/dist/src/checks/checkHooks.d.ts +1 -0
  8. package/dist/src/checks/checkImports.d.ts +1 -0
  9. package/dist/src/checks/checkInternal.d.ts +1 -0
  10. package/dist/src/checks/checkLayerBoundaries.d.ts +1 -0
  11. package/dist/src/checks/checkLayerImports.d.ts +1 -0
  12. package/dist/src/checks/checkPresenterNames.d.ts +1 -0
  13. package/dist/src/checks/checkProject.d.ts +1 -0
  14. package/dist/src/checks/checkProviderGraph.d.ts +1 -0
  15. package/dist/src/checks/checkProviderNames.d.ts +1 -0
  16. package/dist/src/generate/layers/generateRepository.d.ts +1 -0
  17. package/dist/src/generate/layers/generateRepositoryMethod.d.ts +1 -0
  18. package/dist/src/generate/layers/generateUseCases.d.ts +1 -0
  19. package/dist/src/generate/module/generateDomain.d.ts +8 -0
  20. package/dist/src/generate/module/generateModule.d.ts +1 -0
  21. package/dist/src/generate/module/generateModulePreset.d.ts +1 -0
  22. package/dist/src/generate/module/generatePresenter.d.ts +29 -0
  23. package/dist/src/generate/module/generateRepository.d.ts +15 -0
  24. package/dist/src/generate/module/generateRepositoryMethod.d.ts +2 -0
  25. package/dist/src/generate/module/generateSchemaFromType.d.ts +9 -0
  26. package/dist/src/generate/module/generateStore.d.ts +1 -0
  27. package/dist/src/generate/module/generateTypesJson.d.ts +2 -0
  28. package/dist/src/generate/module/generateUseCases.d.ts +1 -0
  29. package/dist/src/generate/module/repositoryModuleShared.d.ts +89 -0
  30. package/dist/src/generate/routes/generateRoutes.d.ts +14 -0
  31. package/dist/src/generate/ui/generateComponent.d.ts +1 -0
  32. package/dist/src/generate/ui/generateDesignComponent.d.ts +1 -0
  33. package/dist/src/generate/ui/generateWidget.d.ts +1 -0
  34. package/dist/src/git/commit.d.ts +23 -0
  35. package/dist/src/git/push.d.ts +11 -0
  36. package/dist/src/git/runGit.d.ts +2 -0
  37. package/dist/src/init/initAliases.d.ts +12 -0
  38. package/dist/src/init/initEdges.d.ts +2 -0
  39. package/dist/src/init/initStructure.d.ts +1 -0
  40. package/dist/src/install/configureCommitTools.d.ts +1 -0
  41. package/dist/src/install/installFresh.d.ts +1 -0
  42. package/dist/src/migrate/migrate.d.ts +22 -0
  43. package/dist/src/migrate/presenters.d.ts +7 -0
  44. package/dist/src/plugins/addLint.d.ts +5 -0
  45. package/dist/src/scaffolds/createCoreSchema.d.ts +1 -0
  46. package/dist/src/scaffolds/createDatasource.d.ts +1 -0
  47. package/dist/src/scaffolds/createProgram.d.ts +1 -0
  48. package/dist/src/scaffolds/createResponse.d.ts +1 -0
  49. package/dist/src/scaffolds/createSchemaRule.d.ts +1 -0
  50. package/dist/src/scaffolds/createTranslationManager.d.ts +1 -0
  51. package/{src/scaffolds/index.ts → dist/src/scaffolds/index.d.ts} +0 -2
  52. package/dist/src/scaffolds/registerDatasource.d.ts +2 -0
  53. package/dist/src/scaffolds/updateDefaultFactoryConfig.d.ts +1 -0
  54. package/dist/src/utils/architecture.d.ts +31 -0
  55. package/dist/src/utils/contextUtils.d.ts +6 -0
  56. package/dist/src/utils/fileUtils.d.ts +5 -0
  57. package/dist/src/utils/flattenConfig.d.ts +2 -0
  58. package/dist/src/utils/legacyAliases.d.ts +1 -0
  59. package/dist/src/utils/loadConfig.d.ts +16 -0
  60. package/dist/src/utils/packageImports.d.ts +4 -0
  61. package/dist/src/utils/sharedFoundation.d.ts +20 -0
  62. package/dist/src/utils/viteConfig.d.ts +9 -0
  63. package/package.json +48 -36
  64. package/src/checks/architecture.js +154 -0
  65. package/src/checks/checkDomain.js +124 -154
  66. package/src/checks/checkFoldersStructure.js +64 -52
  67. package/src/checks/checkHooks.js +12 -12
  68. package/src/checks/checkImports.js +26 -142
  69. package/src/checks/checkInternal.js +27 -24
  70. package/src/checks/checkLayerBoundaries.js +22 -197
  71. package/src/checks/checkLayerImports.js +14 -134
  72. package/src/checks/checkPresenterNames.js +156 -143
  73. package/src/checks/checkProject.js +27 -26
  74. package/src/checks/checkProviderGraph.js +182 -166
  75. package/src/checks/checkProviderNames.js +123 -112
  76. package/src/generate/layers/generateRepository.js +1 -109
  77. package/src/generate/layers/generateRepositoryMethod.js +1 -90
  78. package/src/generate/layers/generateUseCases.js +1 -44
  79. package/src/generate/module/generateDomain.js +81 -105
  80. package/src/generate/module/generateModule.js +34 -68
  81. package/src/generate/module/generateModulePreset.js +188 -248
  82. package/src/generate/module/generatePresenter.js +441 -369
  83. package/src/generate/module/generateRepository.js +102 -121
  84. package/src/generate/module/generateRepositoryMethod.js +117 -0
  85. package/src/generate/module/generateSchemaFromType.js +283 -280
  86. package/src/generate/module/generateStore.js +41 -0
  87. package/src/generate/module/generateTypesJson.js +196 -195
  88. package/src/generate/module/generateUseCases.js +47 -55
  89. package/src/generate/module/repositoryModuleShared.js +480 -459
  90. package/src/generate/routes/generateRoutes.js +165 -174
  91. package/src/generate/ui/generateComponent.js +44 -64
  92. package/src/generate/ui/generateDesignComponent.js +21 -41
  93. package/src/generate/ui/generateWidget.js +21 -41
  94. package/src/git/commit.js +67 -0
  95. package/src/git/push.js +19 -0
  96. package/src/git/runGit.js +11 -0
  97. package/src/init/initAliases.js +19 -135
  98. package/src/init/initEdges.js +79 -54
  99. package/src/init/initStructure.js +31 -145
  100. package/src/install/configureCommitTools.js +1 -0
  101. package/src/install/installFresh.js +39 -68
  102. package/src/migrate/migrate.js +914 -0
  103. package/src/migrate/presenters.js +265 -0
  104. package/src/plugins/addLint.js +52 -219
  105. package/src/scaffolds/createCoreSchema.js +65 -91
  106. package/src/scaffolds/createDatasource.js +67 -101
  107. package/src/scaffolds/createProgram.js +8 -8
  108. package/src/scaffolds/createResponse.js +29 -29
  109. package/src/scaffolds/createSchemaRule.js +19 -19
  110. package/src/scaffolds/createTranslationManager.js +84 -37
  111. package/src/scaffolds/index.js +0 -2
  112. package/src/scaffolds/registerDatasource.js +59 -0
  113. package/src/scaffolds/updateDefaultFactoryConfig.js +31 -0
  114. package/src/utils/architecture.js +145 -0
  115. package/src/utils/contextUtils.js +32 -65
  116. package/src/utils/fileUtils.js +69 -50
  117. package/src/utils/flattenConfig.js +38 -0
  118. package/src/utils/legacyAliases.js +75 -0
  119. package/src/utils/loadConfig.js +76 -40
  120. package/src/utils/packageImports.js +63 -0
  121. package/src/utils/sharedFoundation.js +36 -42
  122. package/src/utils/viteConfig.js +295 -0
  123. package/.prettierrc +0 -7
  124. package/bin/azure-net.ts +0 -308
  125. package/eslint.config.js +0 -34
  126. package/src/checks/checkDomain.ts +0 -223
  127. package/src/checks/checkFoldersStructure.ts +0 -85
  128. package/src/checks/checkHooks.ts +0 -22
  129. package/src/checks/checkImports.ts +0 -193
  130. package/src/checks/checkInternal.ts +0 -48
  131. package/src/checks/checkLayerBoundaries.ts +0 -255
  132. package/src/checks/checkLayerImports.ts +0 -185
  133. package/src/checks/checkPresenterNames.ts +0 -203
  134. package/src/checks/checkProject.ts +0 -45
  135. package/src/checks/checkProviderGraph.ts +0 -234
  136. package/src/checks/checkProviderNames.ts +0 -165
  137. package/src/generate/layers/generateRepository.ts +0 -123
  138. package/src/generate/layers/generateRepositoryMethod.ts +0 -102
  139. package/src/generate/layers/generateUseCases.ts +0 -50
  140. package/src/generate/layers/repositoryShared.js +0 -506
  141. package/src/generate/layers/repositoryShared.ts +0 -662
  142. package/src/generate/module/generateDomain.ts +0 -147
  143. package/src/generate/module/generateModule.ts +0 -84
  144. package/src/generate/module/generateModulePreset.ts +0 -338
  145. package/src/generate/module/generatePresenter.ts +0 -498
  146. package/src/generate/module/generateRepository.ts +0 -158
  147. package/src/generate/module/generateSchemaFromType.ts +0 -368
  148. package/src/generate/module/generateTypesJson.ts +0 -259
  149. package/src/generate/module/generateUseCases.ts +0 -67
  150. package/src/generate/module/repositoryModuleShared.ts +0 -669
  151. package/src/generate/routes/generateRoutes.ts +0 -282
  152. package/src/generate/ui/generateComponent.ts +0 -100
  153. package/src/generate/ui/generateDesignComponent.ts +0 -71
  154. package/src/generate/ui/generateWidget.ts +0 -71
  155. package/src/init/initAliases.ts +0 -172
  156. package/src/init/initEdges.ts +0 -74
  157. package/src/init/initStructure.ts +0 -172
  158. package/src/install/installFresh.ts +0 -93
  159. package/src/plugins/addLint.ts +0 -274
  160. package/src/scaffolds/createCoreSchema.ts +0 -130
  161. package/src/scaffolds/createDatasource.ts +0 -161
  162. package/src/scaffolds/createDatasourceProvider.js +0 -127
  163. package/src/scaffolds/createDatasourceProvider.ts +0 -161
  164. package/src/scaffolds/createPresenterFactory.js +0 -83
  165. package/src/scaffolds/createPresenterFactory.ts +0 -102
  166. package/src/scaffolds/createProgram.ts +0 -19
  167. package/src/scaffolds/createResponse.ts +0 -66
  168. package/src/scaffolds/createSchemaRule.ts +0 -44
  169. package/src/scaffolds/createTranslationManager.ts +0 -80
  170. package/src/utils/contextUtils.ts +0 -88
  171. package/src/utils/fileUtils.ts +0 -74
  172. package/src/utils/loadConfig.ts +0 -68
  173. package/src/utils/sharedFoundation.ts +0 -70
  174. package/tsconfig.json +0 -19
  175. /package/{src/checks/index.ts → dist/src/checks/index.d.ts} +0 -0
  176. /package/{src/plugins/index.ts → dist/src/plugins/index.d.ts} +0 -0
@@ -1,109 +1 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import prompts from 'prompts';
4
- import {
5
- buildRepositoryContent,
6
- ensureDomainType,
7
- ensureRepositoryInterfaceFile,
8
- ensureRepositoryName,
9
- ensureUseCasesFile,
10
- getConfigState,
11
- getRepositoryMeta,
12
- resolveContextAlias,
13
- resolveRepositoriesPath,
14
- selectContext,
15
- selectDatasource,
16
- promptMethodDefinition
17
- } from './repositoryShared.js';
18
- import { updateIndexTs, writeIfNotExists } from '../../utils/fileUtils.js';
19
- export default async function generateRepository() {
20
- const { rawName } = await prompts({
21
- type: 'text',
22
- name: 'rawName',
23
- message: 'Repository name:',
24
- validate: (value) => (String(value ?? '').trim().length > 0 ? true : 'Repository name is required')
25
- });
26
- const className = ensureRepositoryName(rawName);
27
- const meta = getRepositoryMeta(className);
28
- const contextName = await selectContext('Select context for repository:');
29
- if (!contextName) {
30
- process.exitCode = 1;
31
- return;
32
- }
33
- const datasource = await selectDatasource(contextName);
34
- if (!datasource) {
35
- process.exitCode = 1;
36
- return;
37
- }
38
- const { methodsCountRaw } = await prompts({
39
- type: 'number',
40
- name: 'methodsCountRaw',
41
- message: 'How many methods to create?',
42
- initial: 1,
43
- min: 0
44
- });
45
- const methodsCount = Number(methodsCountRaw ?? 0);
46
- if (!Number.isFinite(methodsCount) || methodsCount < 0) {
47
- console.error('❌ Invalid methods count.');
48
- process.exitCode = 1;
49
- return;
50
- }
51
- const methods = [];
52
- for (let index = 0; index < methodsCount; index += 1) {
53
- console.log(`\n🧩 Method ${index + 1} of ${methodsCount}`);
54
- const method = await promptMethodDefinition();
55
- methods.push(method);
56
- }
57
- const { contexts } = await getConfigState();
58
- const contextAlias = resolveContextAlias(contexts, contextName);
59
- const repositoriesPath = resolveRepositoriesPath(contextName);
60
- await fs.mkdir(repositoriesPath, { recursive: true });
61
- const repositoryPath = path.join(repositoriesPath, `${meta.className}.ts`);
62
- for (const method of methods) {
63
- if (!method) continue;
64
- const ensuredResponseType = await ensureDomainType({
65
- contextName,
66
- domainName: meta.domainName,
67
- typeName: method.responseType,
68
- layer: method.responseLayer
69
- });
70
- method.responseType = ensuredResponseType.interfaceName;
71
- method.responseLayer = ensuredResponseType.layer;
72
- if (method.requestType) {
73
- const ensuredRequestType = await ensureDomainType({
74
- contextName,
75
- domainName: meta.domainName,
76
- typeName: method.requestType,
77
- layer: method.requestLayer ?? 'ports'
78
- });
79
- method.requestType = ensuredRequestType.interfaceName;
80
- method.requestLayer = ensuredRequestType.layer;
81
- }
82
- }
83
- const filteredMethods = methods.filter(Boolean);
84
- await ensureRepositoryInterfaceFile({ contextName, meta, methods: filteredMethods });
85
- const repositoryContent = buildRepositoryContent({
86
- meta,
87
- contextAlias,
88
- datasourceImportPath: datasource.importPath,
89
- datasourceName: datasource.name,
90
- methods: filteredMethods
91
- });
92
- const created = await writeIfNotExists(repositoryPath, repositoryContent);
93
- await updateIndexTs(repositoriesPath);
94
- if (!created) {
95
- console.warn(`⚠️ Repository "${meta.className}" already exists. File was not overwritten.`);
96
- process.exitCode = 1;
97
- return;
98
- }
99
- const { shouldCreateUseCases } = await prompts({
100
- type: 'confirm',
101
- name: 'shouldCreateUseCases',
102
- message: 'Create UseCases for this repository?',
103
- initial: true
104
- });
105
- if (shouldCreateUseCases) {
106
- await ensureUseCasesFile({ contextName, contextAlias, meta });
107
- }
108
- console.log(`✅ Repository generated: ${repositoryPath}`);
109
- }
1
+ export { default } from '../module/generateRepository.js';
@@ -1,90 +1 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import prompts from 'prompts';
4
- import {
5
- appendRepositoryMethod,
6
- ensureDomainType,
7
- ensureRepositoryInterfaceFile,
8
- getAvailableTsNames,
9
- getConfigState,
10
- getRepositoryMeta,
11
- parseRepositoryMethods,
12
- resolveContextAlias,
13
- resolveRepositoriesPath,
14
- selectContext,
15
- promptMethodDefinition
16
- } from './repositoryShared.js';
17
- export default async function generateRepositoryMethod() {
18
- const contextName = await selectContext('Select context for repository method:');
19
- if (!contextName) {
20
- process.exitCode = 1;
21
- return;
22
- }
23
- const repositoriesPath = resolveRepositoriesPath(contextName);
24
- const repositories = await getAvailableTsNames(repositoriesPath);
25
- if (!repositories.length) {
26
- console.error(`❌ No repositories found in ${repositoriesPath}`);
27
- process.exitCode = 1;
28
- return;
29
- }
30
- const { repositoryName } = await prompts({
31
- type: 'select',
32
- name: 'repositoryName',
33
- message: 'Select repository:',
34
- choices: repositories.map((name) => ({ title: name, value: name })),
35
- initial: 0
36
- });
37
- if (!repositoryName) {
38
- process.exitCode = 1;
39
- return;
40
- }
41
- const meta = getRepositoryMeta(String(repositoryName));
42
- const repositoryPath = path.join(repositoriesPath, `${meta.className}.ts`);
43
- const method = await promptMethodDefinition();
44
- const ensuredResponseType = await ensureDomainType({
45
- contextName,
46
- domainName: meta.domainName,
47
- typeName: method.responseType,
48
- layer: method.responseLayer
49
- });
50
- method.responseType = ensuredResponseType.interfaceName;
51
- method.responseLayer = ensuredResponseType.layer;
52
- if (method.requestType) {
53
- const ensuredRequestType = await ensureDomainType({
54
- contextName,
55
- domainName: meta.domainName,
56
- typeName: method.requestType,
57
- layer: method.requestLayer ?? 'ports'
58
- });
59
- method.requestType = ensuredRequestType.interfaceName;
60
- method.requestLayer = ensuredRequestType.layer;
61
- }
62
- let repositoryContent = '';
63
- try {
64
- repositoryContent = await fs.readFile(repositoryPath, 'utf-8');
65
- } catch {
66
- console.error(`❌ Repository file not found: ${repositoryPath}`);
67
- process.exitCode = 1;
68
- return;
69
- }
70
- const existingMethods = parseRepositoryMethods(repositoryContent);
71
- if (existingMethods.some((item) => item.name === method.name)) {
72
- console.warn(`⚠️ Method "${method.name}" already exists in ${meta.className}.`);
73
- process.exitCode = 1;
74
- return;
75
- }
76
- const { contexts } = await getConfigState();
77
- const contextAlias = resolveContextAlias(contexts, contextName);
78
- await appendRepositoryMethod({
79
- repositoryPath,
80
- method,
81
- contextAlias,
82
- domainName: meta.domainName
83
- });
84
- await ensureRepositoryInterfaceFile({
85
- contextName,
86
- meta,
87
- methods: [...existingMethods, method]
88
- });
89
- console.log(`✅ Method "${method.name}" added to ${meta.className}`);
90
- }
1
+ export { default } from '../module/generateRepositoryMethod.js';
@@ -1,44 +1 @@
1
- import prompts from 'prompts';
2
- import {
3
- ensureUseCasesFile,
4
- getAvailableTsNames,
5
- getConfigState,
6
- getRepositoryMeta,
7
- resolveContextAlias,
8
- resolveRepositoriesPath,
9
- selectContext
10
- } from './repositoryShared.js';
11
- export default async function generateUseCases() {
12
- const contextName = await selectContext('Select context for UseCases:');
13
- if (!contextName) {
14
- process.exitCode = 1;
15
- return;
16
- }
17
- const repositoriesPath = resolveRepositoriesPath(contextName);
18
- const repositories = await getAvailableTsNames(repositoriesPath);
19
- if (!repositories.length) {
20
- console.error(`❌ No repositories found in ${repositoriesPath}`);
21
- process.exitCode = 1;
22
- return;
23
- }
24
- const { repositoryName } = await prompts({
25
- type: 'select',
26
- name: 'repositoryName',
27
- message: 'Select repository:',
28
- choices: repositories.map((name) => ({ title: name, value: name })),
29
- initial: 0
30
- });
31
- if (!repositoryName) {
32
- process.exitCode = 1;
33
- return;
34
- }
35
- const { contexts } = await getConfigState();
36
- const contextAlias = resolveContextAlias(contexts, contextName);
37
- const meta = getRepositoryMeta(String(repositoryName));
38
- const created = await ensureUseCasesFile({ contextName, contextAlias, meta });
39
- if (!created) {
40
- process.exitCode = 1;
41
- return;
42
- }
43
- console.log(`✅ UseCases generated: ${meta.useCasesClassName}`);
44
- }
1
+ export { default } from '../module/generateUseCases.js';
@@ -1,121 +1,97 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import prompts from 'prompts';
4
- import { normalizeContexts } from '../../init/initAliases.js';
5
- import { loadUserConfig } from '../../utils/loadConfig.js';
6
- import { toKebabCase, toPascalCase } from '../../utils/contextUtils.js';
7
- import { updateIndexTs, writeIfNotExists } from '../../utils/fileUtils.js';
8
- const parseInterfaceNames = (rawValue) =>
9
- String(rawValue ?? '')
10
- .split(',')
11
- .map((item) => item.trim())
12
- .filter(Boolean)
13
- .map((item) => toPascalCase(item))
14
- .filter(Boolean);
4
+ import { selectContext, toPascalCase } from '../../utils/contextUtils.js';
5
+ import { appendBarrelExports, updateIndexTs, writeIfNotExists } from '../../utils/fileUtils.js';
6
+ const parseInterfaceNames = (rawValue) => String(rawValue ?? '')
7
+ .split(',')
8
+ .map((item) => item.trim())
9
+ .filter(Boolean)
10
+ .map((item) => toPascalCase(item))
11
+ .filter(Boolean);
15
12
  const toFileNameFromInterface = (interfaceName) => interfaceName.replace(/^I/, '') || 'Type';
16
13
  const validateInterfaceNames = (rawValue) => {
17
- const names = parseInterfaceNames(rawValue);
18
- if (!names.length) return 'Provide at least one interface name';
19
- for (const name of names) {
20
- if (!name.startsWith('I')) {
21
- return `Interface "${name}" must start with "I"`;
22
- }
23
- }
24
- return true;
14
+ const names = parseInterfaceNames(rawValue);
15
+ if (!names.length)
16
+ return 'Provide at least one interface name';
17
+ for (const name of names) {
18
+ if (!/^I[A-Z][A-Za-z0-9]*$/.test(name)) {
19
+ return `Interface "${name}" must start with "I"`;
20
+ }
21
+ }
22
+ return true;
25
23
  };
26
24
  const createInterfaceContent = (name) => `export interface ${name} {
27
25
  \t[key: string]: unknown;
28
26
  }
29
27
  `;
30
28
  const writeRootIndex = async (domainPath) => {
31
- const content = `export * from './model';
32
- export * from './ports';
33
- `;
34
- await fs.writeFile(path.join(domainPath, 'index.ts'), content, 'utf-8');
35
- };
36
- const selectContext = async () => {
37
- const config = await loadUserConfig();
38
- const contexts = normalizeContexts(config.contexts);
39
- if (!contexts.length) {
40
- console.error('❌ Cannot generate domain: `contexts` is missing or empty in azure-net.config.ts/js');
41
- return null;
42
- }
43
- const { context } = await prompts({
44
- type: 'select',
45
- name: 'context',
46
- message: 'Select context:',
47
- choices: contexts.map((item) => ({ title: item.name, value: item.name })),
48
- initial: 0
49
- });
50
- return context ? String(context) : null;
29
+ await appendBarrelExports(path.join(domainPath, 'index.ts'), ['./Entities', './Ports', './Enums']);
51
30
  };
52
31
  const createInterfacesInLayer = async (layerPath, names) => {
53
- for (const interfaceName of names) {
54
- const fileName = toFileNameFromInterface(interfaceName);
55
- const filePath = path.join(layerPath, `${fileName}.ts`);
56
- await writeIfNotExists(filePath, createInterfaceContent(interfaceName));
57
- }
58
- await updateIndexTs(layerPath);
32
+ for (const interfaceName of names) {
33
+ const fileName = toFileNameFromInterface(interfaceName);
34
+ const filePath = path.join(layerPath, `${fileName}.ts`);
35
+ await writeIfNotExists(filePath, createInterfaceContent(interfaceName));
36
+ }
37
+ await updateIndexTs(layerPath);
59
38
  };
60
39
  export default async function generateDomain(options = {}) {
61
- const { entityRaw } = await prompts({
62
- type: 'text',
63
- name: 'entityRaw',
64
- message: 'Entity name:',
65
- initial: options.entityName ?? '',
66
- validate: (value) => (String(value ?? '').trim().length > 0 ? true : 'Entity name is required')
67
- });
68
- let context = options.contextName ? String(options.contextName) : null;
69
- if (!context) {
70
- context = await selectContext();
71
- }
72
- if (!context) {
73
- process.exitCode = 1;
74
- return null;
75
- }
76
- const entityName = toKebabCase(String(entityRaw ?? '').trim()) || 'entity';
77
- const domainPath = path.join(process.cwd(), 'src', 'app', context, 'layers', 'domain', entityName);
78
- const modelPath = path.join(domainPath, 'model');
79
- const portsPath = path.join(domainPath, 'ports');
80
- await fs.mkdir(modelPath, { recursive: true });
81
- await fs.mkdir(portsPath, { recursive: true });
82
- const { shouldCreateModels } = await prompts({
83
- type: 'confirm',
84
- name: 'shouldCreateModels',
85
- message: 'Create model interfaces?',
86
- initial: true
87
- });
88
- if (shouldCreateModels) {
89
- const { modelNamesRaw } = await prompts({
90
- type: 'text',
91
- name: 'modelNamesRaw',
92
- message: 'Model interface names (comma separated, start with I):',
93
- validate: validateInterfaceNames
94
- });
95
- const modelNames = parseInterfaceNames(modelNamesRaw);
96
- await createInterfacesInLayer(modelPath, modelNames);
97
- } else {
98
- await updateIndexTs(modelPath);
99
- }
100
- const { shouldCreatePorts } = await prompts({
101
- type: 'confirm',
102
- name: 'shouldCreatePorts',
103
- message: 'Create port interfaces?',
104
- initial: true
105
- });
106
- if (shouldCreatePorts) {
107
- const { portNamesRaw } = await prompts({
108
- type: 'text',
109
- name: 'portNamesRaw',
110
- message: 'Port interface names (comma separated, start with I):',
111
- validate: validateInterfaceNames
112
- });
113
- const portNames = parseInterfaceNames(portNamesRaw);
114
- await createInterfacesInLayer(portsPath, portNames);
115
- } else {
116
- await updateIndexTs(portsPath);
117
- }
118
- await writeRootIndex(domainPath);
119
- console.log(`✅ Domain generated: ${domainPath}`);
120
- return { contextName: context, domainName: entityName, domainPath };
40
+ let context = options.contextName ? String(options.contextName) : null;
41
+ if (!context) {
42
+ context = await selectContext();
43
+ }
44
+ if (!context) {
45
+ process.exitCode = 1;
46
+ return null;
47
+ }
48
+ context = toPascalCase(context);
49
+ const domainPath = path.join(process.cwd(), 'src/app/Contexts', context, 'Domain');
50
+ const modelPath = path.join(domainPath, 'Entities');
51
+ const portsPath = path.join(domainPath, 'Ports');
52
+ await fs.mkdir(modelPath, { recursive: true });
53
+ await fs.mkdir(portsPath, { recursive: true });
54
+ const { shouldCreateModels } = await prompts({
55
+ type: 'confirm',
56
+ name: 'shouldCreateModels',
57
+ message: 'Create entity interfaces?',
58
+ initial: true
59
+ });
60
+ if (shouldCreateModels) {
61
+ const { modelNamesRaw } = await prompts({
62
+ type: 'text',
63
+ name: 'modelNamesRaw',
64
+ message: 'Entity interface names (comma separated, start with I):',
65
+ validate: validateInterfaceNames
66
+ });
67
+ const modelNames = parseInterfaceNames(modelNamesRaw);
68
+ await createInterfacesInLayer(modelPath, modelNames);
69
+ }
70
+ else {
71
+ await updateIndexTs(modelPath);
72
+ }
73
+ const { shouldCreatePorts } = await prompts({
74
+ type: 'confirm',
75
+ name: 'shouldCreatePorts',
76
+ message: 'Create port interfaces?',
77
+ initial: true
78
+ });
79
+ if (shouldCreatePorts) {
80
+ const { portNamesRaw } = await prompts({
81
+ type: 'text',
82
+ name: 'portNamesRaw',
83
+ message: 'Port interface names (comma separated, start with I):',
84
+ validate: validateInterfaceNames
85
+ });
86
+ const portNames = parseInterfaceNames(portNamesRaw);
87
+ await createInterfacesInLayer(portsPath, portNames);
88
+ }
89
+ else {
90
+ await updateIndexTs(portsPath);
91
+ }
92
+ await fs.mkdir(path.join(domainPath, 'Enums'), { recursive: true });
93
+ await updateIndexTs(path.join(domainPath, 'Enums'));
94
+ await writeRootIndex(domainPath);
95
+ console.log(`✅ Domain generated: ${domainPath}`);
96
+ return { contextName: context, domainName: context, domainPath };
121
97
  }
@@ -1,74 +1,40 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
1
  import prompts from 'prompts';
4
2
  import generateDomain from './generateDomain.js';
5
3
  import generateRepository from './generateRepository.js';
6
4
  import generatePresenter from './generatePresenter.js';
7
- const findProviderFile = async (contextName, layerName, preferredFileName) => {
8
- const providersPath = path.join(process.cwd(), 'src', 'app', contextName, 'layers', layerName, 'providers');
9
- const preferredPath = path.join(providersPath, preferredFileName);
10
- try {
11
- await fs.access(preferredPath);
12
- return preferredPath;
13
- } catch {
14
- try {
15
- const files = await fs.readdir(providersPath);
16
- const firstTs = files.find((item) => item.endsWith('.ts') && item !== 'index.ts');
17
- return firstTs ? path.join(providersPath, firstTs) : preferredPath;
18
- } catch {
19
- return preferredPath;
20
- }
21
- }
22
- };
23
- const parseProviderConstName = async (providerPath, fallbackName) => {
24
- try {
25
- const content = await fs.readFile(providerPath, 'utf-8');
26
- const match = content.match(/export\s+const\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*createBoundaryProvider/);
27
- return match?.[1] ?? fallbackName;
28
- } catch {
29
- return fallbackName;
30
- }
31
- };
5
+ import { printApplicationProviderWiring } from './repositoryModuleShared.js';
32
6
  export default async function generateModule() {
33
- const domainResult = await generateDomain();
34
- if (!domainResult) {
35
- process.exitCode = 1;
36
- return;
37
- }
38
- const repositoryResult = await generateRepository({
39
- contextName: domainResult.contextName,
40
- domainName: domainResult.domainName,
41
- forceCreateUseCases: true
42
- });
43
- if (!repositoryResult) {
44
- process.exitCode = 1;
45
- return;
46
- }
47
- const infrastructureProviderPath = await findProviderFile(repositoryResult.contextName, 'infrastructure', 'InfrastructureProvider.ts');
48
- const applicationProviderPath = await findProviderFile(repositoryResult.contextName, 'application', 'ApplicationProvider.ts');
49
- const infrastructureProviderName = await parseProviderConstName(infrastructureProviderPath, 'InfrastructureProvider');
50
- console.log('\n⚠️ Manual provider registration is required before presenter generation.');
51
- console.log(`Infrastructure provider file: ${infrastructureProviderPath}`);
52
- console.log(`Application provider file: ${applicationProviderPath}`);
53
- console.log('\nSuggested register snippets:');
54
- console.log(
55
- `- Infrastructure register: ${repositoryResult.repositoryName}: () => new ${repositoryResult.repositoryName}(/* datasource */),`
56
- );
57
- console.log(
58
- `- Application register: ${repositoryResult.useCasesName}: () => new ${repositoryResult.useCasesName}(${infrastructureProviderName}().${repositoryResult.repositoryName}),`
59
- );
60
- const { isReadyForPresenter } = await prompts({
61
- type: 'confirm',
62
- name: 'isReadyForPresenter',
63
- message: 'Did you register repository/use-cases in providers and want to continue?',
64
- initial: false
65
- });
66
- if (!isReadyForPresenter) {
67
- console.log('ℹ️ Module flow paused. Complete provider wiring and rerun `azure-net generate presenter`.');
68
- return;
69
- }
70
- await generatePresenter({
71
- contextName: repositoryResult.contextName,
72
- useCasesName: repositoryResult.useCasesName
73
- });
7
+ const domainResult = await generateDomain();
8
+ if (!domainResult) {
9
+ process.exitCode = 1;
10
+ return;
11
+ }
12
+ const repositoryResult = await generateRepository({
13
+ contextName: domainResult.contextName,
14
+ domainName: domainResult.domainName,
15
+ forceCreateUseCases: true
16
+ });
17
+ if (!repositoryResult) {
18
+ process.exitCode = 1;
19
+ return;
20
+ }
21
+ if (!repositoryResult.useCasesCreated) {
22
+ process.exitCode = 1;
23
+ return;
24
+ }
25
+ printApplicationProviderWiring(repositoryResult.contextName, repositoryResult.repositoryName, repositoryResult.datasourceName);
26
+ const { isReadyForPresenter } = await prompts({
27
+ type: 'confirm',
28
+ name: 'isReadyForPresenter',
29
+ message: 'Did you register repository/use-cases in the central ApplicationProvider and want to continue?',
30
+ initial: false
31
+ });
32
+ if (!isReadyForPresenter) {
33
+ console.log('ℹ️ Module flow paused. Complete provider wiring and rerun `azure-net generate presenter`.');
34
+ return;
35
+ }
36
+ await generatePresenter({
37
+ contextName: repositoryResult.contextName,
38
+ useCasesName: repositoryResult.useCasesName
39
+ });
74
40
  }