@azure-net/cli 1.0.3 → 1.1.4
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 +5 -4
- package/package.json +1 -1
- package/src/commands/generateCrud.js +110 -0
- package/src/templates/data/repo/ClassRepo.ejs +32 -0
- package/src/templates/domain/abstracts/Class.ejs +3 -0
- package/src/templates/domain/abstracts/ClassCreateRequest.ejs +1 -0
- package/src/templates/domain/abstracts/ClassUpdateRequest.ejs +1 -0
- package/src/templates/domain/request/ClassCreateRequest.ejs +8 -0
- package/src/templates/domain/request/ClassUpdateRequest.ejs +8 -0
- package/src/templates/domain/services/ClassService.ejs +29 -0
- package/src/utils/loadConfig.js +2 -2
- package/src/commands/generateCrudService.js +0 -27
package/bin/azure-net.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import generateRepository from '../src/commands/generateCrudRepo.js';
|
|
5
|
-
import
|
|
5
|
+
import generateCrud from '../src/commands/generateCrud.js';
|
|
6
6
|
|
|
7
7
|
const program = new Command();
|
|
8
8
|
|
|
@@ -15,8 +15,9 @@ program.command('generate:crud-repo')
|
|
|
15
15
|
.description('Generate a CRUD repository')
|
|
16
16
|
.action(generateRepository);
|
|
17
17
|
|
|
18
|
-
program
|
|
19
|
-
.
|
|
20
|
-
.
|
|
18
|
+
program
|
|
19
|
+
.command('generate:crud')
|
|
20
|
+
.description('Generate CRUD Domain/Repo/Service')
|
|
21
|
+
.action(generateCrud);
|
|
21
22
|
|
|
22
23
|
program.parse();
|
package/package.json
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import ejs from 'ejs';
|
|
5
|
+
import { loadUserConfig } from "../utils/loadConfig.js";
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
8
|
+
|
|
9
|
+
async function writeIfNotExists(filepath, content) {
|
|
10
|
+
try {
|
|
11
|
+
await fs.access(filepath);
|
|
12
|
+
console.log(`⚠️ Skip existing: ${filepath}`);
|
|
13
|
+
} catch {
|
|
14
|
+
await fs.mkdir(path.dirname(filepath), { recursive: true });
|
|
15
|
+
await fs.writeFile(filepath, content, 'utf-8');
|
|
16
|
+
console.log(`✅ Created: ${filepath}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default async function generateCrud() {
|
|
21
|
+
const config = await loadUserConfig();
|
|
22
|
+
const answers = await prompts([
|
|
23
|
+
{ type: 'text', name: 'className', message: 'Class name (PascalCase):' },
|
|
24
|
+
{ type: 'text', name: 'endpoint', message: 'API endpoint:' }
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
const rawName = answers.className.trim();
|
|
28
|
+
const capital = rawName[0].toUpperCase() + rawName.slice(1);
|
|
29
|
+
const lower = rawName[0].toLowerCase() + rawName.slice(1);
|
|
30
|
+
const endpoint = answers.endpoint.trim();
|
|
31
|
+
|
|
32
|
+
// === Domain lowercase folder ===
|
|
33
|
+
const domainPath = path.join(process.cwd(), config.output.domain, lower);
|
|
34
|
+
const repoPath = path.join(process.cwd(), config.output.repo);
|
|
35
|
+
|
|
36
|
+
// 1) Abstracts
|
|
37
|
+
const abstractsDir = path.join(domainPath, 'abstracts');
|
|
38
|
+
for (const file of ['Class', 'ClassCreateRequest', 'ClassUpdateRequest']) {
|
|
39
|
+
const tpl = await fs.readFile(path.join(__dirname, `../templates/domain/abstracts/${file}.ejs`), 'utf-8');
|
|
40
|
+
const result = ejs.render(tpl, { className: capital });
|
|
41
|
+
await writeIfNotExists(path.join(abstractsDir, `${capital}${file.replace('Class', '')}.ts`), result);
|
|
42
|
+
}
|
|
43
|
+
await writeIfNotExists(
|
|
44
|
+
path.join(abstractsDir, `index.ts`),
|
|
45
|
+
[
|
|
46
|
+
`export * from './${capital}';`,
|
|
47
|
+
`export * from './${capital}CreateRequest';`,
|
|
48
|
+
`export * from './${capital}UpdateRequest';`
|
|
49
|
+
].join('\n')
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// 2) Request
|
|
53
|
+
const requestDir = path.join(domainPath, 'request');
|
|
54
|
+
for (const file of ['ClassCreateRequest', 'ClassUpdateRequest']) {
|
|
55
|
+
const tpl = await fs.readFile(path.join(__dirname, `../templates/domain/request/${file}.ejs`), 'utf-8');
|
|
56
|
+
const result = ejs.render(tpl, { className: capital });
|
|
57
|
+
await writeIfNotExists(path.join(requestDir, `${capital}${file.replace('Class', '')}.ts`), result);
|
|
58
|
+
}
|
|
59
|
+
await writeIfNotExists(
|
|
60
|
+
path.join(requestDir, `index.ts`),
|
|
61
|
+
[
|
|
62
|
+
`export * from './${capital}CreateRequest';`,
|
|
63
|
+
`export * from './${capital}UpdateRequest';`
|
|
64
|
+
].join('\n')
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// === 3) Services ===
|
|
68
|
+
const serviceDir = path.join(domainPath, 'services');
|
|
69
|
+
const serviceTpl = await fs.readFile(path.join(__dirname, '../templates/domain/services/ClassService.ejs'), 'utf-8');
|
|
70
|
+
const serviceResult = ejs.render(serviceTpl, {
|
|
71
|
+
className: capital,
|
|
72
|
+
domainName: lower
|
|
73
|
+
});
|
|
74
|
+
await writeIfNotExists(path.join(serviceDir, `${capital}Service.ts`), serviceResult);
|
|
75
|
+
|
|
76
|
+
// ✅ Новый файл index.ts в services
|
|
77
|
+
await writeIfNotExists(
|
|
78
|
+
path.join(serviceDir, 'index.ts'),
|
|
79
|
+
`export * from './${capital}Service';\n`
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// 4) Domain Index
|
|
83
|
+
await writeIfNotExists(
|
|
84
|
+
path.join(domainPath, 'index.ts'),
|
|
85
|
+
[
|
|
86
|
+
`export * from './abstracts';`,
|
|
87
|
+
`export * from './request';`,
|
|
88
|
+
`export * from './services';`
|
|
89
|
+
].join('\n')
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// === Generate Repo ===
|
|
93
|
+
const repoTpl = await fs.readFile(path.join(__dirname, '../templates/data/repo/ClassRepo.ejs'), 'utf-8');
|
|
94
|
+
const repoResult = ejs.render(repoTpl, {
|
|
95
|
+
className: capital,
|
|
96
|
+
endpoint,
|
|
97
|
+
domainName: lower
|
|
98
|
+
});
|
|
99
|
+
await writeIfNotExists(path.join(repoPath, `${capital}Repo.ts`), repoResult);
|
|
100
|
+
|
|
101
|
+
// === Repo Index ===
|
|
102
|
+
const files = await fs.readdir(repoPath);
|
|
103
|
+
const exports = files
|
|
104
|
+
.filter(f => f.endsWith('Repo.ts') && f !== 'index.ts')
|
|
105
|
+
.map(f => `export * from './${f.replace('.ts', '')}';`)
|
|
106
|
+
.join('\n');
|
|
107
|
+
await fs.writeFile(path.join(repoPath, 'index.ts'), exports, 'utf-8');
|
|
108
|
+
|
|
109
|
+
console.log(`✅ CRUD for ${capital} generated successfully!`);
|
|
110
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { BaseDatasource } from '@azure-net/kit';
|
|
2
|
+
import {
|
|
3
|
+
I<%= className %>Collection,
|
|
4
|
+
I<%= className %>Resource,
|
|
5
|
+
I<%= className %>CreateRequest,
|
|
6
|
+
I<%= className %>UpdateRequest
|
|
7
|
+
} from '$domain/<%= domainName %>';
|
|
8
|
+
|
|
9
|
+
export class <%= className %>Repo {
|
|
10
|
+
private endpoint = '<%= endpoint %>';
|
|
11
|
+
constructor(private source: BaseDatasource) {}
|
|
12
|
+
|
|
13
|
+
public async collection() {
|
|
14
|
+
return await this.source.createRequest<I<%= className %>Collection>(({ http }) => http.get(this.endpoint));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public async resource(id: number) {
|
|
18
|
+
return await this.source.createRequest<I<%= className %>Resource>(({ http }) => http.get(`${this.endpoint}/${id}`));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public async create(data: I<%= className %>CreateRequest) {
|
|
22
|
+
return await this.source.createRequest<I<%= className %>Resource>(({ http }) => http.post(this.endpoint, { json: data }));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public async update(id: number, data: I<%= className %>UpdateRequest) {
|
|
26
|
+
return await this.source.createRequest<I<%= className %>Resource>(({ http }) => http.put(`${this.endpoint}/${id}`, { json: data }));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public async remove(id: number) {
|
|
30
|
+
return await this.source.createRequest<void>(({ http }) => http.delete(`${this.endpoint}/${id}`));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export interface I<%= className %>CreateRequest {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export interface I<%= className %>UpdateRequest {}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BaseService } from '@azure-net/kit';
|
|
2
|
+
import { <%= className %>Repo } from '$data/repo';
|
|
3
|
+
import { <%= className %>CreateRequest, <%= className %>UpdateRequest } from '$domain/<%= domainName %>/request';
|
|
4
|
+
|
|
5
|
+
export class <%= className %>Service extends BaseService {
|
|
6
|
+
constructor(private <%= domainName %>Repo = new <%= className %>Repo()) {
|
|
7
|
+
super();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async collection() {
|
|
11
|
+
return await this.transformResponse(this.<%= className %>Repo.collection());
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async resource(id: number) {
|
|
15
|
+
return await this.transformResponse(this.<%= className %>Repo.resource(id));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async create(request: <%= className %>CreateRequest) {
|
|
19
|
+
return await this.transformResponse(this.<%= className %>Repo.create(request.json()));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async update(id: number, request: <%= className %>UpdateRequest) {
|
|
23
|
+
return await this.transformResponse(this.<%= className %>Repo.update(request.json()));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async remove(id: number) {
|
|
27
|
+
return await this.transformResponse(this.<%= className %>Repo.remove());
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/utils/loadConfig.js
CHANGED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import prompts from 'prompts';
|
|
2
|
-
import ejs from 'ejs';
|
|
3
|
-
import fs from 'fs/promises';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import { loadUserConfig } from "../utils/loadConfig.js";
|
|
7
|
-
|
|
8
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
|
|
10
|
-
export default async function generateCrudService() {
|
|
11
|
-
const config = await loadUserConfig();
|
|
12
|
-
const answers = await prompts([
|
|
13
|
-
{ type: 'text', name: 'className', message: 'Class name:' },
|
|
14
|
-
{ type: 'text', name: 'endpoint', message: 'API endpoint:' },
|
|
15
|
-
]);
|
|
16
|
-
|
|
17
|
-
const templatePath = path.join(__dirname, '../templates/generateCrudRepo.ejs');
|
|
18
|
-
const template = await fs.readFile(templatePath, 'utf-8');
|
|
19
|
-
const result = ejs.render(template, answers);
|
|
20
|
-
|
|
21
|
-
const outputDir = config.output.repository;
|
|
22
|
-
const outFile = path.join(process.cwd(), outputDir, `${answers.className}Repo.ts`);
|
|
23
|
-
await fs.mkdir(path.dirname(outFile), { recursive: true });
|
|
24
|
-
await fs.writeFile(outFile, result, 'utf-8');
|
|
25
|
-
|
|
26
|
-
console.log(`✅ Created: ${outFile}`);
|
|
27
|
-
}
|