@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.
- package/.prettierrc +7 -0
- package/bin/azure-net.js +278 -157
- package/bin/azure-net.ts +284 -0
- package/eslint.config.js +34 -0
- package/package.json +12 -5
- package/src/checks/checkDomain.js +201 -0
- package/src/checks/checkDomain.ts +213 -0
- package/src/checks/checkFoldersStructure.js +70 -0
- package/src/checks/checkFoldersStructure.ts +85 -0
- package/src/checks/checkInternal.js +35 -0
- package/src/checks/checkInternal.ts +40 -0
- package/src/checks/checkLayerBoundaries.js +178 -0
- package/src/checks/checkLayerBoundaries.ts +189 -0
- package/src/checks/checkPresenterNames.js +202 -0
- package/src/checks/checkPresenterNames.ts +208 -0
- package/src/checks/checkProject.js +42 -0
- package/src/checks/checkProject.ts +45 -0
- package/src/checks/checkProviderNames.js +158 -0
- package/src/checks/checkProviderNames.ts +165 -0
- package/src/checks/index.js +7 -0
- package/src/checks/index.ts +7 -0
- package/src/generate/layers/generateRepository.js +124 -0
- package/src/generate/layers/generateRepository.ts +123 -0
- package/src/generate/layers/generateRepositoryMethod.js +102 -0
- package/src/generate/layers/generateRepositoryMethod.ts +102 -0
- package/src/generate/layers/generateUseCases.js +50 -0
- package/src/generate/layers/generateUseCases.ts +50 -0
- package/src/generate/layers/repositoryShared.js +569 -0
- package/src/generate/layers/repositoryShared.ts +657 -0
- package/src/generate/module/generateDomain.js +146 -0
- package/src/generate/module/generateDomain.ts +147 -0
- package/src/generate/module/generateModule.js +84 -0
- package/src/generate/module/generateModule.ts +84 -0
- package/src/generate/module/generateModulePreset.js +307 -0
- package/src/generate/module/generateModulePreset.ts +337 -0
- package/src/generate/module/generatePresenter.js +419 -0
- package/src/generate/module/generatePresenter.ts +442 -0
- package/src/generate/module/generateRepository.js +144 -0
- package/src/generate/module/generateRepository.ts +158 -0
- package/src/generate/module/generateSchemaFromType.js +358 -0
- package/src/generate/module/generateSchemaFromType.ts +369 -0
- package/src/generate/module/generateTypesJson.js +252 -0
- package/src/generate/module/generateTypesJson.ts +259 -0
- package/src/generate/module/generateUseCases.js +67 -0
- package/src/generate/module/generateUseCases.ts +67 -0
- package/src/generate/module/repositoryModuleShared.js +598 -0
- package/src/generate/module/repositoryModuleShared.ts +661 -0
- package/src/generate/ui/generateComponent.js +98 -0
- package/src/generate/ui/generateComponent.ts +100 -0
- package/src/generate/ui/generateDesignComponent.js +71 -0
- package/src/generate/ui/generateDesignComponent.ts +71 -0
- package/src/generate/ui/generateWidget.js +71 -0
- package/src/generate/ui/generateWidget.ts +71 -0
- package/src/init/initAliases.js +159 -0
- package/src/init/initAliases.ts +167 -0
- package/src/init/initEdges.js +74 -0
- package/src/init/initEdges.ts +74 -0
- package/src/init/initStructure.js +122 -0
- package/src/init/initStructure.ts +124 -0
- package/src/install/installFresh.js +101 -0
- package/src/install/installFresh.ts +101 -0
- package/src/plugins/addLint.js +257 -0
- package/src/plugins/addLint.ts +274 -0
- package/src/plugins/index.js +1 -0
- package/src/plugins/index.ts +1 -0
- package/src/scaffolds/createCoreMiddleware.js +27 -0
- package/src/scaffolds/createCoreMiddleware.ts +27 -0
- package/src/scaffolds/createCoreSchema.js +141 -0
- package/src/scaffolds/createCoreSchema.ts +142 -0
- package/src/scaffolds/createDatasource.js +173 -0
- package/src/scaffolds/createDatasource.ts +175 -0
- package/src/scaffolds/createDatasourceProvider.js +164 -0
- package/src/scaffolds/createDatasourceProvider.ts +175 -0
- package/src/scaffolds/createMiddleware.js +105 -0
- package/src/scaffolds/createMiddleware.ts +105 -0
- package/src/scaffolds/createPresenterFactory.js +112 -0
- package/src/scaffolds/createPresenterFactory.ts +114 -0
- package/src/scaffolds/createResponse.js +64 -0
- package/src/scaffolds/createResponse.ts +64 -0
- package/src/scaffolds/createSchemaRule.js +40 -0
- package/src/scaffolds/createSchemaRule.ts +42 -0
- package/src/scaffolds/createTranslationManager.js +78 -0
- package/src/scaffolds/createTranslationManager.ts +78 -0
- package/src/scaffolds/index.js +9 -0
- package/src/scaffolds/index.ts +9 -0
- package/src/utils/contextUtils.js +56 -49
- package/src/utils/contextUtils.ts +89 -0
- package/src/utils/fileUtils.js +72 -84
- package/src/utils/fileUtils.ts +100 -0
- package/src/utils/loadConfig.js +57 -13
- package/src/utils/loadConfig.ts +69 -0
- package/tsconfig.json +19 -0
- package/src/commands/generate/generateComponent.js +0 -53
- package/src/commands/generate/generateCrudBase.js +0 -207
- package/src/commands/generate/generateCrudPresenter.js +0 -232
- package/src/commands/generate/generateDatasource.js +0 -84
- package/src/commands/generate/generateDesignComponent.js +0 -53
- package/src/commands/generate/generateModule.js +0 -31
- package/src/commands/generate/generateModuleBase.js +0 -152
- package/src/commands/generate/generateModulePresenter.js +0 -110
- package/src/commands/generate/generatePresenter.js +0 -86
- package/src/commands/generate/generateRepository.js +0 -76
- package/src/commands/generate/generateResponse.js +0 -41
- package/src/commands/generate/generateSchema.js +0 -96
- package/src/commands/generate/generateService.js +0 -71
- package/src/commands/generate/generateWidget.js +0 -53
- package/src/commands/generate/index.js +0 -14
- package/src/commands/init/index.js +0 -9
- package/src/commands/init/initAliases.js +0 -52
- package/src/commands/init/initEdges.js +0 -42
- package/src/commands/init/initLint.js +0 -138
- package/src/commands/init/initMiddleware.js +0 -21
- package/src/commands/init/initPresenter.js +0 -25
- package/src/commands/init/initSchema.js +0 -22
- package/src/commands/init/initStructure.js +0 -140
- package/src/commands/init/initTranslations.js +0 -59
- 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
|
+
}
|
package/src/utils/fileUtils.js
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
67
|
+
try {
|
|
68
|
+
let content = await fs.readFile(filepath, 'utf-8');
|
|
69
|
+
const index = content.indexOf(searchPattern);
|
|
82
70
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
71
|
+
if (index === -1) {
|
|
72
|
+
console.warn(`Pattern not found in ${filepath}`);
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
87
75
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
if (content.includes(newContent.trim())) {
|
|
77
|
+
console.log(`Content already exists in ${filepath}`);
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
92
80
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
+
}
|
package/src/utils/loadConfig.js
CHANGED
|
@@ -1,15 +1,59 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
}
|