@azure-net/cli 1.3.0 → 1.3.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/bin/azure-net.js
CHANGED
|
@@ -5,6 +5,7 @@ import generateRepository from '../src/commands/generateCrudRepo.js';
|
|
|
5
5
|
import generateCrud from '../src/commands/generateCrud.js';
|
|
6
6
|
import initLint from '../src/commands/initLint.js';
|
|
7
7
|
import initStructure from '../src/commands/generateStructure.js';
|
|
8
|
+
import initAliases from '../src/commands/initAliases.js';
|
|
8
9
|
|
|
9
10
|
const program = new Command();
|
|
10
11
|
|
|
@@ -32,4 +33,9 @@ program
|
|
|
32
33
|
.description('Generate base folder structure based on config')
|
|
33
34
|
.action(initStructure);
|
|
34
35
|
|
|
36
|
+
program
|
|
37
|
+
.command('init:aliases')
|
|
38
|
+
.description('Generate alias mappings for modules or default architecture')
|
|
39
|
+
.action(initAliases);
|
|
40
|
+
|
|
35
41
|
program.parse();
|
package/package.json
CHANGED
|
@@ -17,98 +17,83 @@ async function writeIfNotExists(filepath, content) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
async function updateIndexTs(dir, filePattern = '.ts', ignore = ['index.ts']) {
|
|
21
|
+
const files = (await fs.readdir(dir)).filter(f => f.endsWith(filePattern) && !ignore.includes(f));
|
|
22
|
+
const content = files.map(f => `export * from './${f.replace('.ts', '')}';`).join('\n') + '\n';
|
|
23
|
+
await fs.writeFile(path.join(dir, 'index.ts'), content, 'utf-8');
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
export default async function generateCrud() {
|
|
21
27
|
const config = await loadUserConfig();
|
|
22
28
|
|
|
23
29
|
const answers = await prompts([
|
|
30
|
+
config.modules?.length
|
|
31
|
+
? {
|
|
32
|
+
type: 'select',
|
|
33
|
+
name: 'module',
|
|
34
|
+
message: 'Select target module:',
|
|
35
|
+
choices: config.modules.map(m => ({ title: m, value: m }))
|
|
36
|
+
}
|
|
37
|
+
: null,
|
|
24
38
|
{ type: 'text', name: 'className', message: 'Class name (PascalCase):' },
|
|
25
39
|
{ type: 'text', name: 'endpoint', message: 'API endpoint:' },
|
|
26
40
|
{ type: 'text', name: 'datasource', message: 'Datasource name:', initial: 'BaseDatasource' }
|
|
27
|
-
]);
|
|
41
|
+
].filter(Boolean));
|
|
28
42
|
|
|
29
43
|
const rawName = answers.className.trim();
|
|
30
44
|
const capital = rawName[0].toUpperCase() + rawName.slice(1);
|
|
31
45
|
const lower = rawName[0].toLowerCase() + rawName.slice(1);
|
|
32
46
|
const endpoint = answers.endpoint.trim();
|
|
33
47
|
const datasource = answers.datasource.trim();
|
|
48
|
+
const selectedModule = answers.module;
|
|
34
49
|
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const repoPath = path.join(process.cwd(), config.output.repo);
|
|
50
|
+
const baseArch = path.join(process.cwd(), 'src/app/context');
|
|
51
|
+
const basePath = selectedModule ? path.join(baseArch, selectedModule) : baseArch;
|
|
38
52
|
|
|
39
|
-
|
|
53
|
+
const domainPath = path.join(basePath, 'domain', lower);
|
|
54
|
+
const serviceDir = path.join(basePath, 'application', 'services');
|
|
55
|
+
const repoPath = path.join(basePath, 'infra', 'repo');
|
|
56
|
+
|
|
57
|
+
// === 1) Abstracts
|
|
40
58
|
const abstractsDir = path.join(domainPath, 'abstracts');
|
|
41
59
|
for (const file of ['Class', 'ClassCreateRequest', 'ClassUpdateRequest']) {
|
|
42
60
|
const tpl = await fs.readFile(path.join(__dirname, `../templates/domain/abstracts/${file}.ejs`), 'utf-8');
|
|
43
61
|
const result = ejs.render(tpl, { className: capital });
|
|
44
62
|
await writeIfNotExists(path.join(abstractsDir, `${capital}${file.replace('Class', '')}.ts`), result);
|
|
45
63
|
}
|
|
46
|
-
await
|
|
47
|
-
path.join(abstractsDir, `index.ts`),
|
|
48
|
-
[
|
|
49
|
-
`export * from './${capital}';`,
|
|
50
|
-
`export * from './${capital}CreateRequest';`,
|
|
51
|
-
`export * from './${capital}UpdateRequest';`
|
|
52
|
-
].join('\n')
|
|
53
|
-
);
|
|
64
|
+
await updateIndexTs(abstractsDir);
|
|
54
65
|
|
|
55
|
-
// 2) Request
|
|
66
|
+
// === 2) Request
|
|
56
67
|
const requestDir = path.join(domainPath, 'request');
|
|
57
68
|
for (const file of ['ClassCreateRequest', 'ClassUpdateRequest']) {
|
|
58
69
|
const tpl = await fs.readFile(path.join(__dirname, `../templates/domain/request/${file}.ejs`), 'utf-8');
|
|
59
70
|
const result = ejs.render(tpl, { className: capital });
|
|
60
71
|
await writeIfNotExists(path.join(requestDir, `${capital}${file.replace('Class', '')}.ts`), result);
|
|
61
72
|
}
|
|
62
|
-
await
|
|
63
|
-
path.join(requestDir, `index.ts`),
|
|
64
|
-
[
|
|
65
|
-
`export * from './${capital}CreateRequest';`,
|
|
66
|
-
`export * from './${capital}UpdateRequest';`
|
|
67
|
-
].join('\n')
|
|
68
|
-
);
|
|
73
|
+
await updateIndexTs(requestDir);
|
|
69
74
|
|
|
70
|
-
// === 3) Services
|
|
71
|
-
const serviceDir = path.join(domainPath, 'services');
|
|
75
|
+
// === 3) Services
|
|
72
76
|
const serviceTpl = await fs.readFile(path.join(__dirname, '../templates/domain/services/ClassService.ejs'), 'utf-8');
|
|
73
|
-
const serviceResult = ejs.render(serviceTpl, {
|
|
74
|
-
className: capital,
|
|
75
|
-
domainName: lower
|
|
76
|
-
});
|
|
77
|
+
const serviceResult = ejs.render(serviceTpl, { className: capital, domainName: lower });
|
|
77
78
|
await writeIfNotExists(path.join(serviceDir, `${capital}Service.ts`), serviceResult);
|
|
79
|
+
await updateIndexTs(serviceDir);
|
|
78
80
|
|
|
79
|
-
//
|
|
80
|
-
await writeIfNotExists(
|
|
81
|
-
path.join(serviceDir, 'index.ts'),
|
|
82
|
-
`export * from './${capital}Service';\n`
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
// === 4) Domain Index ===
|
|
81
|
+
// === 4) Domain Index
|
|
86
82
|
await writeIfNotExists(
|
|
87
83
|
path.join(domainPath, 'index.ts'),
|
|
88
|
-
[
|
|
89
|
-
`export * from './abstracts';`,
|
|
90
|
-
`export * from './request';`,
|
|
91
|
-
`export * from './services';`
|
|
92
|
-
].join('\n')
|
|
84
|
+
[`export * from './abstracts';`, `export * from './request';`].join('\n') + '\n'
|
|
93
85
|
);
|
|
94
86
|
|
|
95
|
-
// === 5)
|
|
87
|
+
// === 5) Repo
|
|
96
88
|
const repoTpl = await fs.readFile(path.join(__dirname, '../templates/data/repo/ClassRepo.ejs'), 'utf-8');
|
|
97
89
|
const repoResult = ejs.render(repoTpl, {
|
|
98
90
|
className: capital,
|
|
99
91
|
endpoint,
|
|
100
92
|
domainName: lower,
|
|
101
|
-
datasource
|
|
93
|
+
datasource
|
|
102
94
|
});
|
|
103
95
|
await writeIfNotExists(path.join(repoPath, `${capital}Repo.ts`), repoResult);
|
|
96
|
+
await updateIndexTs(repoPath);
|
|
104
97
|
|
|
105
|
-
|
|
106
|
-
const files = await fs.readdir(repoPath);
|
|
107
|
-
const exports = files
|
|
108
|
-
.filter(f => f.endsWith('Repo.ts') && f !== 'index.ts')
|
|
109
|
-
.map(f => `export * from './${f.replace('.ts', '')}';`)
|
|
110
|
-
.join('\n');
|
|
111
|
-
await fs.writeFile(path.join(repoPath, 'index.ts'), exports, 'utf-8');
|
|
112
|
-
|
|
113
|
-
console.log(`✅ CRUD for ${capital} generated successfully!`);
|
|
98
|
+
console.log(`✅ CRUD for ${capital} generated in ${selectedModule || 'monolith'} structure`);
|
|
114
99
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { loadUserConfig } from '../utils/loadConfig.js';
|
|
4
|
+
|
|
5
|
+
/** Файл конфигурации */
|
|
6
|
+
const svelteConfigPath = path.resolve('svelte.config.js');
|
|
7
|
+
|
|
8
|
+
function generateAliases(config) {
|
|
9
|
+
const hasModules = Array.isArray(config.modules) && config.modules.length > 0;
|
|
10
|
+
|
|
11
|
+
if (hasModules) {
|
|
12
|
+
return Object.fromEntries(
|
|
13
|
+
config.modules.map(m => [`$${m}`, `./src/app/context/${m}`])
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
'$domain': './src/app/context/domain',
|
|
19
|
+
'$infra': './src/app/context/infra',
|
|
20
|
+
'$application': './src/app/context/application',
|
|
21
|
+
'$presentation': './src/app/context/presentation',
|
|
22
|
+
'$services': './src/app/context/application/services'
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseObjectLiteral(text) {
|
|
27
|
+
const obj = {};
|
|
28
|
+
const entries = text.split(/,(?![^{]*})/).filter(Boolean);
|
|
29
|
+
for (const entry of entries) {
|
|
30
|
+
const [key, value] = entry.split(':').map(s => s.trim());
|
|
31
|
+
if (key && value) {
|
|
32
|
+
obj[key.replace(/^['"]|['"]$/g, '')] = value.replace(/^['"]|['"]$/g, '');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return obj;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function serializeObjectLiteral(obj) {
|
|
39
|
+
return Object.entries(obj)
|
|
40
|
+
.map(([key, value]) => `\t\t\t'${key}': '${value}'`)
|
|
41
|
+
.join(',\n');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function updateAliases() {
|
|
45
|
+
const config = await loadUserConfig();
|
|
46
|
+
const newAliases = generateAliases(config);
|
|
47
|
+
|
|
48
|
+
let content = await fs.readFile(svelteConfigPath, 'utf-8');
|
|
49
|
+
|
|
50
|
+
const aliasRegex = /alias:\s*{([\s\S]*?)}/m;
|
|
51
|
+
const match = content.match(aliasRegex);
|
|
52
|
+
|
|
53
|
+
if (!match) {
|
|
54
|
+
console.error('❌ No `alias` field found in svelte.config.js');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// существующие алиасы
|
|
59
|
+
const existingAliases = parseObjectLiteral(match[1]);
|
|
60
|
+
|
|
61
|
+
// объединение
|
|
62
|
+
const updatedAliases = { ...existingAliases, ...newAliases };
|
|
63
|
+
|
|
64
|
+
// замена в контенте
|
|
65
|
+
const newAliasBlock = `alias: {\n${serializeObjectLiteral(updatedAliases)}\n\t\t}`;
|
|
66
|
+
content = content.replace(aliasRegex, newAliasBlock);
|
|
67
|
+
|
|
68
|
+
await fs.writeFile(svelteConfigPath, content, 'utf-8');
|
|
69
|
+
console.log('✅ Aliases updated in svelte.config.js');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default updateAliases;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseService } from '@azure-net/kit';
|
|
2
2
|
import { <%= className %>Repo } from '$data/repo';
|
|
3
|
-
import type { <%= className %>CreateRequest, <%= className %>UpdateRequest } from '$domain/<%= domainName
|
|
3
|
+
import type { <%= className %>CreateRequest, <%= className %>UpdateRequest } from '$domain/<%= domainName %>';
|
|
4
4
|
|
|
5
5
|
export class <%= className %>Service extends BaseService {
|
|
6
6
|
constructor(private <%= domainName %>Repo = new <%= className %>Repo()) {
|
package/src/utils/loadConfig.js
CHANGED