@azure-net/cli 2.3.62 → 4.0.0-0
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 +247 -157
- package/bin/azure-net.ts +253 -0
- package/eslint.config.js +19 -0
- package/package.json +12 -5
- package/src/commands/generate/generateCrudBase.js +95 -114
- package/src/commands/generate/generateCrudPresenter.js +135 -142
- package/src/commands/generate/generateModule.js +21 -21
- package/src/commands/generate/generateModuleBase.js +92 -114
- package/src/commands/generate/generateModulePresenter.js +73 -80
- package/src/commands/generate/generatePresenter.js +38 -44
- package/src/commands/generate/generateRepository.js +41 -47
- package/src/commands/generate/generateSchema.js +74 -70
- package/src/commands/generate/generateService.js +32 -37
- package/src/commands/generate/index.js +0 -5
- package/src/generate/layers/generateRepository.js +124 -0
- package/src/generate/layers/generateRepositoryMethod.js +102 -0
- package/src/generate/layers/generateUseCases.js +50 -0
- package/src/generate/layers/repositoryShared.js +569 -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/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 +320 -0
- package/src/generate/module/generateSchemaFromType.ts +325 -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/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/fileUtils.js +72 -84
- package/src/utils/loadConfig.js +57 -13
- package/tsconfig.json +19 -0
- package/src/commands/generate/generateComponent.js +0 -53
- package/src/commands/generate/generateDatasource.js +0 -84
- package/src/commands/generate/generateDesignComponent.js +0 -53
- package/src/commands/generate/generateResponse.js +0 -41
- package/src/commands/generate/generateWidget.js +0 -53
- 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,100 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import prompts from 'prompts';
|
|
4
|
+
import { toPascalCase } from '../../utils/contextUtils.js';
|
|
5
|
+
import { normalizeContexts } from '../../init/initAliases.js';
|
|
6
|
+
import { loadUserConfig } from '../../utils/loadConfig.js';
|
|
7
|
+
import { writeIfNotExists } from '../../utils/fileUtils.js';
|
|
8
|
+
|
|
9
|
+
type ComponentKind = 'shared' | 'layout' | 'page';
|
|
10
|
+
|
|
11
|
+
const createComponentContent = (propsName: string): string => `<script lang="ts">
|
|
12
|
+
import type { ${propsName} } from './types';
|
|
13
|
+
const {}: ${propsName} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
<!--Your HTML here-->
|
|
16
|
+
<style lang="scss">
|
|
17
|
+
\t@use './style';
|
|
18
|
+
</style>
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const createTypesContent = (propsName: string): string => `export interface ${propsName} {}
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
const createIndexContent = (name: string): string => `export { default as ${name} } from './Component.svelte';
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
const printContextsError = (): void => {
|
|
28
|
+
console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const selectContext = async (): Promise<string | null> => {
|
|
32
|
+
const config = await loadUserConfig();
|
|
33
|
+
const contexts = normalizeContexts(config.contexts);
|
|
34
|
+
if (!contexts.length) return null;
|
|
35
|
+
|
|
36
|
+
const { context } = await prompts({
|
|
37
|
+
type: 'select',
|
|
38
|
+
name: 'context',
|
|
39
|
+
message: 'Select context:',
|
|
40
|
+
choices: contexts.map((item) => ({ title: item.name, value: item.name })),
|
|
41
|
+
initial: 0
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return context ? String(context) : null;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default async function generateComponent(): Promise<void> {
|
|
48
|
+
const context = await selectContext();
|
|
49
|
+
if (!context) {
|
|
50
|
+
printContextsError();
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const { rawName } = await prompts({
|
|
56
|
+
type: 'text',
|
|
57
|
+
name: 'rawName',
|
|
58
|
+
message: 'Component name:',
|
|
59
|
+
validate: (value: string) => (String(value).trim().length > 0 ? true : 'Name is required')
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const { componentKind } = await prompts({
|
|
63
|
+
type: 'select',
|
|
64
|
+
name: 'componentKind',
|
|
65
|
+
message: 'Component kind:',
|
|
66
|
+
choices: [
|
|
67
|
+
{ title: 'shared', value: 'shared' },
|
|
68
|
+
{ title: 'layout', value: 'layout' },
|
|
69
|
+
{ title: 'page', value: 'page' }
|
|
70
|
+
],
|
|
71
|
+
initial: 0
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const name = toPascalCase(String(rawName ?? 'Component')) || 'Component';
|
|
75
|
+
const propsName = `IComponent${name}Props`;
|
|
76
|
+
const kind = (componentKind as ComponentKind) ?? 'shared';
|
|
77
|
+
let targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'components', kind);
|
|
78
|
+
|
|
79
|
+
if (kind === 'page') {
|
|
80
|
+
const { pageFolderRaw } = await prompts({
|
|
81
|
+
type: 'text',
|
|
82
|
+
name: 'pageFolderRaw',
|
|
83
|
+
message: 'Page folder name:',
|
|
84
|
+
validate: (value: string) => (String(value).trim().length > 0 ? true : 'Page folder name is required')
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const pageFolder = String(pageFolderRaw ?? '').trim();
|
|
88
|
+
targetDir = path.join(targetDir, pageFolder);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
targetDir = path.join(targetDir, name);
|
|
92
|
+
|
|
93
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
94
|
+
await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
|
|
95
|
+
await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
|
|
96
|
+
await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
|
|
97
|
+
await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
|
|
98
|
+
|
|
99
|
+
console.log(`✅ Component generated: ${targetDir}`);
|
|
100
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import prompts from 'prompts';
|
|
4
|
+
import { toPascalCase } from '../../utils/contextUtils.js';
|
|
5
|
+
import { normalizeContexts } from '../../init/initAliases.js';
|
|
6
|
+
import { loadUserConfig } from '../../utils/loadConfig.js';
|
|
7
|
+
import { writeIfNotExists } from '../../utils/fileUtils.js';
|
|
8
|
+
|
|
9
|
+
const createComponentContent = (propsName) => `<script lang="ts">
|
|
10
|
+
import type { ${propsName} } from './types';
|
|
11
|
+
const {}: ${propsName} = $props();
|
|
12
|
+
</script>
|
|
13
|
+
<!--Your HTML here-->
|
|
14
|
+
<style lang="scss">
|
|
15
|
+
\t@use './style';
|
|
16
|
+
</style>
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const createTypesContent = (propsName) => `export interface ${propsName} {}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const createIndexContent = (name) => `export { default as ${name} } from './Component.svelte';
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const printContextsError = () => {
|
|
26
|
+
console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const selectContext = async () => {
|
|
30
|
+
const config = await loadUserConfig();
|
|
31
|
+
const contexts = normalizeContexts(config.contexts);
|
|
32
|
+
if (!contexts.length) return null;
|
|
33
|
+
|
|
34
|
+
const { context } = await prompts({
|
|
35
|
+
type: 'select',
|
|
36
|
+
name: 'context',
|
|
37
|
+
message: 'Select context:',
|
|
38
|
+
choices: contexts.map((item) => ({ title: item.name, value: item.name })),
|
|
39
|
+
initial: 0
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return context ? String(context) : null;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default async function generateDesignComponent() {
|
|
46
|
+
const context = await selectContext();
|
|
47
|
+
if (!context) {
|
|
48
|
+
printContextsError();
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { rawName } = await prompts({
|
|
54
|
+
type: 'text',
|
|
55
|
+
name: 'rawName',
|
|
56
|
+
message: 'Design component name:',
|
|
57
|
+
validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const name = toPascalCase(String(rawName ?? 'DesignComponent')) || 'DesignComponent';
|
|
61
|
+
const propsName = `IDesignComponent${name}Props`;
|
|
62
|
+
const targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'design', name);
|
|
63
|
+
|
|
64
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
65
|
+
await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
|
|
66
|
+
await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
|
|
67
|
+
await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
|
|
68
|
+
await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
|
|
69
|
+
|
|
70
|
+
console.log(`✅ Design component generated: ${targetDir}`);
|
|
71
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import prompts from 'prompts';
|
|
4
|
+
import { toPascalCase } from '../../utils/contextUtils.js';
|
|
5
|
+
import { normalizeContexts } from '../../init/initAliases.js';
|
|
6
|
+
import { loadUserConfig } from '../../utils/loadConfig.js';
|
|
7
|
+
import { writeIfNotExists } from '../../utils/fileUtils.js';
|
|
8
|
+
|
|
9
|
+
const createComponentContent = (propsName: string): string => `<script lang="ts">
|
|
10
|
+
import type { ${propsName} } from './types';
|
|
11
|
+
const {}: ${propsName} = $props();
|
|
12
|
+
</script>
|
|
13
|
+
<!--Your HTML here-->
|
|
14
|
+
<style lang="scss">
|
|
15
|
+
\t@use './style';
|
|
16
|
+
</style>
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const createTypesContent = (propsName: string): string => `export interface ${propsName} {}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const createIndexContent = (name: string): string => `export { default as ${name} } from './Component.svelte';
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const printContextsError = (): void => {
|
|
26
|
+
console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const selectContext = async (): Promise<string | null> => {
|
|
30
|
+
const config = await loadUserConfig();
|
|
31
|
+
const contexts = normalizeContexts(config.contexts);
|
|
32
|
+
if (!contexts.length) return null;
|
|
33
|
+
|
|
34
|
+
const { context } = await prompts({
|
|
35
|
+
type: 'select',
|
|
36
|
+
name: 'context',
|
|
37
|
+
message: 'Select context:',
|
|
38
|
+
choices: contexts.map((item) => ({ title: item.name, value: item.name })),
|
|
39
|
+
initial: 0
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return context ? String(context) : null;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default async function generateDesignComponent(): Promise<void> {
|
|
46
|
+
const context = await selectContext();
|
|
47
|
+
if (!context) {
|
|
48
|
+
printContextsError();
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { rawName } = await prompts({
|
|
54
|
+
type: 'text',
|
|
55
|
+
name: 'rawName',
|
|
56
|
+
message: 'Design component name:',
|
|
57
|
+
validate: (value: string) => (String(value).trim().length > 0 ? true : 'Name is required')
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const name = toPascalCase(String(rawName ?? 'DesignComponent')) || 'DesignComponent';
|
|
61
|
+
const propsName = `IDesignComponent${name}Props`;
|
|
62
|
+
const targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'design', name);
|
|
63
|
+
|
|
64
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
65
|
+
await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
|
|
66
|
+
await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
|
|
67
|
+
await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
|
|
68
|
+
await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
|
|
69
|
+
|
|
70
|
+
console.log(`✅ Design component generated: ${targetDir}`);
|
|
71
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import prompts from 'prompts';
|
|
4
|
+
import { toPascalCase } from '../../utils/contextUtils.js';
|
|
5
|
+
import { normalizeContexts } from '../../init/initAliases.js';
|
|
6
|
+
import { loadUserConfig } from '../../utils/loadConfig.js';
|
|
7
|
+
import { writeIfNotExists } from '../../utils/fileUtils.js';
|
|
8
|
+
|
|
9
|
+
const createComponentContent = (propsName) => `<script lang="ts">
|
|
10
|
+
import type { ${propsName} } from './types';
|
|
11
|
+
const {}: ${propsName} = $props();
|
|
12
|
+
</script>
|
|
13
|
+
<!--Your HTML here-->
|
|
14
|
+
<style lang="scss">
|
|
15
|
+
\t@use './style';
|
|
16
|
+
</style>
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const createTypesContent = (propsName) => `export interface ${propsName} {}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const createIndexContent = (name) => `export { default as ${name} } from './Component.svelte';
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const printContextsError = () => {
|
|
26
|
+
console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const selectContext = async () => {
|
|
30
|
+
const config = await loadUserConfig();
|
|
31
|
+
const contexts = normalizeContexts(config.contexts);
|
|
32
|
+
if (!contexts.length) return null;
|
|
33
|
+
|
|
34
|
+
const { context } = await prompts({
|
|
35
|
+
type: 'select',
|
|
36
|
+
name: 'context',
|
|
37
|
+
message: 'Select context:',
|
|
38
|
+
choices: contexts.map((item) => ({ title: item.name, value: item.name })),
|
|
39
|
+
initial: 0
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return context ? String(context) : null;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default async function generateWidget() {
|
|
46
|
+
const context = await selectContext();
|
|
47
|
+
if (!context) {
|
|
48
|
+
printContextsError();
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { rawName } = await prompts({
|
|
54
|
+
type: 'text',
|
|
55
|
+
name: 'rawName',
|
|
56
|
+
message: 'Widget name:',
|
|
57
|
+
validate: (value) => (String(value).trim().length > 0 ? true : 'Name is required')
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const name = toPascalCase(String(rawName ?? 'Widget')) || 'Widget';
|
|
61
|
+
const propsName = `IWidget${name}Props`;
|
|
62
|
+
const targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'widgets', name);
|
|
63
|
+
|
|
64
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
65
|
+
await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
|
|
66
|
+
await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
|
|
67
|
+
await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
|
|
68
|
+
await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
|
|
69
|
+
|
|
70
|
+
console.log(`✅ Widget generated: ${targetDir}`);
|
|
71
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import prompts from 'prompts';
|
|
4
|
+
import { toPascalCase } from '../../utils/contextUtils.js';
|
|
5
|
+
import { normalizeContexts } from '../../init/initAliases.js';
|
|
6
|
+
import { loadUserConfig } from '../../utils/loadConfig.js';
|
|
7
|
+
import { writeIfNotExists } from '../../utils/fileUtils.js';
|
|
8
|
+
|
|
9
|
+
const createComponentContent = (propsName: string): string => `<script lang="ts">
|
|
10
|
+
import type { ${propsName} } from './types';
|
|
11
|
+
const {}: ${propsName} = $props();
|
|
12
|
+
</script>
|
|
13
|
+
<!--Your HTML here-->
|
|
14
|
+
<style lang="scss">
|
|
15
|
+
\t@use './style';
|
|
16
|
+
</style>
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const createTypesContent = (propsName: string): string => `export interface ${propsName} {}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const createIndexContent = (name: string): string => `export { default as ${name} } from './Component.svelte';
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const printContextsError = (): void => {
|
|
26
|
+
console.error('❌ Cannot generate UI artifact: `contexts` is missing or empty in azure-net.config.ts/js');
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const selectContext = async (): Promise<string | null> => {
|
|
30
|
+
const config = await loadUserConfig();
|
|
31
|
+
const contexts = normalizeContexts(config.contexts);
|
|
32
|
+
if (!contexts.length) return null;
|
|
33
|
+
|
|
34
|
+
const { context } = await prompts({
|
|
35
|
+
type: 'select',
|
|
36
|
+
name: 'context',
|
|
37
|
+
message: 'Select context:',
|
|
38
|
+
choices: contexts.map((item) => ({ title: item.name, value: item.name })),
|
|
39
|
+
initial: 0
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return context ? String(context) : null;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default async function generateWidget(): Promise<void> {
|
|
46
|
+
const context = await selectContext();
|
|
47
|
+
if (!context) {
|
|
48
|
+
printContextsError();
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { rawName } = await prompts({
|
|
54
|
+
type: 'text',
|
|
55
|
+
name: 'rawName',
|
|
56
|
+
message: 'Widget name:',
|
|
57
|
+
validate: (value: string) => (String(value).trim().length > 0 ? true : 'Name is required')
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const name = toPascalCase(String(rawName ?? 'Widget')) || 'Widget';
|
|
61
|
+
const propsName = `IWidget${name}Props`;
|
|
62
|
+
const targetDir = path.join(process.cwd(), 'src', 'app', context, 'ui', 'widgets', name);
|
|
63
|
+
|
|
64
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
65
|
+
await writeIfNotExists(path.join(targetDir, 'Component.svelte'), createComponentContent(propsName));
|
|
66
|
+
await writeIfNotExists(path.join(targetDir, 'style.scss'), '');
|
|
67
|
+
await writeIfNotExists(path.join(targetDir, 'types.ts'), createTypesContent(propsName));
|
|
68
|
+
await writeIfNotExists(path.join(targetDir, 'index.ts'), createIndexContent(name));
|
|
69
|
+
|
|
70
|
+
console.log(`✅ Widget generated: ${targetDir}`);
|
|
71
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { loadUserConfig, resolveConfigFile } from '../utils/loadConfig.js';
|
|
4
|
+
|
|
5
|
+
const svelteConfigPath = path.resolve('svelte.config.js');
|
|
6
|
+
|
|
7
|
+
function normalizeAliasValue(value, fallbackName) {
|
|
8
|
+
const raw = String(value ?? '').trim();
|
|
9
|
+
if (!raw.length) return `$${fallbackName}`;
|
|
10
|
+
return raw.startsWith('$') ? raw : `$${raw}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function normalizeContexts(rawContexts) {
|
|
14
|
+
if (!Array.isArray(rawContexts)) return [];
|
|
15
|
+
|
|
16
|
+
return rawContexts
|
|
17
|
+
.map((item) => {
|
|
18
|
+
if (typeof item === 'string') {
|
|
19
|
+
const name = item.trim();
|
|
20
|
+
if (!name.length) return null;
|
|
21
|
+
return { name, alias: `$${name}` };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!item || typeof item !== 'object') return null;
|
|
25
|
+
|
|
26
|
+
const name = String(item.name ?? '').trim();
|
|
27
|
+
if (!name.length) return null;
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
name,
|
|
31
|
+
alias: normalizeAliasValue(item.alias, name)
|
|
32
|
+
};
|
|
33
|
+
})
|
|
34
|
+
.filter(Boolean);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function generateAliases(config) {
|
|
38
|
+
const coreAlias = normalizeAliasValue(config.coreAlias, 'core');
|
|
39
|
+
const contexts = normalizeContexts(config.contexts);
|
|
40
|
+
|
|
41
|
+
const entries = [];
|
|
42
|
+
for (const context of contexts) {
|
|
43
|
+
entries.push([context.alias, `./src/app/${context.name}`]);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
entries.push([coreAlias, './src/core']);
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
coreAlias,
|
|
50
|
+
contexts,
|
|
51
|
+
aliases: Object.fromEntries(entries)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function parseAliasEntries(aliasBody) {
|
|
56
|
+
const entryRegex = /(['"`])([^'"`]+)\1\s*:\s*(['"`])([^'"`]+)\3\s*,?/g;
|
|
57
|
+
const ordered = [];
|
|
58
|
+
const map = new Map();
|
|
59
|
+
let match;
|
|
60
|
+
|
|
61
|
+
while ((match = entryRegex.exec(aliasBody)) !== null) {
|
|
62
|
+
const key = match[2];
|
|
63
|
+
const value = match[4];
|
|
64
|
+
if (!map.has(key)) {
|
|
65
|
+
ordered.push(key);
|
|
66
|
+
}
|
|
67
|
+
map.set(key, value);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { ordered, map };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function buildAliasEntriesString(orderedKeys, map, baseIndent) {
|
|
74
|
+
if (!orderedKeys.length) return '';
|
|
75
|
+
|
|
76
|
+
return orderedKeys.map((key) => `${baseIndent}'${key}': '${map.get(key)}'`).join(',\n');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function mergeAliasesInSvelteConfig(content, aliases) {
|
|
80
|
+
const aliasRegex = /alias\s*:\s*\{([\s\S]*?)\}/m;
|
|
81
|
+
const aliasMatch = content.match(aliasRegex);
|
|
82
|
+
|
|
83
|
+
if (aliasMatch) {
|
|
84
|
+
const aliasBody = aliasMatch[1] ?? '';
|
|
85
|
+
const { ordered, map } = parseAliasEntries(aliasBody);
|
|
86
|
+
for (const [key, value] of Object.entries(aliases)) {
|
|
87
|
+
if (!map.has(key)) ordered.push(key);
|
|
88
|
+
map.set(key, value);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const baseIndentMatch = aliasBody.match(/\n(\s*)['"`]/);
|
|
92
|
+
const baseIndent = baseIndentMatch?.[1] ?? '\t\t\t';
|
|
93
|
+
const merged = buildAliasEntriesString(ordered, map, baseIndent);
|
|
94
|
+
const nextAliasBlock = `alias: {\n${merged}\n\t\t}`;
|
|
95
|
+
return content.replace(aliasRegex, nextAliasBlock);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const kitRegex = /kit\s*:\s*\{/m;
|
|
99
|
+
if (kitRegex.test(content)) {
|
|
100
|
+
const aliasLines = Object.entries(aliases)
|
|
101
|
+
.map(([key, value]) => `\t\t\t'${key}': '${value}'`)
|
|
102
|
+
.join(',\n');
|
|
103
|
+
const aliasBlock = `alias: {\n${aliasLines}\n\t\t},`;
|
|
104
|
+
return content.replace(kitRegex, `kit: {\n\t\t${aliasBlock}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return `${content}\n\n// azure-net aliases\nconst alias = {\n${Object.entries(aliases)
|
|
108
|
+
.map(([key, value]) => `\t'${key}': '${value}'`)
|
|
109
|
+
.join(',\n')}\n};\n`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function upsertCoreAlias(content, coreAlias) {
|
|
113
|
+
const exportDefaultRegex = /export\s+default\s*\{([\s\S]*)\}\s*;?/m;
|
|
114
|
+
if (!exportDefaultRegex.test(content)) {
|
|
115
|
+
return `export default {\n\tcoreAlias: '${coreAlias}'\n};\n`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (/coreAlias\s*:/.test(content)) {
|
|
119
|
+
return content.replace(/coreAlias\s*:\s*['"`][^'"`]+['"`]/, `coreAlias: '${coreAlias}'`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return content.replace(exportDefaultRegex, (_full, body) => {
|
|
123
|
+
const trimmed = body.replace(/\s*$/, '');
|
|
124
|
+
if (!trimmed.length) {
|
|
125
|
+
return `export default {\n\tcoreAlias: '${coreAlias}'\n};`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const withComma = trimmed.endsWith(',') ? trimmed : `${trimmed},`;
|
|
129
|
+
return `export default {${withComma}\n\tcoreAlias: '${coreAlias}'\n};`;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function ensureCoreAliasInConfig(coreAlias) {
|
|
134
|
+
const { exists, filepath } = resolveConfigFile();
|
|
135
|
+
const aliasToSave = normalizeAliasValue(coreAlias, 'core');
|
|
136
|
+
const currentContent = exists ? await fs.readFile(filepath, 'utf-8') : '';
|
|
137
|
+
const nextContent = upsertCoreAlias(currentContent, aliasToSave);
|
|
138
|
+
await fs.writeFile(filepath, nextContent, 'utf-8');
|
|
139
|
+
return aliasToSave;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export default async function initAliases() {
|
|
143
|
+
const config = await loadUserConfig();
|
|
144
|
+
const generated = generateAliases(config);
|
|
145
|
+
const actualCoreAlias = await ensureCoreAliasInConfig(generated.coreAlias);
|
|
146
|
+
const aliases = { ...generated.aliases, [actualCoreAlias]: './src/core' };
|
|
147
|
+
|
|
148
|
+
let content;
|
|
149
|
+
try {
|
|
150
|
+
content = await fs.readFile(svelteConfigPath, 'utf-8');
|
|
151
|
+
} catch {
|
|
152
|
+
console.warn('⚠️ svelte.config.js not found, aliases were not updated');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const nextContent = mergeAliasesInSvelteConfig(content, aliases);
|
|
157
|
+
await fs.writeFile(svelteConfigPath, nextContent, 'utf-8');
|
|
158
|
+
console.log('✅ Aliases updated in svelte.config.js');
|
|
159
|
+
}
|