@azure-net/cli 5.1.1 → 6.0.0-next.3

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 (180) hide show
  1. package/README.md +201 -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/presenterFactories.d.ts +9 -0
  44. package/dist/src/migrate/presenters.d.ts +13 -0
  45. package/dist/src/migrate/translations.d.ts +8 -0
  46. package/dist/src/plugins/addLint.d.ts +5 -0
  47. package/dist/src/scaffolds/createCoreSchema.d.ts +1 -0
  48. package/dist/src/scaffolds/createDatasource.d.ts +1 -0
  49. package/dist/src/scaffolds/createProgram.d.ts +1 -0
  50. package/dist/src/scaffolds/createResponse.d.ts +1 -0
  51. package/dist/src/scaffolds/createSchemaRule.d.ts +1 -0
  52. package/dist/src/scaffolds/createTranslationManager.d.ts +1 -0
  53. package/{src/scaffolds/index.ts → dist/src/scaffolds/index.d.ts} +0 -2
  54. package/dist/src/scaffolds/registerDatasource.d.ts +2 -0
  55. package/dist/src/scaffolds/updateDefaultFactoryConfig.d.ts +1 -0
  56. package/dist/src/utils/architecture.d.ts +31 -0
  57. package/dist/src/utils/contextUtils.d.ts +6 -0
  58. package/dist/src/utils/fileUtils.d.ts +5 -0
  59. package/dist/src/utils/flattenConfig.d.ts +2 -0
  60. package/dist/src/utils/legacyAliases.d.ts +1 -0
  61. package/dist/src/utils/loadConfig.d.ts +16 -0
  62. package/dist/src/utils/packageImports.d.ts +4 -0
  63. package/dist/src/utils/sharedFoundation.d.ts +20 -0
  64. package/dist/src/utils/viteConfig.d.ts +9 -0
  65. package/package.json +17 -7
  66. package/src/checks/architecture.js +154 -0
  67. package/src/checks/checkDomain.js +124 -154
  68. package/src/checks/checkFoldersStructure.js +64 -52
  69. package/src/checks/checkHooks.js +12 -12
  70. package/src/checks/checkImports.js +26 -142
  71. package/src/checks/checkInternal.js +27 -24
  72. package/src/checks/checkLayerBoundaries.js +22 -197
  73. package/src/checks/checkLayerImports.js +14 -134
  74. package/src/checks/checkPresenterNames.js +156 -143
  75. package/src/checks/checkProject.js +27 -26
  76. package/src/checks/checkProviderGraph.js +182 -166
  77. package/src/checks/checkProviderNames.js +123 -112
  78. package/src/generate/layers/generateRepository.js +1 -109
  79. package/src/generate/layers/generateRepositoryMethod.js +1 -90
  80. package/src/generate/layers/generateUseCases.js +1 -44
  81. package/src/generate/module/generateDomain.js +81 -105
  82. package/src/generate/module/generateModule.js +34 -68
  83. package/src/generate/module/generateModulePreset.js +188 -248
  84. package/src/generate/module/generatePresenter.js +441 -369
  85. package/src/generate/module/generateRepository.js +102 -121
  86. package/src/generate/module/generateRepositoryMethod.js +117 -0
  87. package/src/generate/module/generateSchemaFromType.js +283 -280
  88. package/src/generate/module/generateStore.js +41 -0
  89. package/src/generate/module/generateTypesJson.js +196 -195
  90. package/src/generate/module/generateUseCases.js +47 -55
  91. package/src/generate/module/repositoryModuleShared.js +480 -459
  92. package/src/generate/routes/generateRoutes.js +4 -7
  93. package/src/generate/ui/generateComponent.js +44 -64
  94. package/src/generate/ui/generateDesignComponent.js +21 -41
  95. package/src/generate/ui/generateWidget.js +21 -41
  96. package/src/git/commit.js +67 -0
  97. package/src/git/push.js +19 -0
  98. package/src/git/runGit.js +11 -0
  99. package/src/init/initAliases.js +19 -135
  100. package/src/init/initEdges.js +79 -54
  101. package/src/init/initStructure.js +31 -145
  102. package/src/install/configureCommitTools.js +1 -0
  103. package/src/install/installFresh.js +39 -68
  104. package/src/migrate/migrate.js +1027 -0
  105. package/src/migrate/presenterFactories.js +189 -0
  106. package/src/migrate/presenters.js +373 -0
  107. package/src/migrate/translations.js +213 -0
  108. package/src/plugins/addLint.js +52 -219
  109. package/src/scaffolds/createCoreSchema.js +65 -91
  110. package/src/scaffolds/createDatasource.js +67 -101
  111. package/src/scaffolds/createProgram.js +8 -8
  112. package/src/scaffolds/createResponse.js +29 -29
  113. package/src/scaffolds/createSchemaRule.js +19 -19
  114. package/src/scaffolds/createTranslationManager.js +84 -37
  115. package/src/scaffolds/index.js +0 -2
  116. package/src/scaffolds/registerDatasource.js +59 -0
  117. package/src/scaffolds/updateDefaultFactoryConfig.js +31 -0
  118. package/src/utils/architecture.js +145 -0
  119. package/src/utils/contextUtils.js +32 -65
  120. package/src/utils/fileUtils.js +69 -50
  121. package/src/utils/flattenConfig.js +38 -0
  122. package/src/utils/legacyAliases.js +75 -0
  123. package/src/utils/loadConfig.js +76 -40
  124. package/src/utils/packageImports.js +63 -0
  125. package/src/utils/sharedFoundation.js +36 -42
  126. package/src/utils/viteConfig.js +295 -0
  127. package/.prettierrc +0 -7
  128. package/bin/azure-net.ts +0 -308
  129. package/eslint.config.js +0 -34
  130. package/src/checks/checkDomain.ts +0 -223
  131. package/src/checks/checkFoldersStructure.ts +0 -85
  132. package/src/checks/checkHooks.ts +0 -22
  133. package/src/checks/checkImports.ts +0 -193
  134. package/src/checks/checkInternal.ts +0 -48
  135. package/src/checks/checkLayerBoundaries.ts +0 -255
  136. package/src/checks/checkLayerImports.ts +0 -185
  137. package/src/checks/checkPresenterNames.ts +0 -203
  138. package/src/checks/checkProject.ts +0 -45
  139. package/src/checks/checkProviderGraph.ts +0 -234
  140. package/src/checks/checkProviderNames.ts +0 -165
  141. package/src/generate/layers/generateRepository.ts +0 -123
  142. package/src/generate/layers/generateRepositoryMethod.ts +0 -102
  143. package/src/generate/layers/generateUseCases.ts +0 -50
  144. package/src/generate/layers/repositoryShared.js +0 -506
  145. package/src/generate/layers/repositoryShared.ts +0 -662
  146. package/src/generate/module/generateDomain.ts +0 -147
  147. package/src/generate/module/generateModule.ts +0 -84
  148. package/src/generate/module/generateModulePreset.ts +0 -338
  149. package/src/generate/module/generatePresenter.ts +0 -498
  150. package/src/generate/module/generateRepository.ts +0 -158
  151. package/src/generate/module/generateSchemaFromType.ts +0 -368
  152. package/src/generate/module/generateTypesJson.ts +0 -259
  153. package/src/generate/module/generateUseCases.ts +0 -67
  154. package/src/generate/module/repositoryModuleShared.ts +0 -669
  155. package/src/generate/routes/generateRoutes.ts +0 -275
  156. package/src/generate/ui/generateComponent.ts +0 -100
  157. package/src/generate/ui/generateDesignComponent.ts +0 -71
  158. package/src/generate/ui/generateWidget.ts +0 -71
  159. package/src/init/initAliases.ts +0 -172
  160. package/src/init/initEdges.ts +0 -74
  161. package/src/init/initStructure.ts +0 -172
  162. package/src/install/installFresh.ts +0 -93
  163. package/src/plugins/addLint.ts +0 -274
  164. package/src/scaffolds/createCoreSchema.ts +0 -130
  165. package/src/scaffolds/createDatasource.ts +0 -161
  166. package/src/scaffolds/createDatasourceProvider.js +0 -127
  167. package/src/scaffolds/createDatasourceProvider.ts +0 -161
  168. package/src/scaffolds/createPresenterFactory.js +0 -83
  169. package/src/scaffolds/createPresenterFactory.ts +0 -102
  170. package/src/scaffolds/createProgram.ts +0 -19
  171. package/src/scaffolds/createResponse.ts +0 -66
  172. package/src/scaffolds/createSchemaRule.ts +0 -44
  173. package/src/scaffolds/createTranslationManager.ts +0 -80
  174. package/src/utils/contextUtils.ts +0 -88
  175. package/src/utils/fileUtils.ts +0 -74
  176. package/src/utils/loadConfig.ts +0 -68
  177. package/src/utils/sharedFoundation.ts +0 -70
  178. package/tsconfig.json +0 -19
  179. /package/{src/checks/index.ts → dist/src/checks/index.d.ts} +0 -0
  180. /package/{src/plugins/index.ts → dist/src/plugins/index.d.ts} +0 -0
