@azure-net/cli 2.3.63 → 4.0.0-1

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 (117) hide show
  1. package/.prettierrc +7 -0
  2. package/bin/azure-net.js +278 -157
  3. package/bin/azure-net.ts +284 -0
  4. package/eslint.config.js +34 -0
  5. package/package.json +12 -5
  6. package/src/checks/checkDomain.js +201 -0
  7. package/src/checks/checkDomain.ts +213 -0
  8. package/src/checks/checkFoldersStructure.js +70 -0
  9. package/src/checks/checkFoldersStructure.ts +85 -0
  10. package/src/checks/checkInternal.js +35 -0
  11. package/src/checks/checkInternal.ts +40 -0
  12. package/src/checks/checkLayerBoundaries.js +178 -0
  13. package/src/checks/checkLayerBoundaries.ts +189 -0
  14. package/src/checks/checkPresenterNames.js +202 -0
  15. package/src/checks/checkPresenterNames.ts +208 -0
  16. package/src/checks/checkProject.js +42 -0
  17. package/src/checks/checkProject.ts +45 -0
  18. package/src/checks/checkProviderNames.js +158 -0
  19. package/src/checks/checkProviderNames.ts +165 -0
  20. package/src/checks/index.js +7 -0
  21. package/src/checks/index.ts +7 -0
  22. package/src/generate/layers/generateRepository.js +124 -0
  23. package/src/generate/layers/generateRepository.ts +123 -0
  24. package/src/generate/layers/generateRepositoryMethod.js +102 -0
  25. package/src/generate/layers/generateRepositoryMethod.ts +102 -0
  26. package/src/generate/layers/generateUseCases.js +50 -0
  27. package/src/generate/layers/generateUseCases.ts +50 -0
  28. package/src/generate/layers/repositoryShared.js +569 -0
  29. package/src/generate/layers/repositoryShared.ts +657 -0
  30. package/src/generate/module/generateDomain.js +146 -0
  31. package/src/generate/module/generateDomain.ts +147 -0
  32. package/src/generate/module/generateModule.js +84 -0
  33. package/src/generate/module/generateModule.ts +84 -0
  34. package/src/generate/module/generateModulePreset.js +307 -0
  35. package/src/generate/module/generateModulePreset.ts +337 -0
  36. package/src/generate/module/generatePresenter.js +419 -0
  37. package/src/generate/module/generatePresenter.ts +442 -0
  38. package/src/generate/module/generateRepository.js +144 -0
  39. package/src/generate/module/generateRepository.ts +158 -0
  40. package/src/generate/module/generateSchemaFromType.js +358 -0
  41. package/src/generate/module/generateSchemaFromType.ts +369 -0
  42. package/src/generate/module/generateTypesJson.js +252 -0
  43. package/src/generate/module/generateTypesJson.ts +259 -0
  44. package/src/generate/module/generateUseCases.js +67 -0
  45. package/src/generate/module/generateUseCases.ts +67 -0
  46. package/src/generate/module/repositoryModuleShared.js +598 -0
  47. package/src/generate/module/repositoryModuleShared.ts +661 -0
  48. package/src/generate/ui/generateComponent.js +98 -0
  49. package/src/generate/ui/generateComponent.ts +100 -0
  50. package/src/generate/ui/generateDesignComponent.js +71 -0
  51. package/src/generate/ui/generateDesignComponent.ts +71 -0
  52. package/src/generate/ui/generateWidget.js +71 -0
  53. package/src/generate/ui/generateWidget.ts +71 -0
  54. package/src/init/initAliases.js +159 -0
  55. package/src/init/initAliases.ts +167 -0
  56. package/src/init/initEdges.js +74 -0
  57. package/src/init/initEdges.ts +74 -0
  58. package/src/init/initStructure.js +122 -0
  59. package/src/init/initStructure.ts +124 -0
  60. package/src/install/installFresh.js +101 -0
  61. package/src/install/installFresh.ts +101 -0
  62. package/src/plugins/addLint.js +257 -0
  63. package/src/plugins/addLint.ts +274 -0
  64. package/src/plugins/index.js +1 -0
  65. package/src/plugins/index.ts +1 -0
  66. package/src/scaffolds/createCoreMiddleware.js +27 -0
  67. package/src/scaffolds/createCoreMiddleware.ts +27 -0
  68. package/src/scaffolds/createCoreSchema.js +141 -0
  69. package/src/scaffolds/createCoreSchema.ts +142 -0
  70. package/src/scaffolds/createDatasource.js +173 -0
  71. package/src/scaffolds/createDatasource.ts +175 -0
  72. package/src/scaffolds/createDatasourceProvider.js +164 -0
  73. package/src/scaffolds/createDatasourceProvider.ts +175 -0
  74. package/src/scaffolds/createMiddleware.js +105 -0
  75. package/src/scaffolds/createMiddleware.ts +105 -0
  76. package/src/scaffolds/createPresenterFactory.js +112 -0
  77. package/src/scaffolds/createPresenterFactory.ts +114 -0
  78. package/src/scaffolds/createResponse.js +64 -0
  79. package/src/scaffolds/createResponse.ts +64 -0
  80. package/src/scaffolds/createSchemaRule.js +40 -0
  81. package/src/scaffolds/createSchemaRule.ts +42 -0
  82. package/src/scaffolds/createTranslationManager.js +78 -0
  83. package/src/scaffolds/createTranslationManager.ts +78 -0
  84. package/src/scaffolds/index.js +9 -0
  85. package/src/scaffolds/index.ts +9 -0
  86. package/src/utils/contextUtils.js +56 -49
  87. package/src/utils/contextUtils.ts +89 -0
  88. package/src/utils/fileUtils.js +72 -84
  89. package/src/utils/fileUtils.ts +100 -0
  90. package/src/utils/loadConfig.js +57 -13
  91. package/src/utils/loadConfig.ts +69 -0
  92. package/tsconfig.json +19 -0
  93. package/src/commands/generate/generateComponent.js +0 -53
  94. package/src/commands/generate/generateCrudBase.js +0 -207
  95. package/src/commands/generate/generateCrudPresenter.js +0 -232
  96. package/src/commands/generate/generateDatasource.js +0 -84
  97. package/src/commands/generate/generateDesignComponent.js +0 -53
  98. package/src/commands/generate/generateModule.js +0 -31
  99. package/src/commands/generate/generateModuleBase.js +0 -152
  100. package/src/commands/generate/generateModulePresenter.js +0 -110
  101. package/src/commands/generate/generatePresenter.js +0 -86
  102. package/src/commands/generate/generateRepository.js +0 -76
  103. package/src/commands/generate/generateResponse.js +0 -41
  104. package/src/commands/generate/generateSchema.js +0 -96
  105. package/src/commands/generate/generateService.js +0 -71
  106. package/src/commands/generate/generateWidget.js +0 -53
  107. package/src/commands/generate/index.js +0 -14
  108. package/src/commands/init/index.js +0 -9
  109. package/src/commands/init/initAliases.js +0 -52
  110. package/src/commands/init/initEdges.js +0 -42
  111. package/src/commands/init/initLint.js +0 -138
  112. package/src/commands/init/initMiddleware.js +0 -21
  113. package/src/commands/init/initPresenter.js +0 -25
  114. package/src/commands/init/initSchema.js +0 -22
  115. package/src/commands/init/initStructure.js +0 -140
  116. package/src/commands/init/initTranslations.js +0 -59
  117. package/src/commands/init/migrateStructure.js +0 -144
