@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
@@ -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
  }