@@ -2,9 +2,8 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import prompts from 'prompts';
4
4
  import { loadUserConfig } from '../../utils/loadConfig.js';
5
- import { getSharedContextRootPath, getSharedState } from '../../utils/sharedFoundation.js';
6
5
  import { toCamelCase } from '../../utils/contextUtils.js';
7
- const ROUTES_DIR = path.join(process.cwd(), 'src', 'routes');
6
+ const getRoutesDir = () => path.join(process.cwd(), 'src', 'routes');
8
7
  const ROUTE_FILE_PATTERN = /^\+(page|server)(?:\.server)?\.(?:svelte|ts|js)$/;
9
8
  const PAGE_FILE_PATTERN = /^\+page(?:\.server)?\.(?:svelte|ts|js)$/;
10
9
  const SERVER_FILE_PATTERN = /^\+server\.(?:ts|js)$/;
@@ -79,7 +78,7 @@ const collectRoutes = async (dir, segments = [], groupStack = [], rootGroup) =>
79
78
  routes.push({
80
79
  url,
81
80
  routeDir: dir,
82
- relativeDir: path.relative(ROUTES_DIR, dir) || '.',
81
+ relativeDir: path.relative(getRoutesDir(), dir) || '.',
83
82
  segments,
84
83
  dynamicParams: routeVariants.dynamicParams,
85
84
  rootGroup,
@@ -190,22 +189,20 @@ export default async function generateRoutes() {
190
189
  const mode = await selectGroupingMode();
191
190
  if (!mode)
192
191
  return;
193
- const { sharedContext } = await getSharedState();
194
192
  const resolver = mode === 'config-function' ? await getConfigRouteGroupResolver() : undefined;
195
193
  if (mode === 'config-function' && !resolver) {
196
194
  process.exitCode = 1;
197
195
  return;
198
196
  }
199
- const routes = await collectRoutes(ROUTES_DIR);
197
+ const routes = await collectRoutes(getRoutesDir());
200
198
  if (!routes.length) {
201
199
  console.warn('⚠️ No SvelteKit routes found in src/routes');
202
200
  return;
203
201
  }
204
202
  const groups = createGroupMap(routes, mode, resolver ?? undefined);
205
- const outputDir = path.join(getSharedContextRootPath(sharedContext.name), 'runtime', 'routes');
203
+ const outputDir = path.join(process.cwd(), 'src', 'app', 'Platform', 'Bootstrap', 'Routes');
206
204
  const outputFile = path.join(outputDir, 'index.ts');
207
205
  await fs.mkdir(outputDir, { recursive: true });
208
206
  await fs.writeFile(outputFile, createGeneratedFile(groups), 'utf-8');
209
207
  console.log(`✅ Routes generated: ${outputFile}`);
210
208
  }
211
- //# sourceMappingURL=generateRoutes.js.map
@@ -2,81 +2,61 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import prompts from 'prompts';
4
4
  import { toPascalCase } from '../../utils/contextUtils.js';
5
- import { normalizeContexts } from '../../init/initAliases.js';
6
- import { loadUserConfig } from '../../utils/loadConfig.js';
5
+ import { selectWorkspace } from '../../utils/architecture.js';
7
6
  import { writeIfNotExists } from '../../utils/fileUtils.js';
8
7
  const createComponentContent = (propsName) => `<script lang="ts">
9
- import type { ${propsName} } from './types';
8
+ import type { ${propsName} } from './Types';
10
9
  const {}: ${propsName} = $props();
11
10
  </script>
12
11
  <!--Your HTML here-->
13
12
  <style lang="scss">
14
- \t@use './style';
13
+ \t@use './Style';
15
14
  </style>
16
15
  `;
17
16
  const createTypesContent = (propsName) => `export interface ${propsName} {}
18
17
  `;
19
18
  const createIndexContent = (name) => `export { default as ${name} } from './Component.svelte';
20
19
  `;
21
- const printContextsError = () => {
22
- console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
23
- };
24
- const selectContext = async () => {
25
- const config = await loadUserConfig();
26
- const contexts = normalizeContexts(config.contexts);
27
- if (!contexts.length) return null;
28
- const { context } = await prompts({
29
- type: 'select',
30
- name: 'context',
31
- message: 'Select context:',
32
- choices: contexts.map((item) => ({ title: item.name, value: item.name })),
33
- initial: 0
34
- });
35
- return context ? String(context) : null;
36
- };
37
20
  export default async function generateComponent() {
38
- const context = await selectContext();
39
- if (!context) {
40
- printContextsError();
41
- process.exitCode = 1;
42
- return;
43
- }
44
- const { rawName } = await prompts({
45
- type: 'text',
46
- name: 'rawName',
47
- message: 'Component name:',
48
- validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
49
- });
50
- const { componentKind } = await prompts({
51
- type: 'select',
52
- name: 'componentKind',
53
- message: 'Component kind:',
54
- choices: [
55
- { title: 'shared', value: 'shared' },
56
- { title: 'layout', value: 'layout' },
57
- { title: 'page', value: 'page' }
58
- ],
59
- initial: 0
60
- });
61
- const name = toPascalCase(String(rawName ?? 'Component')) || 'Component';
62
- const propsName = `IComponent${name}Props`;
63
- const kind = componentKind ?? 'shared';
64
- let targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'components', kind);
65
- if (kind === 'page') {
66
- const { pageFolderRaw } = await prompts({
67
- type: 'text',
68
- name: 'pageFolderRaw',
69
- message: 'Page folder name:',
70
- validate: (value) => (String(value).trim().length > 0 ? true : 'Page folder name is required')
71
- });
72
- const pageFolder = String(pageFolderRaw ?? '').trim();
73
- targetDir = path.join(targetDir, pageFolder);
74
- }
75
- targetDir = path.join(targetDir, name);
76
- await fs.mkdir(targetDir, { recursive: true });
77
- await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
78
- await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
79
- await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
80
- await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
81
- console.log(`✅ Component generated: ${targetDir}`);
21
+ const workspace = await selectWorkspace();
22
+ if (!workspace)
23
+ return;
24
+ const { rawName } = await prompts({
25
+ type: 'text',
26
+ name: 'rawName',
27
+ message: 'Component name:',
28
+ validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
29
+ });
30
+ const { componentKind } = await prompts({
31
+ type: 'select',
32
+ name: 'componentKind',
33
+ message: 'Component kind:',
34
+ choices: [
35
+ { title: 'shared', value: 'shared' },
36
+ { title: 'layout', value: 'layout' },
37
+ { title: 'page', value: 'page' }
38
+ ],
39
+ initial: 0
40
+ });
41
+ const name = toPascalCase(String(rawName ?? 'Component')) || 'Component';
42
+ const propsName = `IComponent${name}Props`;
43
+ const kind = componentKind ?? 'shared';
44
+ let targetDir = path.join(workspace.path, 'Ui', 'Components', toPascalCase(kind));
45
+ if (kind === 'page') {
46
+ const { pageFolderRaw } = await prompts({
47
+ type: 'text',
48
+ name: 'pageFolderRaw',
49
+ message: 'Page folder name:',
50
+ validate: (value) => (String(value).trim().length > 0 ? true : 'Page folder name is required')
51
+ });
52
+ const pageFolder = toPascalCase(String(pageFolderRaw ?? 'Page')) || 'Page';
53
+ targetDir = path.join(targetDir, pageFolder);
54
+ }
55
+ targetDir = path.join(targetDir, name);
56
+ await fs.mkdir(targetDir, { recursive: true });
57
+ await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
58
+ await writeIfNotExists(path.join(targetDir, 'Style.scss'), '');
59
+ await writeIfNotExists(path.join(targetDir, 'Types.ts'), createTypesContent(propsName));
60
+ await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
61
+ console.log(`✅ Component generated: ${targetDir}`);
82
62
  }
@@ -2,58 +2,38 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import prompts from 'prompts';
4
4
  import { toPascalCase } from '../../utils/contextUtils.js';
5
- import { normalizeContexts } from '../../init/initAliases.js';
6
- import { loadUserConfig } from '../../utils/loadConfig.js';
5
+ import { selectWorkspace } from '../../utils/architecture.js';
7
6
  import { writeIfNotExists } from '../../utils/fileUtils.js';
8
7
  const createComponentContent = (propsName) => `<script lang="ts">
9
- import type { ${propsName} } from './types';
8
+ import type { ${propsName} } from './Types';
10
9
  const {}: ${propsName} = $props();
11
10
  </script>
12
11
  <!--Your HTML here-->
13
12
  <style lang="scss">
14
- \t@use './style';
13
+ \t@use './Style';
15
14
  </style>
16
15
  `;
17
16
  const createTypesContent = (propsName) => `export interface ${propsName} {}
18
17
  `;
19
18
  const createIndexContent = (name) => `export { default as ${name} } from './Component.svelte';
20
19
  `;
21
- const printContextsError = () => {
22
- console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
23
- };
24
- const selectContext = async () => {
25
- const config = await loadUserConfig();
26
- const contexts = normalizeContexts(config.contexts);
27
- if (!contexts.length) return null;
28
- const { context } = await prompts({
29
- type: 'select',
30
- name: 'context',
31
- message: 'Select context:',
32
- choices: contexts.map((item) => ({ title: item.name, value: item.name })),
33
- initial: 0
34
- });
35
- return context ? String(context) : null;
36
- };
37
20
  export default async function generateDesignComponent() {
38
- const context = await selectContext();
39
- if (!context) {
40
- printContextsError();
41
- process.exitCode = 1;
42
- return;
43
- }
44
- const { rawName } = await prompts({
45
- type: 'text',
46
- name: 'rawName',
47
- message: 'Design component name:',
48
- validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
49
- });
50
- const name = toPascalCase(String(rawName ?? 'DesignComponent')) || 'DesignComponent';
51
- const propsName = `IDesignComponent${name}Props`;
52
- const targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'design', name);
53
- await fs.mkdir(targetDir, { recursive: true });
54
- await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
55
- await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
56
- await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
57
- await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
58
- console.log(`✅ Design component generated: ${targetDir}`);
21
+ const workspace = await selectWorkspace();
22
+ if (!workspace)
23
+ return;
24
+ const { rawName } = await prompts({
25
+ type: 'text',
26
+ name: 'rawName',
27
+ message: 'Design component name:',
28
+ validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
29
+ });
30
+ const name = toPascalCase(String(rawName ?? 'DesignComponent')) || 'DesignComponent';
31
+ const propsName = `IDesignComponent${name}Props`;
32
+ const targetDir = path.join(workspace.path, 'Ui', 'Design', name);
33
+ await fs.mkdir(targetDir, { recursive: true });
34
+ await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
35
+ await writeIfNotExists(path.join(targetDir, 'Style.scss'), '');
36
+ await writeIfNotExists(path.join(targetDir, 'Types.ts'), createTypesContent(propsName));
37
+ await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
38
+ console.log(`✅ Design component generated: ${targetDir}`);
59
39
  }