@@ -0,0 +1,89 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import prompts from 'prompts';
4
+ import { loadUserConfig } from './loadConfig.js';
5
+
6
+ const APP_PATH = path.join(process.cwd(), 'src/app');
7
+ const CORE_PATH = path.join(process.cwd(), 'src/core');
8
+
9
+ function normalizeContextNames(rawContexts: unknown): string[] {
10
+ if (!Array.isArray(rawContexts)) return [];
11
+
12
+ return rawContexts
13
+ .map((item) => {
14
+ if (typeof item === 'string') {
15
+ return item.trim();
16
+ }
17
+ if (!item || typeof item !== 'object') return '';
18
+ return String(item.name ?? '').trim();
19
+ })
20
+ .filter(Boolean);
21
+ }
22
+
23
+ export async function selectContext(message = 'Select context:'): Promise<string | null> {
24
+ const config = await loadUserConfig();
25
+ const contexts = normalizeContextNames(config.contexts);
26
+
27
+ const { context } = await prompts({
28
+ type: 'select',
29
+ name: 'context',
30
+ message,
31
+ choices: [...contexts.map((c) => ({ title: c, value: c })), { title: 'core', value: 'core' }]
32
+ });
33
+
34
+ return context ? String(context) : null;
35
+ }
36
+
37
+ export function getContextPath(context: string): string {
38
+ return context === 'core' ? CORE_PATH : path.join(APP_PATH, context, 'layers');
39
+ }
40
+
41
+ export async function getAvailableFiles(dir: string, pattern = '.ts'): Promise<string[]> {
42
+ try {
43
+ const files = await fs.readdir(dir);
44
+ return files.filter((f) => f.endsWith(pattern) && f !== 'index.ts').map((f) => f.replace(pattern, ''));
45
+ } catch {
46
+ return [];
47
+ }
48
+ }
49
+
50
+ export async function getApplicationProviderServices(context: string): Promise<string[]> {
51
+ const contextPath = getContextPath(context);
52
+ const providerPath = path.join(contextPath, 'application/providers/ApplicationProvider.ts');
53
+
54
+ try {
55
+ const content = await fs.readFile(providerPath, 'utf-8');
56
+ // Extract service names from ApplicationProvider
57
+ const serviceRegex = /(\w+Service):\s*\(/g;
58
+ const services: string[] = [];
59
+ let match;
60
+
61
+ while ((match = serviceRegex.exec(content)) !== null) {
62
+ const serviceName = match[1];
63
+ if (serviceName) services.push(serviceName);
64
+ }
65
+
66
+ return services;
67
+ } catch {
68
+ return [];
69
+ }
70
+ }
71
+
72
+ export function toPascalCase(str: string): string {
73
+ return str
74
+ .split(/[-_\s]+/)
75
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
76
+ .join('');
77
+ }
78
+
79
+ export function toCamelCase(str: string): string {
80
+ const pascal = toPascalCase(str);
81
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
82
+ }
83
+
84
+ export function toKebabCase(str: string): string {
85
+ return str
86
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
87
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
88
+ .toLowerCase();
89
+ }
@@ -2,106 +2,94 @@ import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
 
4
4
  export async function writeIfNotExists(filepath, content) {
5
- try {
6
- await fs.access(filepath);
7
- console.log(`āš ļø Skip existing: ${filepath}`);
8
- return false;
9
- } catch {
10
- await fs.mkdir(path.dirname(filepath), { recursive: true });
11
- await fs.writeFile(filepath, content, 'utf-8');
12
- console.log(`āœ… Created: ${filepath}`);
13
- return true;
14
- }
5
+ try {
6
+ await fs.access(filepath);
7
+ console.log(`āš ļø Skip existing: ${filepath}`);
8
+ return false;
9
+ } catch {
10
+ await fs.mkdir(path.dirname(filepath), { recursive: true });
11
+ await fs.writeFile(filepath, content, 'utf-8');
12
+ console.log(`āœ… Created: ${filepath}`);
13
+ return true;
14
+ }
15
15
  }
16
16
 
17
17
  export async function updateIndexTs(dir, filePattern = '.ts', ignore = ['index.ts']) {
18
- try {
19
- const files = (await fs.readdir(dir)).filter(f =>
20
- f.endsWith(filePattern) && !ignore.includes(f)
21
- );
22
- const content = files
23
- .map(f => `export * from './${f.replace('.ts', '')}';`)
24
- .join('\n') + '\n';
25
- await fs.writeFile(path.join(dir, 'index.ts'), content, 'utf-8');
26
- } catch (error) {
27
- // Directory doesn't exist yet
28
- }
18
+ try {
19
+ const files = (await fs.readdir(dir)).filter((f) => f.endsWith(filePattern) && !ignore.includes(f));
20
+ const content = files.map((f) => `export * from './${f.replace('.ts', '')}';`).join('\n') + '\n';
21
+ await fs.writeFile(path.join(dir, 'index.ts'), content, 'utf-8');
22
+ } catch (error) {
23
+ // Directory doesn't exist yet
24
+ }
29
25
  }
30
26
 
31
27
  export async function updateCoreIndex() {
32
- const corePath = path.join(process.cwd(), 'src/core');
33
- try {
34
- const dirs = await fs.readdir(corePath, { withFileTypes: true });
35
- const validDirs = [];
28
+ const corePath = path.join(process.cwd(), 'src/core');
29
+ try {
30
+ const dirs = await fs.readdir(corePath, { withFileTypes: true });
31
+ const validDirs = [];
36
32
 
37
- for (const dir of dirs) {
38
- if (dir.isDirectory()) {
39
- // Check if directory has any files
40
- const dirPath = path.join(corePath, dir.name);
41
- const files = await fs.readdir(dirPath);
42
- if (files.length > 0) {
43
- validDirs.push(dir.name);
44
- }
45
- }
46
- }
33
+ for (const dir of dirs) {
34
+ if (dir.isDirectory()) {
35
+ // Check if directory has any files
36
+ const dirPath = path.join(corePath, dir.name);
37
+ const files = await fs.readdir(dirPath);
38
+ if (files.length > 0) {
39
+ validDirs.push(dir.name);
40
+ }
41
+ }
42
+ }
47
43
 
48
- if (validDirs.length > 0) {
49
- const content = validDirs
50
- .map(d => `export * from './${d}';`)
51
- .join('\n') + '\n';
52
- await fs.writeFile(path.join(corePath, 'index.ts'), content, 'utf-8');
53
- }
54
- } catch (error) {
55
- // Core directory doesn't exist
56
- }
44
+ if (validDirs.length > 0) {
45
+ const content = validDirs.map((d) => `export * from './${d}';`).join('\n') + '\n';
46
+ await fs.writeFile(path.join(corePath, 'index.ts'), content, 'utf-8');
47
+ }
48
+ } catch (error) {
49
+ // Core directory doesn't exist
50
+ }
57
51
  }
58
52
 
59
53
  export async function ensureIndexExports(layerPath) {
60
- try {
61
- const subdirs = await fs.readdir(layerPath, { withFileTypes: true });
62
- const exportLines = subdirs
63
- .filter(d => d.isDirectory())
64
- .map(d => `export * from './${d.name}';`);
54
+ try {
55
+ const subdirs = await fs.readdir(layerPath, { withFileTypes: true });
56
+ const exportLines = subdirs.filter((d) => d.isDirectory()).map((d) => `export * from './${d.name}';`);
65
57
 
66
- if (exportLines.length > 0) {
67
- await fs.writeFile(
68
- path.join(layerPath, 'index.ts'),
69
- exportLines.join('\n') + '\n',
70
- 'utf-8'
71
- );
72
- }
73
- } catch (error) {
74
- // Directory doesn't exist
75
- }
58
+ if (exportLines.length > 0) {
59
+ await fs.writeFile(path.join(layerPath, 'index.ts'), exportLines.join('\n') + '\n', 'utf-8');
60
+ }
61
+ } catch (error) {
62
+ // Directory doesn't exist
63
+ }
76
64
  }
77
65
 
78
66
  export async function injectIntoFile(filepath, searchPattern, newContent, position = 'after') {
79
- try {
80
- let content = await fs.readFile(filepath, 'utf-8');
81
- const index = content.indexOf(searchPattern);
67
+ try {
68
+ let content = await fs.readFile(filepath, 'utf-8');
69
+ const index = content.indexOf(searchPattern);
82
70
 
83
- if (index === -1) {
84
- console.warn(`Pattern not found in ${filepath}`);
85
- return false;
86
- }
71
+ if (index === -1) {
72
+ console.warn(`Pattern not found in ${filepath}`);
73
+ return false;
74
+ }
87
75
 
88
- if (content.includes(newContent.trim())) {
89
- console.log(`Content already exists in ${filepath}`);
90
- return false;
91
- }
76
+ if (content.includes(newContent.trim())) {
77
+ console.log(`Content already exists in ${filepath}`);
78
+ return false;
79
+ }
92
80
 
93
- if (position === 'after') {
94
- const insertIndex = index + searchPattern.length;
95
- content = content.slice(0, insertIndex) + '\n' + newContent + content.slice(insertIndex);
96
- } else {
97
- content = content.slice(0, index) + newContent + '\n' + content.slice(index);
98
- }
81
+ if (position === 'after') {
82
+ const insertIndex = index + searchPattern.length;
83
+ content = content.slice(0, insertIndex) + '\n' + newContent + content.slice(insertIndex);
84
+ } else {
85
+ content = content.slice(0, index) + newContent + '\n' + content.slice(index);
86
+ }
99
87
 
100
- await fs.writeFile(filepath, content, 'utf-8');
101
- console.log(`āœ… Updated: ${filepath}`);
102
- return true;
103
- } catch (error) {
104
- console.error(`Failed to update ${filepath}:`, error.message);
105
- return false;
106
- }
107
- }
88
+ await fs.writeFile(filepath, content, 'utf-8');
89
+ console.log(`āœ… Updated: ${filepath}`);
90
+ return true;
91
+ } catch (error) {
92
+ console.error(`Failed to update ${filepath}:`, error.message);
93
+ return false;
94
+ }
95
+ }
@@ -0,0 +1,100 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+
4
+ export async function writeIfNotExists(filepath: string, content: string): Promise<boolean> {
5
+ try {
6
+ await fs.access(filepath);
7
+ console.log(`āš ļø Skip existing: ${filepath}`);
8
+ return false;
9
+ } catch {
10
+ await fs.mkdir(path.dirname(filepath), { recursive: true });
11
+ await fs.writeFile(filepath, content, 'utf-8');
12
+ console.log(`āœ… Created: ${filepath}`);
13
+ return true;
14
+ }
15
+ }
16
+
17
+ export async function updateIndexTs(dir: string, filePattern = '.ts', ignore: string[] = ['index.ts']): Promise<void> {
18
+ try {
19
+ const files = (await fs.readdir(dir)).filter((f) => f.endsWith(filePattern) && !ignore.includes(f));
20
+ const content = files.map((f) => `export * from './${f.replace('.ts', '')}';`).join('\n') + '\n';
21
+ await fs.writeFile(path.join(dir, 'index.ts'), content, 'utf-8');
22
+ } catch {
23
+ // Directory doesn't exist yet
24
+ }
25
+ }
26
+
27
+ export async function updateCoreIndex(): Promise<void> {
28
+ const corePath = path.join(process.cwd(), 'src/core');
29
+ try {
30
+ const dirs = await fs.readdir(corePath, { withFileTypes: true });
31
+ const validDirs: string[] = [];
32
+
33
+ for (const dir of dirs) {
34
+ if (dir.isDirectory()) {
35
+ // Check if directory has any files
36
+ const dirPath = path.join(corePath, dir.name);
37
+ const files = await fs.readdir(dirPath);
38
+ if (files.length > 0) {
39
+ validDirs.push(dir.name);
40
+ }
41
+ }
42
+ }
43
+
44
+ if (validDirs.length > 0) {
45
+ const content = validDirs.map((d) => `export * from './${d}';`).join('\n') + '\n';
46
+ await fs.writeFile(path.join(corePath, 'index.ts'), content, 'utf-8');
47
+ }
48
+ } catch {
49
+ // Core directory doesn't exist
50
+ }
51
+ }
52
+
53
+ export async function ensureIndexExports(layerPath: string): Promise<void> {
54
+ try {
55
+ const subdirs = await fs.readdir(layerPath, { withFileTypes: true });
56
+ const exportLines = subdirs.filter((d) => d.isDirectory()).map((d) => `export * from './${d.name}';`);
57
+
58
+ if (exportLines.length > 0) {
59
+ await fs.writeFile(path.join(layerPath, 'index.ts'), exportLines.join('\n') + '\n', 'utf-8');
60
+ }
61
+ } catch {
62
+ // Directory doesn't exist
63
+ }
64
+ }
65
+
66
+ export async function injectIntoFile(
67
+ filepath: string,
68
+ searchPattern: string,
69
+ newContent: string,
70
+ position: 'after' | 'before' = 'after'
71
+ ): Promise<boolean> {
72
+ try {
73
+ let content = await fs.readFile(filepath, 'utf-8');
74
+ const index = content.indexOf(searchPattern);
75
+
76
+ if (index === -1) {
77
+ console.warn(`Pattern not found in ${filepath}`);
78
+ return false;
79
+ }
80
+
81
+ if (content.includes(newContent.trim())) {
82
+ console.log(`Content already exists in ${filepath}`);
83
+ return false;
84
+ }
85
+
86
+ if (position === 'after') {
87
+ const insertIndex = index + searchPattern.length;
88
+ content = content.slice(0, insertIndex) + '\n' + newContent + content.slice(insertIndex);
89
+ } else {
90
+ content = content.slice(0, index) + newContent + '\n' + content.slice(index);
91
+ }
92
+
93
+ await fs.writeFile(filepath, content, 'utf-8');
94
+ console.log(`āœ… Updated: ${filepath}`);
95
+ return true;
96
+ } catch (error: unknown) {
97
+ console.error(`Failed to update ${filepath}:`, error instanceof Error ? error.message : String(error));
98
+ return false;
99
+ }
100
+ }
@@ -1,15 +1,59 @@
1
- import path from 'path';
2
- import { pathToFileURL } from 'url';
1
+ import fs from 'node:fs/promises';
2
+ import fsSync from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ const DEFAULT_CONFIG = {
6
+ contexts: [],
7
+ defaultContext: 'web',
8
+ coreAlias: '$core'
9
+ };
10
+
11
+ function toObjectFromDefaultExport(content) {
12
+ const source = String(content ?? '').trim();
13
+ if (!source.length) return {};
14
+
15
+ const replacedExport = source.replace(/^\s*export\s+default\s+/m, 'return ');
16
+ if (replacedExport === source) return {};
17
+
18
+ const withSemicolon = /;\s*$/.test(replacedExport) ? replacedExport : `${replacedExport};`;
19
+
20
+ try {
21
+ // eslint-disable-next-line no-new-func
22
+ return new Function(withSemicolon)() ?? {};
23
+ } catch {
24
+ return {};
25
+ }
26
+ }
27
+
28
+ export function resolveConfigFile(cwd = process.cwd()) {
29
+ const tsPath = path.join(cwd, 'azure-net.config.ts');
30
+ const jsPath = path.join(cwd, 'azure-net.config.js');
31
+
32
+ if (fsSync.existsSync(tsPath)) {
33
+ return { exists: true, filepath: tsPath, type: 'ts' };
34
+ }
35
+ if (fsSync.existsSync(jsPath)) {
36
+ return { exists: true, filepath: jsPath, type: 'js' };
37
+ }
38
+
39
+ return { exists: false, filepath: tsPath, type: 'ts' };
40
+ }
3
41
 
