@azure-net/cli 5.1.0 → 6.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +189 -0
  2. package/bin/azure-net.js +236 -221
  3. package/dist/bin/azure-net.d.ts +2 -0
  4. package/dist/src/checks/architecture.d.ts +20 -0
  5. package/dist/src/checks/checkDomain.d.ts +1 -0
  6. package/dist/src/checks/checkFoldersStructure.d.ts +1 -0
  7. package/dist/src/checks/checkHooks.d.ts +1 -0
  8. package/dist/src/checks/checkImports.d.ts +1 -0
  9. package/dist/src/checks/checkInternal.d.ts +1 -0
  10. package/dist/src/checks/checkLayerBoundaries.d.ts +1 -0
  11. package/dist/src/checks/checkLayerImports.d.ts +1 -0
  12. package/dist/src/checks/checkPresenterNames.d.ts +1 -0
  13. package/dist/src/checks/checkProject.d.ts +1 -0
  14. package/dist/src/checks/checkProviderGraph.d.ts +1 -0
  15. package/dist/src/checks/checkProviderNames.d.ts +1 -0
  16. package/dist/src/generate/layers/generateRepository.d.ts +1 -0
  17. package/dist/src/generate/layers/generateRepositoryMethod.d.ts +1 -0
  18. package/dist/src/generate/layers/generateUseCases.d.ts +1 -0
  19. package/dist/src/generate/module/generateDomain.d.ts +8 -0
  20. package/dist/src/generate/module/generateModule.d.ts +1 -0
  21. package/dist/src/generate/module/generateModulePreset.d.ts +1 -0
  22. package/dist/src/generate/module/generatePresenter.d.ts +29 -0
  23. package/dist/src/generate/module/generateRepository.d.ts +15 -0
  24. package/dist/src/generate/module/generateRepositoryMethod.d.ts +2 -0
  25. package/dist/src/generate/module/generateSchemaFromType.d.ts +9 -0
  26. package/dist/src/generate/module/generateStore.d.ts +1 -0
  27. package/dist/src/generate/module/generateTypesJson.d.ts +2 -0
  28. package/dist/src/generate/module/generateUseCases.d.ts +1 -0
  29. package/dist/src/generate/module/repositoryModuleShared.d.ts +89 -0
  30. package/dist/src/generate/routes/generateRoutes.d.ts +14 -0
  31. package/dist/src/generate/ui/generateComponent.d.ts +1 -0
  32. package/dist/src/generate/ui/generateDesignComponent.d.ts +1 -0
  33. package/dist/src/generate/ui/generateWidget.d.ts +1 -0
  34. package/dist/src/git/commit.d.ts +23 -0
  35. package/dist/src/git/push.d.ts +11 -0
  36. package/dist/src/git/runGit.d.ts +2 -0
  37. package/dist/src/init/initAliases.d.ts +12 -0
  38. package/dist/src/init/initEdges.d.ts +2 -0
  39. package/dist/src/init/initStructure.d.ts +1 -0
  40. package/dist/src/install/configureCommitTools.d.ts +1 -0
  41. package/dist/src/install/installFresh.d.ts +1 -0
  42. package/dist/src/migrate/migrate.d.ts +22 -0
  43. package/dist/src/migrate/presenters.d.ts +7 -0
  44. package/dist/src/plugins/addLint.d.ts +5 -0
  45. package/dist/src/scaffolds/createCoreSchema.d.ts +1 -0
  46. package/dist/src/scaffolds/createDatasource.d.ts +1 -0
  47. package/dist/src/scaffolds/createProgram.d.ts +1 -0
  48. package/dist/src/scaffolds/createResponse.d.ts +1 -0
  49. package/dist/src/scaffolds/createSchemaRule.d.ts +1 -0
  50. package/dist/src/scaffolds/createTranslationManager.d.ts +1 -0
  51. package/{src/scaffolds/index.ts → dist/src/scaffolds/index.d.ts} +0 -2
  52. package/dist/src/scaffolds/registerDatasource.d.ts +2 -0
  53. package/dist/src/scaffolds/updateDefaultFactoryConfig.d.ts +1 -0
  54. package/dist/src/utils/architecture.d.ts +31 -0
  55. package/dist/src/utils/contextUtils.d.ts +6 -0
  56. package/dist/src/utils/fileUtils.d.ts +5 -0
  57. package/dist/src/utils/flattenConfig.d.ts +2 -0
  58. package/dist/src/utils/legacyAliases.d.ts +1 -0
  59. package/dist/src/utils/loadConfig.d.ts +16 -0
  60. package/dist/src/utils/packageImports.d.ts +4 -0
  61. package/dist/src/utils/sharedFoundation.d.ts +20 -0
  62. package/dist/src/utils/viteConfig.d.ts +9 -0
  63. package/package.json +48 -36
  64. package/src/checks/architecture.js +154 -0
  65. package/src/checks/checkDomain.js +124 -154
  66. package/src/checks/checkFoldersStructure.js +64 -52
  67. package/src/checks/checkHooks.js +12 -12
  68. package/src/checks/checkImports.js +26 -142
  69. package/src/checks/checkInternal.js +27 -24
  70. package/src/checks/checkLayerBoundaries.js +22 -197
  71. package/src/checks/checkLayerImports.js +14 -134
  72. package/src/checks/checkPresenterNames.js +156 -143
  73. package/src/checks/checkProject.js +27 -26
  74. package/src/checks/checkProviderGraph.js +182 -166
  75. package/src/checks/checkProviderNames.js +123 -112
  76. package/src/generate/layers/generateRepository.js +1 -109
  77. package/src/generate/layers/generateRepositoryMethod.js +1 -90
  78. package/src/generate/layers/generateUseCases.js +1 -44
  79. package/src/generate/module/generateDomain.js +81 -105
  80. package/src/generate/module/generateModule.js +34 -68
  81. package/src/generate/module/generateModulePreset.js +188 -248
  82. package/src/generate/module/generatePresenter.js +441 -369
  83. package/src/generate/module/generateRepository.js +102 -121
  84. package/src/generate/module/generateRepositoryMethod.js +117 -0
  85. package/src/generate/module/generateSchemaFromType.js +283 -280
  86. package/src/generate/module/generateStore.js +41 -0
  87. package/src/generate/module/generateTypesJson.js +196 -195
  88. package/src/generate/module/generateUseCases.js +47 -55
  89. package/src/generate/module/repositoryModuleShared.js +480 -459
  90. package/src/generate/routes/generateRoutes.js +165 -174
  91. package/src/generate/ui/generateComponent.js +44 -64
  92. package/src/generate/ui/generateDesignComponent.js +21 -41
  93. package/src/generate/ui/generateWidget.js +21 -41
  94. package/src/git/commit.js +67 -0
  95. package/src/git/push.js +19 -0
  96. package/src/git/runGit.js +11 -0
  97. package/src/init/initAliases.js +19 -135
  98. package/src/init/initEdges.js +79 -54
  99. package/src/init/initStructure.js +31 -145
  100. package/src/install/configureCommitTools.js +1 -0
  101. package/src/install/installFresh.js +39 -68
  102. package/src/migrate/migrate.js +914 -0
  103. package/src/migrate/presenters.js +265 -0
  104. package/src/plugins/addLint.js +52 -219
  105. package/src/scaffolds/createCoreSchema.js +65 -91
  106. package/src/scaffolds/createDatasource.js +67 -101
  107. package/src/scaffolds/createProgram.js +8 -8
  108. package/src/scaffolds/createResponse.js +29 -29
  109. package/src/scaffolds/createSchemaRule.js +19 -19
  110. package/src/scaffolds/createTranslationManager.js +84 -37
  111. package/src/scaffolds/index.js +0 -2
  112. package/src/scaffolds/registerDatasource.js +59 -0
  113. package/src/scaffolds/updateDefaultFactoryConfig.js +31 -0
  114. package/src/utils/architecture.js +145 -0
  115. package/src/utils/contextUtils.js +32 -65
  116. package/src/utils/fileUtils.js +69 -50
  117. package/src/utils/flattenConfig.js +38 -0
  118. package/src/utils/legacyAliases.js +75 -0
  119. package/src/utils/loadConfig.js +76 -40
  120. package/src/utils/packageImports.js +63 -0
  121. package/src/utils/sharedFoundation.js +36 -42
  122. package/src/utils/viteConfig.js +295 -0
  123. package/.prettierrc +0 -7
  124. package/bin/azure-net.ts +0 -308
  125. package/eslint.config.js +0 -34
  126. package/src/checks/checkDomain.ts +0 -223
  127. package/src/checks/checkFoldersStructure.ts +0 -85
  128. package/src/checks/checkHooks.ts +0 -22
  129. package/src/checks/checkImports.ts +0 -193
  130. package/src/checks/checkInternal.ts +0 -48
  131. package/src/checks/checkLayerBoundaries.ts +0 -255
  132. package/src/checks/checkLayerImports.ts +0 -185
  133. package/src/checks/checkPresenterNames.ts +0 -203
  134. package/src/checks/checkProject.ts +0 -45
  135. package/src/checks/checkProviderGraph.ts +0 -234
  136. package/src/checks/checkProviderNames.ts +0 -165
  137. package/src/generate/layers/generateRepository.ts +0 -123
  138. package/src/generate/layers/generateRepositoryMethod.ts +0 -102
  139. package/src/generate/layers/generateUseCases.ts +0 -50
  140. package/src/generate/layers/repositoryShared.js +0 -506
  141. package/src/generate/layers/repositoryShared.ts +0 -662
  142. package/src/generate/module/generateDomain.ts +0 -147
  143. package/src/generate/module/generateModule.ts +0 -84
  144. package/src/generate/module/generateModulePreset.ts +0 -338
  145. package/src/generate/module/generatePresenter.ts +0 -498
  146. package/src/generate/module/generateRepository.ts +0 -158
  147. package/src/generate/module/generateSchemaFromType.ts +0 -368
  148. package/src/generate/module/generateTypesJson.ts +0 -259
  149. package/src/generate/module/generateUseCases.ts +0 -67
  150. package/src/generate/module/repositoryModuleShared.ts +0 -669
  151. package/src/generate/routes/generateRoutes.ts +0 -282
  152. package/src/generate/ui/generateComponent.ts +0 -100
  153. package/src/generate/ui/generateDesignComponent.ts +0 -71
  154. package/src/generate/ui/generateWidget.ts +0 -71
  155. package/src/init/initAliases.ts +0 -172
  156. package/src/init/initEdges.ts +0 -74
  157. package/src/init/initStructure.ts +0 -172
  158. package/src/install/installFresh.ts +0 -93
  159. package/src/plugins/addLint.ts +0 -274
  160. package/src/scaffolds/createCoreSchema.ts +0 -130
  161. package/src/scaffolds/createDatasource.ts +0 -161
  162. package/src/scaffolds/createDatasourceProvider.js +0 -127
  163. package/src/scaffolds/createDatasourceProvider.ts +0 -161
  164. package/src/scaffolds/createPresenterFactory.js +0 -83
  165. package/src/scaffolds/createPresenterFactory.ts +0 -102
  166. package/src/scaffolds/createProgram.ts +0 -19
  167. package/src/scaffolds/createResponse.ts +0 -66
  168. package/src/scaffolds/createSchemaRule.ts +0 -44
  169. package/src/scaffolds/createTranslationManager.ts +0 -80
  170. package/src/utils/contextUtils.ts +0 -88
  171. package/src/utils/fileUtils.ts +0 -74
  172. package/src/utils/loadConfig.ts +0 -68
  173. package/src/utils/sharedFoundation.ts +0 -70
  174. package/tsconfig.json +0 -19
  175. /package/{src/checks/index.ts → dist/src/checks/index.d.ts} +0 -0
  176. /package/{src/plugins/index.ts → dist/src/plugins/index.d.ts} +0 -0