@@ -2,58 +2,38 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import prompts from 'prompts';
4
4
  import { toPascalCase } from '../../utils/contextUtils.js';
5
- import { normalizeContexts } from '../../init/initAliases.js';
6
- import { loadUserConfig } from '../../utils/loadConfig.js';
5
+ import { selectWorkspace } from '../../utils/architecture.js';
7
6
  import { writeIfNotExists } from '../../utils/fileUtils.js';
8
7
  const createComponentContent = (propsName) => `<script lang="ts">
9
- import type { ${propsName} } from './types';
8
+ import type { ${propsName} } from './Types';
10
9
  const {}: ${propsName} = $props();
11
10
  </script>
12
11
  <!--Your HTML here-->
13
12
  <style lang="scss">
14
- \t@use './style';
13
+ \t@use './Style';
15
14
  </style>
16
15
  `;
17
16
  const createTypesContent = (propsName) => `export interface ${propsName} {}
18
17
  `;
19
18
  const createIndexContent = (name) => `export { default as ${name} } from './Component.svelte';
20
19
  `;
21
- const printContextsError = () => {
22
- console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
23
- };
24
- const selectContext = async () => {
25
- const config = await loadUserConfig();
26
- const contexts = normalizeContexts(config.contexts);
27
- if (!contexts.length) return null;
28
- const { context } = await prompts({
29
- type: 'select',
30
- name: 'context',
31
- message: 'Select context:',
32
- choices: contexts.map((item) => ({ title: item.name, value: item.name })),
33
- initial: 0
34
- });
35
- return context ? String(context) : null;
36
- };
37
20
  export default async function generateWidget() {
38
- const context = await selectContext();
39
- if (!context) {
40
- printContextsError();
41
- process.exitCode = 1;
42
- return;
43
- }
44
- const { rawName } = await prompts({
45
- type: 'text',
46
- name: 'rawName',
47
- message: 'Widget name:',
48
- validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
49
- });
50
- const name = toPascalCase(String(rawName ?? 'Widget')) || 'Widget';
51
- const propsName = `IWidget${name}Props`;
52
- const targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'widgets', name);
53
- await fs.mkdir(targetDir, { recursive: true });
54
- await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
55
- await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
56
- await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
57
- await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
58
- console.log(`✅ Widget generated: ${targetDir}`);
21
+ const workspace = await selectWorkspace();
22
+ if (!workspace)
23
+ return;
24
+ const { rawName } = await prompts({
25
+ type: 'text',
26
+ name: 'rawName',
27
+ message: 'Widget name:',
28
+ validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
29
+ });
30
+ const name = toPascalCase(String(rawName ?? 'Widget')) || 'Widget';
31
+ const propsName = `IWidget${name}Props`;
32
+ const targetDir = path.join(workspace.path, 'Ui', 'Widgets', name);
33
+ await fs.mkdir(targetDir, { recursive: true });
34
+ await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
35
+ await writeIfNotExists(path.join(targetDir, 'Style.scss'), '');
36
+ await writeIfNotExists(path.join(targetDir, 'Types.ts'), createTypesContent(propsName));
37
+ await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
38
+ console.log(`✅ Widget generated: ${targetDir}`);
59
39
  }