4
42
  export async function loadUserConfig() {
5
- try {
6
- const configPath = path.resolve(process.cwd(), 'azure-net.config.js');
7
- const userConfig = await import(pathToFileURL(configPath));
8
- return userConfig.default || {};
9
- } catch {
10
- return {
11
- contexts: ['web'],
12
- defaultContext: 'web'
13
- };
14
- }
15
- }
43
+ const { exists, filepath } = resolveConfigFile();
44
+ if (!exists) {
45
+ return { ...DEFAULT_CONFIG };
46
+ }
47
+
48
+ try {
49
+ const content = await fs.readFile(filepath, 'utf-8');
50
+ const parsed = toObjectFromDefaultExport(content);
51
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
52
+ return { ...DEFAULT_CONFIG };
53
+ }
54
+
55
+ return { ...DEFAULT_CONFIG, ...parsed };
56
+ } catch {
57
+ return { ...DEFAULT_CONFIG };
58
+ }
59
+ }
@@ -0,0 +1,69 @@
1
+ import fs from 'node:fs/promises';
2
+ import fsSync from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ export type AzureNetConfig = {
6
+ contexts: Array<string | { name?: string; alias?: string }>;
7
+ defaultContext: string;
8
+ coreAlias: string;
9
+ sharedAlias?: string;
10
+ packageManager?: string;
11
+ defaultSchemaFactory?: string;
12
+ defaultPresenterFactory?: string;
13
+ [key: string]: unknown;
14
+ };
15
+
16
+ const DEFAULT_CONFIG: AzureNetConfig = {
17
+ contexts: [],
18
+ defaultContext: 'web',
19
+ coreAlias: '$core'
20
+ };
21
+
22
+ function toObjectFromDefaultExport(content: string): Record<string, unknown> {
23
+ const source = String(content ?? '').trim();
24
+ if (!source.length) return {};
25
+
26
+ const replacedExport = source.replace(/^\s*export\s+default\s+/m, 'return ');
27
+ if (replacedExport === source) return {};
28
+
29
+ const withSemicolon = /;\s*$/.test(replacedExport) ? replacedExport : `${replacedExport};`;
30
+
31
+ try {
32
+ return new Function(withSemicolon)() ?? {};
33
+ } catch {
34
+ return {};
35
+ }
36
+ }
37
+
38
+ export function resolveConfigFile(cwd = process.cwd()): { exists: boolean; filepath: string; type: 'ts' | 'js' } {
39
+ const tsPath = path.join(cwd, 'azure-net.config.ts');
40
+ const jsPath = path.join(cwd, 'azure-net.config.js');
41
+
42
+ if (fsSync.existsSync(tsPath)) {
43
+ return { exists: true, filepath: tsPath, type: 'ts' };
44
+ }
45
+ if (fsSync.existsSync(jsPath)) {
46
+ return { exists: true, filepath: jsPath, type: 'js' };
47
+ }
48
+
49
+ return { exists: false, filepath: tsPath, type: 'ts' };
50
+ }
51
+
52
+ export async function loadUserConfig(): Promise<AzureNetConfig> {
53
+ const { exists, filepath } = resolveConfigFile();
54
+ if (!exists) {
55
+ return { ...DEFAULT_CONFIG };
56
+ }
57
+
58
+ try {
59
+ const content = await fs.readFile(filepath, 'utf-8');
60
+ const parsed = toObjectFromDefaultExport(content);
61
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
62
+ return { ...DEFAULT_CONFIG };
63
+ }
64
+
65
+ return { ...DEFAULT_CONFIG, ...(parsed as Record<string, unknown>) };
66
+ } catch {
67
+ return { ...DEFAULT_CONFIG };
68
+ }
69
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "rootDir": ".",
7
+ "outDir": "dist",
8
+ "allowJs": true,
9
+ "checkJs": false,
10
+ "declaration": true,
11
+ "sourceMap": true,
12
+ "strict": true,
13
+ "noUncheckedIndexedAccess": true,
14
+ "esModuleInterop": true,
15
+ "skipLibCheck": true
16
+ },
17
+ "include": ["bin/**/*.ts", "src/**/*"],
18
+ "exclude": ["dist", "node_modules"]
19
+ }
@@ -1,53 +0,0 @@
1
- import prompts from 'prompts';
2
- import path from 'path';
3
- import { selectContext } from '../../utils/contextUtils.js';
4
- import { writeIfNotExists } from '../../utils/fileUtils.js';
5
-
6
- const componentTemplate = `<script lang="ts">
7
- \timport './style.scss';
8
- </script>
9
-
10
- {{componentName}}
11
- `;
12
-
13
- const styleTemplate = `// Add your styles here
14
- `;
15
-
16
- export default async function generateComponent() {
17
- const context = await selectContext('Select context for component:');
18
-
19
- const { componentPath } = await prompts({
20
- type: 'text',
21
- name: 'componentPath',
22
- message: 'Component path (e.g. reviews/modals/ReviewModal):',
23
- validate: value => value.length > 0 ? true : 'Path cannot be empty'
24
- });
25
-
26
- // Parse the path
27
- const normalizedPath = componentPath.replace(/\\/g, '/');
28
- const pathParts = normalizedPath.split('/');
29
- const componentName = pathParts[pathParts.length - 1];
30
-
31
- // Build the full path: src/app/{context}/ui/components/{path}
32
- const contextUiPath = path.join(process.cwd(), 'src/app', context, 'ui/components');
33
- const fullComponentPath = path.join(contextUiPath, normalizedPath);
34
-
35
- console.log(`\nšŸš€ Generating component: ${componentName}...\n`);
36
-
37
- // Create Component.svelte
38
- await writeIfNotExists(
39
- path.join(fullComponentPath, 'Component.svelte'),
40
- componentTemplate.replace(/{{componentName}}/g, componentName)
41
- );
42
-
43
- // Create style.scss
44
- await writeIfNotExists(
45
- path.join(fullComponentPath, 'style.scss'),
46
- styleTemplate
47
- );
48
-
49
- console.log(`āœ… Component created at: ${fullComponentPath}`);
50
- console.log(`\nšŸ’” Files created:`);
51
- console.log(` - Component.svelte`);
52
- console.log(` - style.scss`);
53
- }