@azure-net/cli 5.1.1 → 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 +4 -7
  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 -275
  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,102 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import fsSync from 'node:fs';
3
- import path from 'node:path';
4
- import prompts from 'prompts';
5
- import { writeIfNotExists, updateIndexTs } from '../utils/fileUtils.js';
6
- import { toPascalCase } from '../utils/contextUtils.js';
7
- import { getFoundationConstructPath, getSharedState } from '../utils/sharedFoundation.js';
8
-
9
- type ConfigPath = 'ts' | 'js';
10
-
11
- const createPresenterFactoryTemplate = (
12
- factoryName: string
13
- ): string => `import { createAsyncHelpers, createPresenterFactory } from '@azure-net/kit/delivery';
14
-
15
- export const AsyncHelpers = createAsyncHelpers();
16
-
17
- export const ${factoryName} = createPresenterFactory({ ...AsyncHelpers });
18
- `;
19
-
20
- const resolveConfigFile = (cwd: string): { filepath: string; type: ConfigPath; exists: boolean; content: string } => {
21
- const tsPath = path.join(cwd, 'azure-net.config.ts');
22
- const jsPath = path.join(cwd, 'azure-net.config.js');
23
-
24
- if (fsSync.existsSync(tsPath)) {
25
- return { filepath: tsPath, type: 'ts', exists: true, content: fsSync.readFileSync(tsPath, 'utf-8') };
26
- }
27
- if (fsSync.existsSync(jsPath)) {
28
- return { filepath: jsPath, type: 'js', exists: true, content: fsSync.readFileSync(jsPath, 'utf-8') };
29
- }
30
-
31
- return { filepath: tsPath, type: 'ts', exists: false, content: '' };
32
- };
33
-
34
- const buildDefaultPresenterFactoryConfigEntry = (factoryName: string): string => {
35
- return `defaultPresenterFactory: '${factoryName}'`;
36
- };
37
-
38
- const upsertDefaultPresenterFactoryConfig = (content: string, factoryName: string): string => {
39
- const hasExportDefaultObject = /export\s+default\s*\{[\s\S]*\}\s*;?/.test(content);
40
- const defaultFactoryEntry = buildDefaultPresenterFactoryConfigEntry(factoryName);
41
-
42
- if (!hasExportDefaultObject) {
43
- return `export default {\n\t${defaultFactoryEntry}\n};\n`;
44
- }
45
-
46
- let nextContent = content;
47
-
48
- if (/defaultPresenterFactory\s*:/.test(nextContent)) {
49
- nextContent = nextContent.replace(/defaultPresenterFactory\s*:\s*(\{[\s\S]*?\n\s*\}|['"`][^'"`]+['"`])/m, defaultFactoryEntry);
50
- } else if (/defaultPresenter\s*:/.test(nextContent)) {
51
- nextContent = nextContent.replace(/defaultPresenter\s*:\s*(\{[\s\S]*?\n\s*\}|['"`][^'"`]+['"`])/m, defaultFactoryEntry);
52
- } else {
53
- nextContent = nextContent.replace(/export\s+default\s*\{([\s\S]*)\}\s*;?/, (_full, body: string) => {
54
- const trimmedRight = body.replace(/\s*$/, '');
55
- if (!trimmedRight.length) {
56
- return `export default {\n\t${defaultFactoryEntry}\n};`;
57
- }
58
-
59
- const withComma = trimmedRight.endsWith(',') ? trimmedRight : `${trimmedRight},`;
60
- return `export default {${withComma}\n\t${defaultFactoryEntry}\n};`;
61
- });
62
- }
63
- return nextContent;
64
- };
65
-
66
- export default async function createPresenterFactory(): Promise<void> {
67
- const { presenterFactoryNameRaw } = await prompts({
68
- type: 'text',
69
- name: 'presenterFactoryNameRaw',
70
- message: 'Presenter factory name:',
71
- initial: 'AppPresenter'
72
- });
73
-
74
- const presenterFactoryName = toPascalCase(String(presenterFactoryNameRaw ?? 'AppPresenter')) || 'AppPresenter';
75
- const { sharedContext } = await getSharedState();
76
- const presenterRootPath = getFoundationConstructPath(sharedContext.name, 'presenter');
77
- const filePath = path.join(presenterRootPath, `${presenterFactoryName}.ts`);
78
-
79
- await fs.mkdir(presenterRootPath, { recursive: true });
80
-
81
- const created = await writeIfNotExists(filePath, createPresenterFactoryTemplate(presenterFactoryName));
82
- if (!created) {
83
- console.log(`⚠️ Presenter factory "${presenterFactoryName}" already exists. File was not overwritten.`);
84
- } else {
85
- await updateIndexTs(presenterRootPath);
86
- console.log(`✅ Presenter factory created: ${filePath}`);
87
- }
88
-
89
- const { useAsDefault } = await prompts({
90
- type: 'confirm',
91
- name: 'useAsDefault',
92
- message: 'Use this presenter factory as default for the project?',
93
- initial: true
94
- });
95
-
96
- if (!useAsDefault) return;
97
-
98
- const config = resolveConfigFile(process.cwd());
99
- const nextContent = upsertDefaultPresenterFactoryConfig(config.content, presenterFactoryName);
100
- await fs.writeFile(config.filepath, nextContent, 'utf-8');
101
- console.log(`✅ Default presenter factory saved to ${path.basename(config.filepath)}`);
102
- }
@@ -1,19 +0,0 @@
1
- import path from 'node:path';
2
- import { writeIfNotExists } from '../utils/fileUtils.js';
3
-
4
- const createProgramTemplate = (): string => `import { createApp } from '@azure-net/kit';
5
-
6
- export const { register, Container } = createApp((app) => app);
7
- `;
8
-
9
- export default async function createProgram(): Promise<void> {
10
- const programPath = path.join(process.cwd(), 'src', 'program.ts');
11
- const created = await writeIfNotExists(programPath, createProgramTemplate());
12
-
13
- if (!created) {
14
- console.log('⚠️ Program already exists. Nothing was overwritten.');
15
- return;
16
- }
17
-
18
- console.log(`✅ Program created: ${programPath}`);
19
- }
@@ -1,66 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import prompts from 'prompts';
4
- import { writeIfNotExists, updateIndexTs } from '../utils/fileUtils.js';
5
- import { toPascalCase } from '../utils/contextUtils.js';
6
- import { getFoundationConstructPath, getSharedState } from '../utils/sharedFoundation.js';
7
-
8
- const createResponseWithWrapperTemplate = (name: string): string => {
9
- const interfaceName = `I${name}`;
10
- return `import { ResponseBuilder } from '@azure-net/kit/infra';
11
-
12
- export interface ${interfaceName}<T> {
13
- \tdata: T;
14
- }
15
-
16
- export class ${name}<TData = unknown, TMeta = unknown> extends ResponseBuilder<TData, TMeta, ${interfaceName}<TData>> {
17
- \tprotected unwrapData(data: ${interfaceName}<TData>): TData {
18
- \t\treturn data.data;
19
- \t}
20
- }
21
- `;
22
- };
23
-
24
- const createResponseSimpleTemplate = (name: string): string => `import { ResponseBuilder } from '@azure-net/kit/infra';
25
-
26
- export class ${name}<TData = unknown, TMeta = unknown> extends ResponseBuilder<TData, TMeta> {}
27
- `;
28
-
29
- const ensureResponseName = (rawName: string): string => {
30
- const normalized = toPascalCase(rawName || 'ApiResponse') || 'ApiResponse';
31
- return normalized.endsWith('Response') ? normalized : `${normalized}Response`;
32
- };
33
-
34
- export default async function createResponse(): Promise<void> {
35
- const { responseNameRaw } = await prompts({
36
- type: 'text',
37
- name: 'responseNameRaw',
38
- message: 'Response class name:',
39
- initial: 'ApiResponse'
40
- });
41
-
42
- const responseName = ensureResponseName(String(responseNameRaw ?? 'ApiResponse'));
43
-
44
- const { useCommonResponseWrapper } = await prompts({
45
- type: 'confirm',
46
- name: 'useCommonResponseWrapper',
47
- message: 'Use common backend response wrapper interface?',
48
- initial: true
49
- });
50
-
51
- const { sharedContext } = await getSharedState();
52
- const responseRoot = getFoundationConstructPath(sharedContext.name, 'response');
53
- const filePath = path.join(responseRoot, `${responseName}.ts`);
54
- await fs.mkdir(responseRoot, { recursive: true });
55
-
56
- const template = useCommonResponseWrapper ? createResponseWithWrapperTemplate(responseName) : createResponseSimpleTemplate(responseName);
57
- const created = await writeIfNotExists(filePath, template);
58
- await updateIndexTs(responseRoot);
59
-
60
- if (!created) {
61
- console.log(`⚠️ Response "${responseName}" already exists. File was not overwritten.`);
62
- return;
63
- }
64
-
65
- console.log(`✅ Response created: ${filePath}`);
66
- }
@@ -1,44 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import prompts from 'prompts';
4
- import { writeIfNotExists, updateIndexTs } from '../utils/fileUtils.js';
5
- import { toPascalCase, toCamelCase } from '../utils/contextUtils.js';
6
- import { getFoundationConstructPath, getSharedState } from '../utils/sharedFoundation.js';
7
-
8
- const createSchemaRuleTemplate = (
9
- ruleName: string
10
- ): string => `import type { ValidationParams, ValidationRuleResult } from '@azure-net/kit/delivery';
11
-
12
- export const ${ruleName} = <T = unknown, D = unknown>(): ValidationRuleResult<T, D> => {
13
- \treturn (validationParams: ValidationParams<T, D>) => {
14
- \t\treturn undefined;
15
- \t};
16
- };
17
- `;
18
-
19
- export default async function createSchemaRule(): Promise<void> {
20
- const { ruleNameRaw } = await prompts({
21
- type: 'text',
22
- name: 'ruleNameRaw',
23
- message: 'Schema rule name:',
24
- initial: 'File'
25
- });
26
-
27
- const pascalName = toPascalCase(String(ruleNameRaw ?? 'File')) || 'File';
28
- const camelName = toCamelCase(pascalName) || 'file';
29
- const { sharedContext } = await getSharedState();
30
- const rulesPath = path.join(getFoundationConstructPath(sharedContext.name, 'schema'), 'custom-rules');
31
- const filePath = path.join(rulesPath, `${pascalName}.ts`);
32
-
33
- await fs.mkdir(rulesPath, { recursive: true });
34
-
35
- const created = await writeIfNotExists(filePath, createSchemaRuleTemplate(camelName));
36
- await updateIndexTs(rulesPath);
37
-
38
- if (!created) {
39
- console.log(`⚠️ Schema rule "${pascalName}" already exists. File was not overwritten.`);
40
- return;
41
- }
42
-
43
- console.log(`✅ Schema rule created: ${filePath}`);
44
- }
@@ -1,80 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import prompts from 'prompts';
4
- import { writeIfNotExists } from '../utils/fileUtils.js';
5
- import { getLocalizationPath, getSharedState } from '../utils/sharedFoundation.js';
6
-
7
- const parseLocales = (rawLocales: string): string[] => {
8
- const parsed = String(rawLocales ?? '')
9
- .split(',')
10
- .map((item) => item.trim().toLowerCase())
11
- .filter(Boolean);
12
-
13
- const unique = Array.from(new Set(parsed));
14
- return unique.length ? unique : ['en', 'ru'];
15
- };
16
-
17
- const createTranslationIndexTemplate = (defaultLocale: string): string => `import { messages } from './locales/index.js';
18
- import { createTranslations, type Path } from '@azure-net/kit/i18n';
19
-
20
- export const TranslationManager = createTranslations({
21
- \tmessages,
22
- \tinitLang: '${defaultLocale}',
23
- \tinitLangFromAcceptLanguage: true,
24
- \tcookieName: 'current-language'
25
- });
26
-
27
- type MessagesList = Awaited<ReturnType<(typeof messages)[keyof typeof messages]>>;
28
- type TranslationExtended = { key: MessageKeys | string; vars?: Record<string, unknown> };
29
-
30
- export type MessageKeys = Path<MessagesList>;
31
- export type TranslationParam = MessageKeys | string | TranslationExtended;
32
- export type AvailableLocales = keyof typeof messages;
33
- `;
34
-
35
- const createLocalesIndexTemplate = (locales: string[]): string => {
36
- const lines = locales.map((locale) => `\t${locale}: () => import('./${locale}/index.js').then((res) => res.default)`);
37
- return `export const messages = {\n${lines.join(',\n')}\n};\n`;
38
- };
39
-
40
- const createLocaleTemplate = (): string => `export default {
41
- \ttest: 'test'
42
- };
43
- `;
44
-
45
- export default async function createTranslationManager(): Promise<void> {
46
- const { localesRaw } = await prompts({
47
- type: 'text',
48
- name: 'localesRaw',
49
- message: 'Enter locales (comma separated):',
50
- initial: 'en, ru'
51
- });
52
-
53
- const locales = parseLocales(String(localesRaw ?? 'en, ru'));
54
-
55
- const { defaultLocale } = await prompts({
56
- type: 'select',
57
- name: 'defaultLocale',
58
- message: 'Choose default locale:',
59
- choices: locales.map((locale) => ({ title: locale, value: locale })),
60
- initial: 0
61
- });
62
-
63
- const selectedDefaultLocale = String(defaultLocale ?? locales[0] ?? 'en');
64
-
65
- const { sharedContext } = await getSharedState();
66
- const translationRoot = getLocalizationPath(sharedContext.name);
67
- const localesRoot = path.join(translationRoot, 'locales');
68
- await fs.mkdir(localesRoot, { recursive: true });
69
-
70
- await writeIfNotExists(path.join(translationRoot, 'index.ts'), createTranslationIndexTemplate(selectedDefaultLocale));
71
- await writeIfNotExists(path.join(localesRoot, 'index.ts'), createLocalesIndexTemplate(locales));
72
-
73
- for (const locale of locales) {
74
- const localeDir = path.join(localesRoot, locale);
75
- await fs.mkdir(localeDir, { recursive: true });
76
- await writeIfNotExists(path.join(localeDir, 'index.ts'), createLocaleTemplate());
77
- }
78
-
79
- console.log(`✅ Translation manager created: ${translationRoot}`);
80
- }
@@ -1,88 +0,0 @@
1
- import fs from 'fs/promises';
2
- import path from 'path';
3
- import prompts from 'prompts';
4
- import { loadUserConfig } from './loadConfig.js';
5
-
6
- const APP_PATH = path.join(process.cwd(), 'src/app');
7
-
8
- function normalizeContextNames(rawContexts: unknown): string[] {
9
- if (!Array.isArray(rawContexts)) return [];
10
-
11
- return rawContexts
12
- .map((item) => {
13
- if (typeof item === 'string') {
14
- return item.trim();
15
- }
16
- if (!item || typeof item !== 'object') return '';
17
- return String(item.name ?? '').trim();
18
- })
19
- .filter(Boolean);
20
- }
21
-
22
- export async function selectContext(message = 'Select context:'): Promise<string | null> {
23
- const config = await loadUserConfig();
24
- const contexts = normalizeContextNames(config.contexts);
25
-
26
- const { context } = await prompts({
27
- type: 'select',
28
- name: 'context',
29
- message,
30
- choices: contexts.map((c) => ({ title: c, value: c }))
31
- });
32
-
33
- return context ? String(context) : null;
34
- }
35
-
36
- export function getContextPath(context: string): string {
37
- return path.join(APP_PATH, context, 'layers');
38
- }
39
-
40
- export async function getAvailableFiles(dir: string, pattern = '.ts'): Promise<string[]> {
41
- try {
42
- const files = await fs.readdir(dir);
43
- return files.filter((f) => f.endsWith(pattern) && f !== 'index.ts').map((f) => f.replace(pattern, ''));
44
- } catch {
45
- return [];
46
- }
47
- }
48
-
49
- export async function getApplicationProviderServices(context: string): Promise<string[]> {
50
- const contextPath = getContextPath(context);
51
- const providerPath = path.join(contextPath, 'application/providers/ApplicationProvider.ts');
52
-
53
- try {
54
- const content = await fs.readFile(providerPath, 'utf-8');
55
- // Extract service names from ApplicationProvider
56
- const serviceRegex = /(\w+Service):\s*\(/g;
57
- const services: string[] = [];
58
- let match;
59
-
60
- while ((match = serviceRegex.exec(content)) !== null) {
61
- const serviceName = match[1];
62
- if (serviceName) services.push(serviceName);
63
- }
64
-
65
- return services;
66
- } catch {
67
- return [];
68
- }
69
- }
70
-
71
- export function toPascalCase(str: string): string {
72
- return str
73
- .split(/[-_\s]+/)
74
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
75
- .join('');
76
- }
77
-
78
- export function toCamelCase(str: string): string {
79
- const pascal = toPascalCase(str);
80
- return pascal.charAt(0).toLowerCase() + pascal.slice(1);
81
- }
82
-
83
- export function toKebabCase(str: string): string {
84
- return str
85
- .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
86
- .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
87
- .toLowerCase();
88
- }
@@ -1,74 +0,0 @@
1
- import fs from 'fs/promises';
2
- import path from 'path';
3
-
4
- export async function writeIfNotExists(filepath: string, content: string): Promise<boolean> {
5
- try {
6
- await fs.access(filepath);
7
- console.log(`⚠️ Skip existing: ${filepath}`);
8
- return false;
9
- } catch {
10
- await fs.mkdir(path.dirname(filepath), { recursive: true });
11
- await fs.writeFile(filepath, content, 'utf-8');
12
- console.log(`✅ Created: ${filepath}`);
13
- return true;
14
- }
15
- }
16
-
17
- export async function updateIndexTs(dir: string, filePattern = '.ts', ignore: string[] = ['index.ts']): Promise<void> {
18
- try {
19
- const files = (await fs.readdir(dir)).filter((f) => f.endsWith(filePattern) && !ignore.includes(f));
20
- const content = files.map((f) => `export * from './${f.replace('.ts', '')}';`).join('\n') + '\n';
21
- await fs.writeFile(path.join(dir, 'index.ts'), content, 'utf-8');
22
- } catch {
23
- // Directory doesn't exist yet
24
- }
25
- }
26
-
27
- export async function ensureIndexExports(layerPath: string): Promise<void> {
28
- try {
29
- const subdirs = await fs.readdir(layerPath, { withFileTypes: true });
30
- const exportLines = subdirs.filter((d) => d.isDirectory()).map((d) => `export * from './${d.name}';`);
31
-
32
- if (exportLines.length > 0) {
33
- await fs.writeFile(path.join(layerPath, 'index.ts'), exportLines.join('\n') + '\n', 'utf-8');
34
- }
35
- } catch {
36
- // Directory doesn't exist
37
- }
38
- }
39
-
40
- export async function injectIntoFile(
41
- filepath: string,
42
- searchPattern: string,
43
- newContent: string,
44
- position: 'after' | 'before' = 'after'
45
- ): Promise<boolean> {
46
- try {
47
- let content = await fs.readFile(filepath, 'utf-8');
48
- const index = content.indexOf(searchPattern);
49
-
50
- if (index === -1) {
51
- console.warn(`Pattern not found in ${filepath}`);
52
- return false;
53
- }
54
-
55
- if (content.includes(newContent.trim())) {
56
- console.log(`Content already exists in ${filepath}`);
57
- return false;
58
- }
59
-
60
- if (position === 'after') {
61
- const insertIndex = index + searchPattern.length;
62
- content = content.slice(0, insertIndex) + '\n' + newContent + content.slice(insertIndex);
63
- } else {
64
- content = content.slice(0, index) + newContent + '\n' + content.slice(index);
65
- }
66
-
67
- await fs.writeFile(filepath, content, 'utf-8');
68
- console.log(`✅ Updated: ${filepath}`);
69
- return true;
70
- } catch (error: unknown) {
71
- console.error(`Failed to update ${filepath}:`, error instanceof Error ? error.message : String(error));
72
- return false;
73
- }
74
- }
@@ -1,68 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import fsSync from 'node:fs';
3
- import path from 'node:path';
4
-
5
- export type AzureNetConfig = {
6
- contexts: Array<string | { name?: string; alias?: string }>;
7
- defaultContext: string;
8
- sharedAlias?: string;
9
- packageManager?: string;
10
- defaultSchemaFactory?: string;
11
- defaultPresenterFactory?: string;
12
- groupRoutesFunc?: unknown;
13
- [key: string]: unknown;
14
- };
15
-
16
- const DEFAULT_CONFIG: AzureNetConfig = {
17
- contexts: [],
18
- defaultContext: 'web'
19
- };
20
-
21
- function toObjectFromDefaultExport(content: string): Record<string, unknown> {
22
- const source = String(content ?? '').trim();
23
- if (!source.length) return {};
24
-
25
- const replacedExport = source.replace(/^\s*export\s+default\s+/m, 'return ');
26
- if (replacedExport === source) return {};
27
-
28
- const withSemicolon = /;\s*$/.test(replacedExport) ? replacedExport : `${replacedExport};`;
29
-
30
- try {
31
- return new Function(withSemicolon)() ?? {};
32
- } catch {
33
- return {};
34
- }
35
- }
36
-
37
- export function resolveConfigFile(cwd = process.cwd()): { exists: boolean; filepath: string; type: 'ts' | 'js' } {
38
- const tsPath = path.join(cwd, 'azure-net.config.ts');
39
- const jsPath = path.join(cwd, 'azure-net.config.js');
40
-
41
- if (fsSync.existsSync(tsPath)) {
42
- return { exists: true, filepath: tsPath, type: 'ts' };
43
- }
44
- if (fsSync.existsSync(jsPath)) {
45
- return { exists: true, filepath: jsPath, type: 'js' };
46
- }
47
-
48
- return { exists: false, filepath: tsPath, type: 'ts' };
49
- }
50
-
51
- export async function loadUserConfig(): Promise<AzureNetConfig> {
52
- const { exists, filepath } = resolveConfigFile();
53
- if (!exists) {
54
- return { ...DEFAULT_CONFIG };
55
- }
56
-
57
- try {
58
- const content = await fs.readFile(filepath, 'utf-8');
59
- const parsed = toObjectFromDefaultExport(content);
60
- if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
61
- return { ...DEFAULT_CONFIG };
62
- }
63
-
64
- return { ...DEFAULT_CONFIG, ...(parsed as Record<string, unknown>) };
65
- } catch {
66
- return { ...DEFAULT_CONFIG };
67
- }
68
- }
@@ -1,70 +0,0 @@
1
- import path from 'node:path';
2
- import { normalizeContexts } from '../init/initAliases.js';
3
- import { loadUserConfig, resolveConfigFile } from './loadConfig.js';
4
-
5
- export type FoundationConstruct = 'datasource' | 'presenter' | 'provider' | 'response' | 'schema';
6
- export type ContextConfig = { name: string; alias: string };
7
-
8
- export const SHARED_ESSENTIALS_DIR_NAME = 'essentials';
9
-
10
- const normalizeAlias = (value: unknown): string => {
11
- const raw = String(value ?? '').trim();
12
- return raw.startsWith('$') ? raw : `$${raw}`;
13
- };
14
-
15
- const createMissingSharedAliasError = (): Error =>
16
- new Error(
17
- '`sharedAlias` is missing in azure-net.config.ts/js. Add sharedAlias and make sure it points to one of `contexts`, for example: sharedAlias: "$shared-kernel".'
18
- );
19
-
20
- export const getSharedState = async (): Promise<{ contexts: ContextConfig[]; sharedAlias: string; sharedContext: ContextConfig }> => {
21
- const config = await loadUserConfig();
22
- const contexts = normalizeContexts(config.contexts) as ContextConfig[];
23
- const sharedAliasRaw = String(config.sharedAlias ?? '').trim();
24
-
25
- if (!sharedAliasRaw.length) throw createMissingSharedAliasError();
26
-
27
- const sharedAlias = normalizeAlias(sharedAliasRaw);
28
- const sharedContext = contexts.find((context) => normalizeAlias(context.alias) === sharedAlias);
29
-
30
- if (!sharedContext) {
31
- throw new Error(
32
- `sharedAlias "${sharedAlias}" does not point to any configured context. Add a context with alias "${sharedAlias}" in azure-net.config.ts/js.`
33
- );
34
- }
35
-
36
- return {
37
- contexts,
38
- sharedAlias,
39
- sharedContext
40
- };
41
- };
42
-
43
- export const hasSharedAliasConfig = async (): Promise<boolean> => {
44
- const config = await loadUserConfig();
45
- return String(config.sharedAlias ?? '').trim().length > 0;
46
- };
47
-
48
- export const getSharedContextRootPath = (sharedContextName: string): string => path.join(process.cwd(), 'src', 'app', sharedContextName);
49
-
50
- export const getSharedEssentialsPath = (sharedContextName: string): string =>
51
- path.join(getSharedContextRootPath(sharedContextName), SHARED_ESSENTIALS_DIR_NAME);
52
-
53
- export const getFoundationRootPath = (sharedContextName: string): string =>
54
- path.join(getSharedEssentialsPath(sharedContextName), 'foundation', 'constructs');
55
-
56
- export const getFoundationConstructPath = (sharedContextName: string, construct: FoundationConstruct): string =>
57
- path.join(getFoundationRootPath(sharedContextName), construct);
58
-
59
- export const getFoundationConstructImportPath = (sharedAlias: string, construct: FoundationConstruct): string =>
60
- `${sharedAlias}/${SHARED_ESSENTIALS_DIR_NAME}/foundation/constructs/${construct}`;
61
-
62
- export const getLocalizationPath = (sharedContextName: string): string =>
63
- path.join(getSharedEssentialsPath(sharedContextName), 'localization');
64
-
65
- export const getLocalizationImportPath = (sharedAlias: string): string => `${sharedAlias}/${SHARED_ESSENTIALS_DIR_NAME}/localization`;
66
-
67
- export const getConfigFileLabel = (): string => {
68
- const config = resolveConfigFile();
69
- return config.exists ? path.basename(config.filepath) : 'azure-net.config.ts/js';
70
- };
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "rootDir": ".",
7
- "outDir": "dist",
8
- "allowJs": true,
9
- "checkJs": false,
10
- "declaration": true,
11
- "sourceMap": true,
12
- "strict": true,
13
- "noUncheckedIndexedAccess": true,
14
- "esModuleInterop": true,
15
- "skipLibCheck": true
16
- },
17
- "include": ["bin/**/*.ts", "src/**/*"],
18
- "exclude": ["dist", "node_modules"]
19
- }