@@ -0,0 +1,67 @@
1
+ import prompts from 'prompts';
2
+ import { runGit } from './runGit.js';
3
+ export const commitTypes = [
4
+ { value: 'feat', title: '\u2728 feat: New feature' },
5
+ { value: 'fix', title: '\ud83d\udc1b fix: Bug fix' },
6
+ { value: 'docs', title: '\ud83d\udcdd docs: Documentation' },
7
+ { value: 'style', title: '\ud83c\udfa8 style: Formatting' },
8
+ { value: 'refactor', title: '\u267b\ufe0f refactor: Code restructuring' },
9
+ { value: 'perf', title: '\u26a1 perf: Performance' },
10
+ { value: 'test', title: '\u2705 test: Tests' },
11
+ { value: 'build', title: '\ud83d\udce6 build: Build system' },
12
+ { value: 'ci', title: '\ud83d\udc77 ci: Continuous integration' },
13
+ { value: 'chore', title: '\ud83d\udd27 chore: Maintenance' },
14
+ { value: 'patch', title: '\ud83d\udd27 patch: Patch release' },
15
+ { value: 'release', title: '\ud83d\ude80 release: Release' },
16
+ { value: 'revert', title: '\u23ea revert: Revert changes' }
17
+ ];
18
+ export class CommitCancelledError extends Error {
19
+ constructor() {
20
+ super('Commit cancelled.');
21
+ }
22
+ }
23
+ export function validateSubject(value) {
24
+ if (!value.trim())
25
+ return 'A subject is required';
26
+ if (/[\r\n\0]/.test(value))
27
+ return 'Subject must be a single line';
28
+ return Array.from(value.trim()).length <= 100 || 'Subject must be at most 100 characters';
29
+ }
30
+ export function formatCommitMessage(answers) {
31
+ if (!commitTypes.some(({ value }) => value === answers.type))
32
+ throw new Error('A conventional commit type is required');
33
+ const validation = validateSubject(answers.subject ?? '');
34
+ if (validation !== true)
35
+ throw new Error(validation);
36
+ const breaking = answers.breaking?.trim();
37
+ const parts = [
38
+ `${answers.type}(${commitTypes.find((item) => item.value === answers.type).title.split(' ')[0]})${breaking ? '!' : ''}: ${answers.subject.trim()}`,
39
+ answers.body?.trim(),
40
+ breaking ? `BREAKING CHANGE: ${breaking}` : undefined,
41
+ answers.footer?.trim()
42
+ ];
43
+ const message = parts.filter(Boolean).join('\n\n');
44
+ if (message.includes('\0'))
45
+ throw new Error('Commit message must not contain null bytes');
46
+ return message;
47
+ }
48
+ export default async function commit(dependencies = {}) {
49
+ const prompt = dependencies.prompt ?? prompts;
50
+ let cancelled = false;
51
+ const answers = await prompt([
52
+ { type: 'select', name: 'type', message: 'Commit type', choices: commitTypes },
53
+ { type: 'text', name: 'subject', message: 'Subject (required, at most 100 characters)', validate: validateSubject },
54
+ { type: 'text', name: 'body', message: 'Body (optional)' },
55
+ { type: 'text', name: 'breaking', message: 'Breaking changes (optional)' },
56
+ { type: 'text', name: 'footer', message: 'Footer / issue references (optional)' }
57
+ ], {
58
+ onCancel: () => {
59
+ cancelled = true;
60
+ return false;
61
+ }
62
+ });
63
+ if (cancelled || !answers.type || answers.subject === undefined)
64
+ throw new CommitCancelledError();
65
+ const message = formatCommitMessage(answers);
66
+ await (dependencies.git ?? runGit)(['commit', '-m', message]);
67
+ }
@@ -0,0 +1,19 @@
1
+ import checkProject from '../checks/checkProject.js';
2
+ import { loadUserConfig } from '../utils/loadConfig.js';
3
+ import commit from './commit.js';
4
+ import { runGit } from './runGit.js';
5
+ export default async function push(options = {}, dependencies = {}) {
6
+ const git = dependencies.git ?? runGit;
7
+ if (options.check !== false) {
8
+ const config = await (dependencies.loadConfig ?? loadUserConfig)();
9
+ if (config.runChecksBeforePush !== false) {
10
+ await (dependencies.checkProject ?? checkProject)();
11
+ // checkProject catches failures and communicates them through exitCode.
12
+ if (process.exitCode && process.exitCode !== '0')
13
+ throw new Error('Project checks failed; push stopped.');
14
+ }
15
+ }
16
+ await git(['add', '.']);
17
+ await commit({ prompt: dependencies.prompt, git });
18
+ await git(['push']);
19
+ }
@@ -0,0 +1,11 @@
1
+ import { spawn } from 'node:child_process';
2
+ export const runGit = (args) => new Promise((resolve, reject) => {
3
+ const child = spawn('git', args, { stdio: 'inherit', shell: false });
4
+ child.once('error', reject);
5
+ child.once('close', (code, signal) => {
6
+ if (code === 0)
7
+ resolve();
8
+ else
9
+ reject(new Error(`git ${args[0]} failed (${signal ? `signal ${signal}` : `exit ${code}`})`));
10
+ });
11
+ });
@@ -1,137 +1,21 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import { loadUserConfig } from '../utils/loadConfig.js';
4
- const svelteConfigPath = path.resolve('svelte.config.js');
5
- function normalizeAliasValue(value, fallbackName) {
6
- const raw = String(value ?? '').trim();
7
- if (!raw.length) return `$${fallbackName}`;
8
- return raw.startsWith('$') ? raw : `$${raw}`;
9
- }
10
- export function normalizeContexts(rawContexts) {
11
- if (!Array.isArray(rawContexts)) return [];
12
- return rawContexts
13
- .map((item) => {
14
- if (typeof item === 'string') {
15
- const name = item.trim();
16
- if (!name.length) return null;
17
- return { name, alias: `$${name}` };
18
- }
19
- if (!item || typeof item !== 'object') return null;
20
- const name = String(item.name ?? '').trim();
21
- if (!name.length) return null;
22
- return {
23
- name,
24
- alias: normalizeAliasValue(item.alias, name)
25
- };
26
- })
27
- .filter((item) => item !== null);
28
- }
29
- export function generateAliases(config) {
30
- const contexts = normalizeContexts(config.contexts);
31
- const entries = [];
32
- for (const context of contexts) {
33
- entries.push([context.alias, `./src/app/${context.name}`]);
34
- }
35
- return {
36
- contexts,
37
- aliases: Object.fromEntries(entries)
38
- };
39
- }
40
- function parseAliasEntries(aliasBody) {
41
- const entryRegex = /(['"`])([^'"`]+)\1\s*:\s*(['"`])([^'"`]+)\3\s*,?/g;
42
- const ordered = [];
43
- const map = new Map();
44
- let match;
45
- while ((match = entryRegex.exec(aliasBody)) !== null) {
46
- const key = match[2];
47
- const value = match[4];
48
- if (!key || !value) continue;
49
- if (!map.has(key)) {
50
- ordered.push(key);
51
- }
52
- map.set(key, value);
53
- }
54
- return { ordered, map };
55
- }
56
- function buildAliasEntriesString(orderedKeys, map, baseIndent) {
57
- if (!orderedKeys.length) return '';
58
- return orderedKeys.map((key) => `${baseIndent}'${key}': '${map.get(key) ?? ''}'`).join(',\n');
59
- }
60
- function removeAliasEntry(content, alias) {
61
- const escapedAlias = alias.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
62
- const aliasRegex = new RegExp(`\\n?\\s*['"\`]${escapedAlias}['"\`]\\s*:\\s*['"\`][^'"\`]+['"\`]\\s*,?`, 'g');
63
- return content.replace(aliasRegex, '');
64
- }
65
- const removeCoreAliasFromAzureNetConfig = async () => {
66
- const tsPath = path.resolve('azure-net.config.ts');
67
- const jsPath = path.resolve('azure-net.config.js');
68
- let filepath = null;
69
- try {
70
- await fs.access(tsPath);
71
- filepath = tsPath;
72
- } catch {
73
- try {
74
- await fs.access(jsPath);
75
- filepath = jsPath;
76
- } catch {
77
- return;
78
- }
79
- }
80
- const content = await fs.readFile(filepath, 'utf-8');
81
- if (!/coreAlias\s*:/.test(content)) return;
82
- const nextContent = content.replace(/\n?\s*coreAlias\s*:\s*['"`][^'"`]+['"`]\s*,?/m, '').replace(/,\s*\n\s*\}/m, '\n}');
83
- await fs.writeFile(filepath, nextContent, 'utf-8');
84
- };
85
- export function mergeAliasesInSvelteConfig(content, aliases) {
86
- const aliasRegex = /alias\s*:\s*\{([\s\S]*?)\}/m;
87
- const aliasMatch = content.match(aliasRegex);
88
- if (aliasMatch) {
89
- const aliasBody = aliasMatch[1] ?? '';
90
- const { ordered, map } = parseAliasEntries(aliasBody);
91
- map.delete('$core');
92
- for (const [key, value] of Object.entries(aliases)) {
93
- if (!map.has(key)) ordered.push(key);
94
- map.set(key, value);
95
- }
96
- const nextOrdered = ordered.filter((key) => key !== '$core');
97
- const baseIndentMatch = aliasBody.match(/\n(\s*)['"`]/);
98
- const baseIndent = baseIndentMatch?.[1] ?? '\t\t\t';
99
- const merged = buildAliasEntriesString(nextOrdered, map, baseIndent);
100
- const nextAliasBlock = `alias: {\n${merged}\n\t\t}`;
101
- return content.replace(aliasRegex, nextAliasBlock);
102
- }
103
- const kitRegex = /kit\s*:\s*\{/m;
104
- if (kitRegex.test(content)) {
105
- const aliasLines = Object.entries(aliases)
106
- .map(([key, value]) => `\t\t\t'${key}': '${value}'`)
107
- .join(',\n');
108
- const aliasBlock = `alias: {\n${aliasLines}\n\t\t},`;
109
- return content.replace(kitRegex, `kit: {\n\t\t${aliasBlock}`);
110
- }
111
- return `${content}\n\n// azure-net aliases\nconst alias = {\n${Object.entries(aliases)
112
- .map(([key, value]) => `\t'${key}': '${value}'`)
113
- .join(',\n')}\n};\n`;
114
- }
1
+ import { initializePackageImports } from '../utils/packageImports.js';
2
+ import { ARCHITECTURE_ALIASES, normalizePascalName } from '../utils/architecture.js';
3
+ /** Compatibility only: architecture discovery never reads configured contexts. */
4
+ export function normalizeContexts(raw) {
5
+ if (!Array.isArray(raw))
6
+ return [];
7
+ return raw.flatMap((item) => {
8
+ const value = typeof item === 'string' ? item : item?.name;
9
+ if (typeof value !== 'string' || !value.trim())
10
+ return [];
11
+ const name = normalizePascalName(value);
12
+ return [{ name, alias: `#contexts/${name}` }];
13
+ });
14
+ }
15
+ export function generateAliases() {
16
+ return { contexts: [], aliases: { ...ARCHITECTURE_ALIASES } };
17
+ }
18
+ export { mergeAliasesInSvelteConfig } from '../utils/legacyAliases.js';
115
19
  export default async function initAliases() {
116
- const config = await loadUserConfig();
117
- const sharedAlias = String(config.sharedAlias ?? '').trim();
118
- if (!sharedAlias.length) {
119
- console.error('❌ Cannot update aliases: `sharedAlias` is missing in azure-net.config.ts/js.');
120
- console.error("Add it first, for example: sharedAlias: '$shared-kernel'");
121
- process.exitCode = 1;
122
- return;
123
- }
124
- const generated = generateAliases(config);
125
- const aliases = generated.aliases;
126
- await removeCoreAliasFromAzureNetConfig();
127
- let content;
128
- try {
129
- content = await fs.readFile(svelteConfigPath, 'utf-8');
130
- } catch {
131
- console.warn('⚠️ svelte.config.js not found, aliases were not updated');
132
- return;
133
- }
134
- const nextContent = removeAliasEntry(mergeAliasesInSvelteConfig(content, aliases), '$core');
135
- await fs.writeFile(svelteConfigPath, nextContent, 'utf-8');
136
- console.log('✅ Aliases updated in svelte.config.js');
20
+ await initializePackageImports();
137
21
  }