@azure-net/cli 1.3.8 → 1.3.10
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/package.json +1 -1
- package/src/commands/generateCrud.js +28 -8
- package/src/commands/generateStructure.js +10 -8
- package/src/commands/initAliases.js +8 -2
- package/src/templates/data/repo/ClassRepo.ejs +12 -12
- package/src/templates/domain/abstracts/Class.ejs +2 -2
- package/src/templates/domain/abstracts/ClassCreateRequest.ejs +1 -1
- package/src/templates/domain/abstracts/ClassUpdateRequest.ejs +1 -1
- package/src/templates/domain/request/ClassCreateRequest.ejs +2 -2
- package/src/templates/domain/request/ClassUpdateRequest.ejs +2 -2
- package/src/templates/domain/services/ClassService.ejs +11 -11
- package/src/utils/loadConfig.js +2 -1
package/package.json
CHANGED
|
@@ -2,9 +2,10 @@ import prompts from 'prompts';
|
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import ejs from 'ejs';
|
|
5
|
-
import { loadUserConfig } from
|
|
5
|
+
import { loadUserConfig } from '../utils/loadConfig.js';
|
|
6
6
|
|
|
7
7
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
8
|
+
const CORE_DATASOURCES_PATH = path.join(process.cwd(), 'src/app/core/datasources');
|
|
8
9
|
|
|
9
10
|
async function writeIfNotExists(filepath, content) {
|
|
10
11
|
try {
|
|
@@ -23,8 +24,20 @@ async function updateIndexTs(dir, filePattern = '.ts', ignore = ['index.ts']) {
|
|
|
23
24
|
await fs.writeFile(path.join(dir, 'index.ts'), content, 'utf-8');
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
async function getAvailableDatasources() {
|
|
28
|
+
try {
|
|
29
|
+
const files = await fs.readdir(CORE_DATASOURCES_PATH);
|
|
30
|
+
return files
|
|
31
|
+
.filter(f => f.endsWith('.ts') && !f.startsWith('_'))
|
|
32
|
+
.map(f => f.replace('.ts', ''));
|
|
33
|
+
} catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
export default async function generateCrud() {
|
|
27
39
|
const config = await loadUserConfig();
|
|
40
|
+
const datasources = await getAvailableDatasources();
|
|
28
41
|
|
|
29
42
|
const answers = await prompts([
|
|
30
43
|
config.modules?.length
|
|
@@ -40,11 +53,17 @@ export default async function generateCrud() {
|
|
|
40
53
|
: null,
|
|
41
54
|
{ type: 'text', name: 'className', message: 'Class name (PascalCase):' },
|
|
42
55
|
{ type: 'text', name: 'endpoint', message: 'API endpoint:' },
|
|
43
|
-
{
|
|
56
|
+
{
|
|
57
|
+
type: 'select',
|
|
58
|
+
name: 'datasource',
|
|
59
|
+
message: 'Select datasource:',
|
|
60
|
+
choices: datasources.map(d => ({ title: d, value: d }))
|
|
61
|
+
}
|
|
44
62
|
].filter(Boolean));
|
|
45
63
|
|
|
46
64
|
const rawName = answers.className.trim();
|
|
47
65
|
const capital = rawName[0].toUpperCase() + rawName.slice(1);
|
|
66
|
+
const lower = rawName[0].toLowerCase() + rawName.slice(1);
|
|
48
67
|
const endpoint = answers.endpoint.trim();
|
|
49
68
|
const datasource = answers.datasource.trim();
|
|
50
69
|
const selectedModule = answers.module;
|
|
@@ -64,15 +83,15 @@ export default async function generateCrud() {
|
|
|
64
83
|
const aliasShared = '$shared-context';
|
|
65
84
|
|
|
66
85
|
const templateData = {
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
camelCaseName: lower,
|
|
87
|
+
pascalCaseName: capital,
|
|
69
88
|
endpoint,
|
|
70
89
|
datasource,
|
|
71
90
|
aliasDomain: `${aliasCurrent}/Domain`,
|
|
72
|
-
aliasShared
|
|
91
|
+
aliasShared,
|
|
73
92
|
aliasApplication: `${aliasCurrent}/Application`,
|
|
74
93
|
aliasInfra: `${aliasCurrent}/Infra`,
|
|
75
|
-
aliasRepo: `${aliasCurrent}/Infra/Repo
|
|
94
|
+
aliasRepo: `${aliasCurrent}/Infra/Repo`
|
|
76
95
|
};
|
|
77
96
|
|
|
78
97
|
// === 1) Abstracts
|
|
@@ -102,8 +121,9 @@ export default async function generateCrud() {
|
|
|
102
121
|
// === 4) Domain Index
|
|
103
122
|
await writeIfNotExists(
|
|
104
123
|
path.join(domainPath, 'index.ts'),
|
|
105
|
-
[`export * from './Abstracts';`, `export * from './Request';`].join('\n')
|
|
124
|
+
[`export * from './Abstracts';`, `export * from './Request';`].join('\n')
|
|
106
125
|
);
|
|
126
|
+
await updateIndexTs(domainPath);
|
|
107
127
|
|
|
108
128
|
// === 5) Repo
|
|
109
129
|
const repoTpl = await fs.readFile(path.join(__dirname, '../templates/data/repo/ClassRepo.ejs'), 'utf-8');
|
|
@@ -112,4 +132,4 @@ export default async function generateCrud() {
|
|
|
112
132
|
await updateIndexTs(repoPath);
|
|
113
133
|
|
|
114
134
|
console.log(`✅ CRUD for ${capital} generated in ${selectedModule || 'app-context'} structure`);
|
|
115
|
-
}
|
|
135
|
+
}
|
|
@@ -5,6 +5,7 @@ import { loadUserConfig } from '../utils/loadConfig.js';
|
|
|
5
5
|
const BASE_STRUCTURE = ['Domain', 'Infra', 'Application', 'Presentation'];
|
|
6
6
|
const APP_ROOT = path.join(process.cwd(), 'src', 'app');
|
|
7
7
|
const CONTEXTS_PATH = path.join(APP_ROOT, 'contexts');
|
|
8
|
+
const CORE_PATH = path.join(APP_ROOT, 'core');
|
|
8
9
|
|
|
9
10
|
async function createDirIfNotExists(dirPath) {
|
|
10
11
|
try {
|
|
@@ -20,10 +21,10 @@ async function createBaseStructure(root) {
|
|
|
20
21
|
const sectionPath = path.join(root, section);
|
|
21
22
|
await createDirIfNotExists(sectionPath);
|
|
22
23
|
|
|
23
|
-
if (section === '
|
|
24
|
+
if (section === 'Infra') {
|
|
24
25
|
await createDirIfNotExists(path.join(sectionPath, 'Repo'));
|
|
25
26
|
}
|
|
26
|
-
if (section === '
|
|
27
|
+
if (section === 'Application') {
|
|
27
28
|
await createDirIfNotExists(path.join(sectionPath, 'Services'));
|
|
28
29
|
await createDirIfNotExists(path.join(sectionPath, 'Orchestrators'));
|
|
29
30
|
}
|
|
@@ -37,7 +38,7 @@ export default async function initStructure() {
|
|
|
37
38
|
|
|
38
39
|
console.log('📦 Generating architecture in: /contexts');
|
|
39
40
|
|
|
40
|
-
// всегда shared-
|
|
41
|
+
// всегда shared-context
|
|
41
42
|
const sharedKernelPath = path.join(CONTEXTS_PATH, 'shared-context');
|
|
42
43
|
await createBaseStructure(sharedKernelPath);
|
|
43
44
|
|
|
@@ -50,13 +51,14 @@ export default async function initStructure() {
|
|
|
50
51
|
}
|
|
51
52
|
} else {
|
|
52
53
|
// fallback-контекст
|
|
53
|
-
console.log('🧱 No modules found — using default "app"
|
|
54
|
-
const
|
|
55
|
-
await createBaseStructure(
|
|
54
|
+
console.log('🧱 No modules found — using default "app-context"...');
|
|
55
|
+
const fallbackPath = path.join(CONTEXTS_PATH, 'app-context');
|
|
56
|
+
await createBaseStructure(fallbackPath);
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
//
|
|
59
|
-
await createDirIfNotExists(
|
|
59
|
+
// Доп. слои вне contexts
|
|
60
|
+
await createDirIfNotExists(CORE_PATH);
|
|
61
|
+
await createDirIfNotExists(path.join(CORE_PATH, 'datasources'));
|
|
60
62
|
await createDirIfNotExists(path.join(APP_ROOT, 'ui'));
|
|
61
63
|
|
|
62
64
|
console.log('✅ Structure initialization complete!');
|
|
@@ -12,13 +12,19 @@ function generateAliases(config) {
|
|
|
12
12
|
if (hasModules) {
|
|
13
13
|
config.modules.push('shared-context');
|
|
14
14
|
return Object.fromEntries(
|
|
15
|
-
|
|
15
|
+
[
|
|
16
|
+
...config.modules.map(m => [`$${m}`, `./src/app/contexts/${m}`]),
|
|
17
|
+
['$core', './src/app/core'],
|
|
18
|
+
['$ui', './src/app/ui']
|
|
19
|
+
]
|
|
16
20
|
);
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
return {
|
|
20
24
|
'$app-context': './src/app/contexts/app-context',
|
|
21
|
-
'$shared-context': './src/app/contexts/shared-context'
|
|
25
|
+
'$shared-context': './src/app/contexts/shared-context',
|
|
26
|
+
'$core': './src/app/core',
|
|
27
|
+
'$ui': './src/app/ui'
|
|
22
28
|
};
|
|
23
29
|
}
|
|
24
30
|
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { <%= datasource %> } from '<%= aliasShared %>/datasources';
|
|
2
2
|
import type {
|
|
3
|
-
I<%=
|
|
4
|
-
I<%=
|
|
5
|
-
I<%=
|
|
6
|
-
I<%=
|
|
7
|
-
} from '<%= aliasDomain %>/<%=
|
|
3
|
+
I<%= pascalCaseName %>Collection,
|
|
4
|
+
I<%= pascalCaseName %>Resource,
|
|
5
|
+
I<%= pascalCaseName %>CreateRequest,
|
|
6
|
+
I<%= pascalCaseName %>UpdateRequest
|
|
7
|
+
} from '<%= aliasDomain %>/<%= pascalCaseName %>';
|
|
8
8
|
|
|
9
|
-
export class <%=
|
|
9
|
+
export class <%= pascalCaseName %>Repo {
|
|
10
10
|
private endpoint = '<%= endpoint %>';
|
|
11
11
|
constructor(private source = new <%= datasource %>()) {}
|
|
12
12
|
|
|
13
13
|
public async collection() {
|
|
14
|
-
return await this.source.createRequest<I<%=
|
|
14
|
+
return await this.source.createRequest<I<%= pascalCaseName %>Collection>(({ http }) => http.get(this.endpoint));
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
public async resource(id: number) {
|
|
18
|
-
return await this.source.createRequest<I<%=
|
|
18
|
+
return await this.source.createRequest<I<%= pascalCaseName %>Resource>(({ http }) => http.get(`${this.endpoint}/${id}`));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
public async create(data: I<%=
|
|
22
|
-
return await this.source.createRequest<I<%=
|
|
21
|
+
public async create(data: I<%= pascalCaseName %>CreateRequest) {
|
|
22
|
+
return await this.source.createRequest<I<%= pascalCaseName %>Resource>(({ http }) => http.post(this.endpoint, { json: data }));
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
public async update(id: number, data: I<%=
|
|
26
|
-
return await this.source.createRequest<I<%=
|
|
25
|
+
public async update(id: number, data: I<%= pascalCaseName %>UpdateRequest) {
|
|
26
|
+
return await this.source.createRequest<I<%= pascalCaseName %>Resource>(({ http }) => http.put(`${this.endpoint}/${id}`, { json: data }));
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
public async remove(id: number) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export interface I<%=
|
|
1
|
+
export interface I<%= pascalCaseName %>Resource {
|
|
2
2
|
// TODO: define fields
|
|
3
3
|
[key: string]: unknown;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
export type I<%=
|
|
6
|
+
export type I<%= pascalCaseName %>Collection = I<%= pascalCaseName %>Resource[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseRequest } from '@azure-net/kit';
|
|
2
|
-
import type { I<%=
|
|
2
|
+
import type { I<%= pascalCaseName %>CreateRequest } from '../Abstracts';
|
|
3
3
|
|
|
4
|
-
export class <%=
|
|
4
|
+
export class <%= pascalCaseName %>CreateRequest extends BaseRequest<I<%= pascalCaseName %>CreateRequest> {
|
|
5
5
|
override rules() {
|
|
6
6
|
return {};
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseRequest } from '@azure-net/kit';
|
|
2
|
-
import type { I<%=
|
|
2
|
+
import type { I<%= pascalCaseName %>UpdateRequest } from '../Abstracts';
|
|
3
3
|
|
|
4
|
-
export class <%=
|
|
4
|
+
export class <%= pascalCaseName %>UpdateRequest extends BaseRequest<I<%= pascalCaseName %>UpdateRequest> {
|
|
5
5
|
override rules() {
|
|
6
6
|
return {};
|
|
7
7
|
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { BaseService } from '@azure-net/kit';
|
|
2
|
-
import { <%=
|
|
3
|
-
import type { <%=
|
|
2
|
+
import { <%= pascalCaseName %>Repo } from '<%= aliasRepo %>';
|
|
3
|
+
import type { <%= pascalCaseName %>CreateRequest, <%= pascalCaseName %>UpdateRequest } from '<%= aliasDomain %>/<%= pascalCaseName %>';
|
|
4
4
|
|
|
5
|
-
export class <%=
|
|
6
|
-
constructor(private <%=
|
|
5
|
+
export class <%= pascalCaseName %>Service extends BaseService {
|
|
6
|
+
constructor(private <%= camelCaseName %>Repo = new <%= pascalCaseName %>Repo()) {
|
|
7
7
|
super();
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
async collection() {
|
|
11
|
-
return await this.transformResponse(this.<%=
|
|
11
|
+
return await this.transformResponse(this.<%= camelCaseName %>Repo.collection());
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
async resource(id: number) {
|
|
15
|
-
return await this.transformResponse(this.<%=
|
|
15
|
+
return await this.transformResponse(this.<%= camelCaseName %>Repo.resource(id));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
async create(request: <%=
|
|
19
|
-
return await this.transformResponse(this.<%=
|
|
18
|
+
async create(request: <%= pascalCaseName %>CreateRequest) {
|
|
19
|
+
return await this.transformResponse(this.<%= camelCaseName %>Repo.create(request.json()));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
async update(id: number, request: <%=
|
|
23
|
-
return await this.transformResponse(this.<%=
|
|
22
|
+
async update(id: number, request: <%= pascalCaseName %>UpdateRequest) {
|
|
23
|
+
return await this.transformResponse(this.<%= camelCaseName %>Repo.update(id, request.json()));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async remove(id: number) {
|
|
27
|
-
return await this.transformResponse(this.<%=
|
|
27
|
+
return await this.transformResponse(this.<%= camelCaseName %>Repo.remove(id));
|
|
28
28
|
}
|
|
29
29
|
}
|