@@ -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
  }
@@ -1,59 +1,84 @@
1
1
  import fs from 'node:fs/promises';
2
- import fsSync from 'node:fs';
3
2
  import path from 'node:path';
4
- const EDGES_IMPORT = `import { edgesPlugin } from '@azure-net/kit/edges/plugin';`;
5
- function resolveViteConfigPath() {
6
- const cwd = process.cwd();
7
- const candidates = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs', 'vite.config.cjs'].map((filename) => path.join(cwd, filename));
8
- for (const filepath of candidates) {
9
- if (fsSync.existsSync(filepath)) {
10
- return filepath;
11
- }
12
- }
13
- return null;
14
- }
15
- function injectEdgesImport(content) {
16
- if (content.includes(EDGES_IMPORT)) return content;
17
- const svelteImportRegex = /import\s+\{\s*sveltekit\s*\}\s+from\s+['"]@sveltejs\/kit\/vite['"]\s*;?/m;
18
- if (svelteImportRegex.test(content)) {
19
- return content.replace(svelteImportRegex, (line) => `${line}\n${EDGES_IMPORT}`);
20
- }
21
- return `${EDGES_IMPORT}\n${content}`;
22
- }
23
- function injectEdgesPlugin(content) {
24
- if (/edgesPlugin\s*\(\s*\)/.test(content)) return content;
25
- const pluginsRegex = /plugins\s*:\s*\[([\s\S]*?)\]/m;
26
- const pluginsMatch = content.match(pluginsRegex);
27
- if (!pluginsMatch) {
28
- throw new Error('plugins array was not found in vite.config');
29
- }
30
- const pluginsBody = pluginsMatch[1] ?? '';
31
- let nextPluginsBody = pluginsBody;
32
- if (/sveltekit\s*\(\s*\)/.test(pluginsBody)) {
33
- nextPluginsBody = pluginsBody.replace(/sveltekit\s*\(\s*\)\s*,?/, (matched) => {
34
- const hasComma = matched.trim().endsWith(',');
35
- return hasComma ? `${matched} edgesPlugin(),` : `${matched}, edgesPlugin()`;
36
- });
37
- } else {
38
- const trimmed = pluginsBody.trim();
39
- if (!trimmed.length) {
40
- nextPluginsBody = 'edgesPlugin()';
41
- } else {
42
- const withComma = /\s*,\s*$/.test(pluginsBody) ? pluginsBody : `${pluginsBody},`;
43
- nextPluginsBody = `${withComma} edgesPlugin()`;
44
- }
45
- }
46
- return content.replace(pluginsRegex, `plugins: [${nextPluginsBody}]`);
3
+ import ts from 'typescript';
4
+ import { VITE_CONFIGS, formatConfig, enableHydratable } from '../utils/viteConfig.js';
5
+ export function configureAzureNetPlugin(content) {
6
+ const source = ts.createSourceFile('vite.config.ts', content, ts.ScriptTarget.Latest, true);
7
+ const edits = [];
8
+ let pluginName = 'AzureNetPlugin';
9
+ let imported = false;
10
+ const legacyNames = new Set();
11
+ for (const statement of source.statements) {
12
+ if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier))
13
+ continue;
14
+ const bindings = statement.importClause?.namedBindings;
15
+ if (!bindings || !ts.isNamedImports(bindings))
16
+ continue;
17
+ if (statement.moduleSpecifier.text === '@azure-net/kit/plugin') {
18
+ for (const item of bindings.elements)
19
+ if ((item.propertyName?.text ?? item.name.text) === 'AzureNetPlugin') {
20
+ pluginName = item.name.text;
21
+ imported = true;
22
+ }
23
+ }
24
+ if (statement.moduleSpecifier.text === '@azure-net/kit/edges/plugin') {
25
+ for (const item of bindings.elements)
26
+ if ((item.propertyName?.text ?? item.name.text) === 'edgesPlugin')
27
+ legacyNames.add(item.name.text);
28
+ if (bindings.elements.some((item) => (item.propertyName?.text ?? item.name.text) !== 'edgesPlugin'))
29
+ throw new Error('Remove unsupported legacy edges/plugin imports from Vite config first.');
30
+ edits.push({ start: statement.getStart(source), end: statement.end, text: '' });
31
+ }
32
+ }
33
+ let plugins;
34
+ const visit = (node) => {
35
+ if (ts.isPropertyAssignment(node) &&
36
+ (ts.isIdentifier(node.name) || ts.isStringLiteral(node.name)) &&
37
+ node.name.text === 'plugins' &&
38
+ ts.isArrayLiteralExpression(node.initializer))
39
+ plugins ??= node.initializer;
40
+ ts.forEachChild(node, visit);
41
+ };
42
+ visit(source);
43
+ if (!plugins)
44
+ throw new Error('Cannot safely configure AzureNetPlugin: use a literal plugins array in vite.config.');
45
+ const existing = plugins.elements.some((element) => ts.isCallExpression(element) && ts.isIdentifier(element.expression) && element.expression.text === pluginName);
46
+ let replacedLegacy = false;
47
+ for (const element of plugins.elements) {
48
+ if (!ts.isCallExpression(element) || !ts.isIdentifier(element.expression) || !legacyNames.has(element.expression.text))
49
+ continue;
50
+ if (existing || replacedLegacy)
51
+ throw new Error('Both legacy and AzureNet plugins are configured. Remove the legacy plugin call first.');
52
+ edits.push({ start: element.getStart(source), end: element.end, text: `${pluginName}()` });
53
+ replacedLegacy = true;
54
+ }
55
+ if (!existing && !replacedLegacy) {
56
+ const last = plugins.elements.at(-1);
57
+ edits.push({ start: plugins.end - 1, end: plugins.end - 1, text: `\n${pluginName}()\n` });
58
+ if (last && !plugins.elements.hasTrailingComma)
59
+ edits.push({ start: last.end, end: last.end, text: ',' });
60
+ }
61
+ for (const edit of edits.sort((a, b) => b.start - a.start))
62
+ content = content.slice(0, edit.start) + edit.text + content.slice(edit.end);
63
+ if (!imported)
64
+ content = `import { AzureNetPlugin } from '@azure-net/kit/plugin';\n${content}`;
65
+ return enableHydratable(content);
47
66
  }
48
67
  export default async function initEdges() {
49
- const viteConfigPath = resolveViteConfigPath();
50
- if (!viteConfigPath) {
51
- console.error('❌ vite.config.(ts|js|mjs|cjs) was not found');
52
- return;
53
- }
54
- let content = await fs.readFile(viteConfigPath, 'utf-8');
55
- content = injectEdgesImport(content);
56
- content = injectEdgesPlugin(content);
57
- await fs.writeFile(viteConfigPath, content, 'utf-8');
58
- console.log(`✅ Edges plugin initialized in ${path.basename(viteConfigPath)}`);
68
+ for (const name of VITE_CONFIGS) {
69
+ const file = path.resolve(name);
70
+ let content;
71
+ try {
72
+ content = await fs.readFile(file, 'utf8');
73
+ }
74
+ catch (error) {
75
+ if (error.code === 'ENOENT')
76
+ continue;
77
+ throw error;
78
+ }
79
+ await fs.writeFile(file, await formatConfig(configureAzureNetPlugin(content), file));
80
+ console.log(`AzureNetPlugin configured in ${name}`);
81
+ return;
82
+ }
83
+ throw new Error('vite.config.(ts|js|mjs) was not found. Initialize a SvelteKit project first.');
59
84
  }