create-backlist 7.3.1 → 9.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/bin/index.js +901 -471
- package/bin/qa.js +191 -0
- package/package.json +27 -18
- package/src/ai-agent.js +581 -124
- package/src/analyzer.js +628 -528
- package/src/env-resolver.js +70 -70
- package/src/generators/dotnet.js +134 -134
- package/src/generators/java.js +248 -248
- package/src/generators/js.js +345 -345
- package/src/generators/nestjs.js +277 -277
- package/src/generators/python.js +86 -86
- package/src/project-detector.js +131 -131
- package/src/qa/qa-engine.js +1187 -0
- package/src/templates/dotnet/partials/Dockerfile.ejs +27 -27
- package/src/templates/dotnet/partials/docker-compose.yml.ejs +33 -33
- package/src/templates/js-express/base/server.js +59 -59
- package/src/templates/js-express/partials/Dockerfile.ejs +12 -12
- package/src/templates/js-express/partials/auth.controller.js.ejs +66 -66
- package/src/templates/js-express/partials/auth.middleware.js.ejs +19 -19
- package/src/templates/js-express/partials/auth.routes.js.ejs +9 -9
- package/src/templates/js-express/partials/controller.js.ejs +53 -53
- package/src/templates/js-express/partials/db.js.ejs +19 -19
- package/src/templates/js-express/partials/docker-compose.yml.ejs +46 -46
- package/src/templates/js-express/partials/model.js.ejs +18 -18
- package/src/templates/js-express/partials/package.json.ejs +17 -17
- package/src/templates/js-express/partials/prisma.schema.ejs +21 -21
- package/src/templates/js-express/partials/routes.js.ejs +19 -19
- package/src/templates/js-express/partials/seeder.js.ejs +103 -103
- package/src/templates/js-express/partials/service.js.ejs +51 -51
- package/src/templates/js-express/partials/swagger.js.ejs +30 -30
- package/src/templates/js-express/partials/test.js.ejs +46 -46
- package/src/templates/nestjs/base/app.module.ts +9 -9
- package/src/templates/nestjs/base/main.ts +23 -23
- package/src/templates/nestjs/base/tsconfig.json +21 -21
- package/src/templates/nestjs/partials/auth.controller.ts.ejs +17 -17
- package/src/templates/nestjs/partials/auth.module.ts.ejs +17 -17
- package/src/templates/nestjs/partials/auth.service.ts.ejs +70 -70
- package/src/templates/nestjs/partials/controller.ts.ejs +34 -34
- package/src/templates/nestjs/partials/create-dto.ts.ejs +22 -22
- package/src/templates/nestjs/partials/jwt-guard.ts.ejs +24 -24
- package/src/templates/nestjs/partials/module.ts.ejs +10 -10
- package/src/templates/nestjs/partials/package.json.ejs +27 -27
- package/src/templates/nestjs/partials/prisma.service.ts.ejs +13 -13
- package/src/templates/nestjs/partials/schema.ts.ejs +19 -19
- package/src/templates/nestjs/partials/service.ts.ejs +67 -67
- package/src/templates/nestjs/partials/update-dto.ts.ejs +4 -4
package/src/env-resolver.js
CHANGED
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
import fs from "fs-extra";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
|
|
4
|
-
const ENV_FILES = [
|
|
5
|
-
".env.local",
|
|
6
|
-
".env.development",
|
|
7
|
-
".env.development.local",
|
|
8
|
-
".env",
|
|
9
|
-
];
|
|
10
|
-
|
|
11
|
-
const API_URL_PATTERNS = [
|
|
12
|
-
"API_URL",
|
|
13
|
-
"API_BASE_URL",
|
|
14
|
-
"API_BASE",
|
|
15
|
-
"BASE_URL",
|
|
16
|
-
"BACKEND_URL",
|
|
17
|
-
"SERVER_URL",
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
export async function parseEnvFiles(projectRoot) {
|
|
21
|
-
const envMap = new Map();
|
|
22
|
-
|
|
23
|
-
for (const envFile of ENV_FILES) {
|
|
24
|
-
const filePath = path.join(projectRoot, envFile);
|
|
25
|
-
if (!(await fs.pathExists(filePath))) continue;
|
|
26
|
-
|
|
27
|
-
let content;
|
|
28
|
-
try {
|
|
29
|
-
content = await fs.readFile(filePath, "utf-8");
|
|
30
|
-
} catch {
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
for (const line of content.split("\n")) {
|
|
35
|
-
const trimmed = line.trim();
|
|
36
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
37
|
-
|
|
38
|
-
const eqIndex = trimmed.indexOf("=");
|
|
39
|
-
if (eqIndex === -1) continue;
|
|
40
|
-
|
|
41
|
-
const key = trimmed.slice(0, eqIndex).trim();
|
|
42
|
-
let value = trimmed.slice(eqIndex + 1).trim();
|
|
43
|
-
|
|
44
|
-
if (
|
|
45
|
-
(value.startsWith('"') && value.endsWith('"')) ||
|
|
46
|
-
(value.startsWith("'") && value.endsWith("'"))
|
|
47
|
-
) {
|
|
48
|
-
value = value.slice(1, -1);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (key && value && !envMap.has(key)) {
|
|
52
|
-
envMap.set(key, value);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return envMap;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function extractBaseUrlFromEnv(envMap) {
|
|
61
|
-
for (const [key, value] of envMap) {
|
|
62
|
-
const upperKey = key.toUpperCase();
|
|
63
|
-
for (const pattern of API_URL_PATTERNS) {
|
|
64
|
-
if (upperKey.includes(pattern) && value.startsWith("http")) {
|
|
65
|
-
return value.replace(/\/$/, "");
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
const ENV_FILES = [
|
|
5
|
+
".env.local",
|
|
6
|
+
".env.development",
|
|
7
|
+
".env.development.local",
|
|
8
|
+
".env",
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const API_URL_PATTERNS = [
|
|
12
|
+
"API_URL",
|
|
13
|
+
"API_BASE_URL",
|
|
14
|
+
"API_BASE",
|
|
15
|
+
"BASE_URL",
|
|
16
|
+
"BACKEND_URL",
|
|
17
|
+
"SERVER_URL",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
export async function parseEnvFiles(projectRoot) {
|
|
21
|
+
const envMap = new Map();
|
|
22
|
+
|
|
23
|
+
for (const envFile of ENV_FILES) {
|
|
24
|
+
const filePath = path.join(projectRoot, envFile);
|
|
25
|
+
if (!(await fs.pathExists(filePath))) continue;
|
|
26
|
+
|
|
27
|
+
let content;
|
|
28
|
+
try {
|
|
29
|
+
content = await fs.readFile(filePath, "utf-8");
|
|
30
|
+
} catch {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (const line of content.split("\n")) {
|
|
35
|
+
const trimmed = line.trim();
|
|
36
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
37
|
+
|
|
38
|
+
const eqIndex = trimmed.indexOf("=");
|
|
39
|
+
if (eqIndex === -1) continue;
|
|
40
|
+
|
|
41
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
42
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
(value.startsWith('"') && value.endsWith('"')) ||
|
|
46
|
+
(value.startsWith("'") && value.endsWith("'"))
|
|
47
|
+
) {
|
|
48
|
+
value = value.slice(1, -1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (key && value && !envMap.has(key)) {
|
|
52
|
+
envMap.set(key, value);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return envMap;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function extractBaseUrlFromEnv(envMap) {
|
|
61
|
+
for (const [key, value] of envMap) {
|
|
62
|
+
const upperKey = key.toUpperCase();
|
|
63
|
+
for (const pattern of API_URL_PATTERNS) {
|
|
64
|
+
if (upperKey.includes(pattern) && value.startsWith("http")) {
|
|
65
|
+
return value.replace(/\/$/, "");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
package/src/generators/dotnet.js
CHANGED
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { execa } from 'execa';
|
|
3
|
-
import fs from 'fs-extra';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { analyzeFrontend } from '../analyzer.js';
|
|
6
|
-
import { renderAndWrite, getTemplatePath } from './template.js';
|
|
7
|
-
|
|
8
|
-
export async function generateDotnetProject(options) {
|
|
9
|
-
const { projectDir, projectName, frontendSrcDir } = options;
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
console.log(chalk.blue(' -> Analyzing frontend for C# backend...'));
|
|
13
|
-
const endpoints = await analyzeFrontend(frontendSrcDir);
|
|
14
|
-
const modelsToGenerate = new Map();
|
|
15
|
-
endpoints.forEach(ep => {
|
|
16
|
-
if (ep.schemaFields && ep.controllerName !== 'Default' && !modelsToGenerate.has(ep.controllerName)) {
|
|
17
|
-
modelsToGenerate.set(ep.controllerName, {
|
|
18
|
-
name: ep.controllerName,
|
|
19
|
-
fields: Object.entries(ep.schemaFields).map(([key, type]) => ({ name: key, type }))
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
if (modelsToGenerate.size > 0) {
|
|
25
|
-
console.log(chalk.green(` -> Identified ${modelsToGenerate.size} models/controllers to generate.`));
|
|
26
|
-
} else {
|
|
27
|
-
console.log(chalk.yellow(' -> No API calls with body data found. A basic API project will be created without models.'));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log(chalk.blue(' -> Scaffolding .NET Core Web API project...'));
|
|
31
|
-
await execa('dotnet', ['new', 'webapi', '-n', projectName, '-o', projectDir, '--no-https']);
|
|
32
|
-
|
|
33
|
-
if (modelsToGenerate.size > 0) {
|
|
34
|
-
console.log(chalk.blue(' -> Adding NuGet packages (Entity Framework Core)...'));
|
|
35
|
-
const packages = [
|
|
36
|
-
'Microsoft.EntityFrameworkCore.Design',
|
|
37
|
-
'Microsoft.EntityFrameworkCore.InMemory'
|
|
38
|
-
];
|
|
39
|
-
for (const pkg of packages) {
|
|
40
|
-
await execa('dotnet', ['add', 'package', pkg], { cwd: projectDir });
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (modelsToGenerate.size > 0) {
|
|
45
|
-
console.log(chalk.blue(' -> Generating EF Core models and DbContext...'));
|
|
46
|
-
const modelsDir = path.join(projectDir, 'Models');
|
|
47
|
-
const dataDir = path.join(projectDir, 'Data');
|
|
48
|
-
await fs.ensureDir(modelsDir);
|
|
49
|
-
await fs.ensureDir(dataDir);
|
|
50
|
-
|
|
51
|
-
for (const [modelName, modelData] of modelsToGenerate.entries()) {
|
|
52
|
-
await renderAndWrite(
|
|
53
|
-
getTemplatePath('dotnet/partials/Model.cs.ejs'),
|
|
54
|
-
path.join(modelsDir, `${modelName}.cs`),
|
|
55
|
-
{ projectName, modelName, model: modelData }
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
await renderAndWrite(
|
|
60
|
-
getTemplatePath('dotnet/partials/DbContext.cs.ejs'),
|
|
61
|
-
path.join(dataDir, 'ApplicationDbContext.cs'),
|
|
62
|
-
{ projectName, modelsToGenerate: Array.from(modelsToGenerate.values()) }
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
console.log(chalk.blue(' -> Configuring services in Program.cs...'));
|
|
67
|
-
const programCsPath = path.join(projectDir, 'Program.cs');
|
|
68
|
-
let programCsContent = await fs.readFile(programCsPath, 'utf-8');
|
|
69
|
-
|
|
70
|
-
let usingStatements = 'using Microsoft.EntityFrameworkCore;\nusing ' + projectName + '.Data;\n';
|
|
71
|
-
programCsContent = usingStatements + programCsContent;
|
|
72
|
-
|
|
73
|
-
let dbContextService = '// Configure the database context\nbuilder.Services.AddDbContext<ApplicationDbContext>(opt => opt.UseInMemoryDatabase("MyDb"));';
|
|
74
|
-
programCsContent = programCsContent.replace('builder.Services.AddControllers();', `builder.Services.AddControllers();\n\n${dbContextService}`);
|
|
75
|
-
|
|
76
|
-
const corsPolicy = `
|
|
77
|
-
builder.Services.AddCors(options =>
|
|
78
|
-
{
|
|
79
|
-
options.AddDefaultPolicy(
|
|
80
|
-
policy =>
|
|
81
|
-
{
|
|
82
|
-
policy.WithOrigins("http://localhost:3000", "http://localhost:5173")
|
|
83
|
-
.AllowAnyHeader()
|
|
84
|
-
.AllowAnyMethod();
|
|
85
|
-
});
|
|
86
|
-
});`;
|
|
87
|
-
programCsContent = programCsContent.replace('var app = builder.Build();', `${corsPolicy}\n\nvar app = builder.Build();\n\napp.UseCors();`);
|
|
88
|
-
|
|
89
|
-
await fs.writeFile(programCsPath, programCsContent);
|
|
90
|
-
|
|
91
|
-
console.log(chalk.blue(' -> Generating controllers with CRUD logic...'));
|
|
92
|
-
await fs.remove(path.join(projectDir, 'Controllers', 'WeatherForecastController.cs'));
|
|
93
|
-
await fs.remove(path.join(projectDir, 'WeatherForecast.cs'));
|
|
94
|
-
|
|
95
|
-
const controllersToGenerate = new Set(Array.from(modelsToGenerate.keys()));
|
|
96
|
-
endpoints.forEach(ep => {
|
|
97
|
-
if (ep.controllerName !== 'Default') controllersToGenerate.add(ep.controllerName);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
for (const controllerName of controllersToGenerate) {
|
|
101
|
-
const controllerEndpoints = endpoints.filter(
|
|
102
|
-
ep => ep.controllerName === controllerName
|
|
103
|
-
);
|
|
104
|
-
await renderAndWrite(
|
|
105
|
-
getTemplatePath('dotnet/partials/Controller.cs.ejs'),
|
|
106
|
-
path.join(projectDir, 'Controllers', `${controllerName}Controller.cs`),
|
|
107
|
-
{ projectName, controllerName, endpoints: controllerEndpoints }
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
console.log(chalk.blue(' -> Generating Docker files...'));
|
|
112
|
-
await renderAndWrite(
|
|
113
|
-
getTemplatePath('dotnet/partials/Dockerfile.ejs'),
|
|
114
|
-
path.join(projectDir, 'Dockerfile'),
|
|
115
|
-
{ projectName }
|
|
116
|
-
);
|
|
117
|
-
await renderAndWrite(
|
|
118
|
-
getTemplatePath('dotnet/partials/docker-compose.yml.ejs'),
|
|
119
|
-
path.join(projectDir, 'docker-compose.yml'),
|
|
120
|
-
{ projectName }
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
await renderAndWrite(
|
|
124
|
-
getTemplatePath('dotnet/partials/README.md.ejs'),
|
|
125
|
-
path.join(projectDir, 'README.md'),
|
|
126
|
-
{ projectName }
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
console.log(chalk.green(' -> C# backend generation is complete!'));
|
|
130
|
-
|
|
131
|
-
} catch (error) {
|
|
132
|
-
throw error;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { execa } from 'execa';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { analyzeFrontend } from '../analyzer.js';
|
|
6
|
+
import { renderAndWrite, getTemplatePath } from './template.js';
|
|
7
|
+
|
|
8
|
+
export async function generateDotnetProject(options) {
|
|
9
|
+
const { projectDir, projectName, frontendSrcDir } = options;
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
console.log(chalk.blue(' -> Analyzing frontend for C# backend...'));
|
|
13
|
+
const endpoints = await analyzeFrontend(frontendSrcDir);
|
|
14
|
+
const modelsToGenerate = new Map();
|
|
15
|
+
endpoints.forEach(ep => {
|
|
16
|
+
if (ep.schemaFields && ep.controllerName !== 'Default' && !modelsToGenerate.has(ep.controllerName)) {
|
|
17
|
+
modelsToGenerate.set(ep.controllerName, {
|
|
18
|
+
name: ep.controllerName,
|
|
19
|
+
fields: Object.entries(ep.schemaFields).map(([key, type]) => ({ name: key, type }))
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (modelsToGenerate.size > 0) {
|
|
25
|
+
console.log(chalk.green(` -> Identified ${modelsToGenerate.size} models/controllers to generate.`));
|
|
26
|
+
} else {
|
|
27
|
+
console.log(chalk.yellow(' -> No API calls with body data found. A basic API project will be created without models.'));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(chalk.blue(' -> Scaffolding .NET Core Web API project...'));
|
|
31
|
+
await execa('dotnet', ['new', 'webapi', '-n', projectName, '-o', projectDir, '--no-https']);
|
|
32
|
+
|
|
33
|
+
if (modelsToGenerate.size > 0) {
|
|
34
|
+
console.log(chalk.blue(' -> Adding NuGet packages (Entity Framework Core)...'));
|
|
35
|
+
const packages = [
|
|
36
|
+
'Microsoft.EntityFrameworkCore.Design',
|
|
37
|
+
'Microsoft.EntityFrameworkCore.InMemory'
|
|
38
|
+
];
|
|
39
|
+
for (const pkg of packages) {
|
|
40
|
+
await execa('dotnet', ['add', 'package', pkg], { cwd: projectDir });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (modelsToGenerate.size > 0) {
|
|
45
|
+
console.log(chalk.blue(' -> Generating EF Core models and DbContext...'));
|
|
46
|
+
const modelsDir = path.join(projectDir, 'Models');
|
|
47
|
+
const dataDir = path.join(projectDir, 'Data');
|
|
48
|
+
await fs.ensureDir(modelsDir);
|
|
49
|
+
await fs.ensureDir(dataDir);
|
|
50
|
+
|
|
51
|
+
for (const [modelName, modelData] of modelsToGenerate.entries()) {
|
|
52
|
+
await renderAndWrite(
|
|
53
|
+
getTemplatePath('dotnet/partials/Model.cs.ejs'),
|
|
54
|
+
path.join(modelsDir, `${modelName}.cs`),
|
|
55
|
+
{ projectName, modelName, model: modelData }
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
await renderAndWrite(
|
|
60
|
+
getTemplatePath('dotnet/partials/DbContext.cs.ejs'),
|
|
61
|
+
path.join(dataDir, 'ApplicationDbContext.cs'),
|
|
62
|
+
{ projectName, modelsToGenerate: Array.from(modelsToGenerate.values()) }
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.log(chalk.blue(' -> Configuring services in Program.cs...'));
|
|
67
|
+
const programCsPath = path.join(projectDir, 'Program.cs');
|
|
68
|
+
let programCsContent = await fs.readFile(programCsPath, 'utf-8');
|
|
69
|
+
|
|
70
|
+
let usingStatements = 'using Microsoft.EntityFrameworkCore;\nusing ' + projectName + '.Data;\n';
|
|
71
|
+
programCsContent = usingStatements + programCsContent;
|
|
72
|
+
|
|
73
|
+
let dbContextService = '// Configure the database context\nbuilder.Services.AddDbContext<ApplicationDbContext>(opt => opt.UseInMemoryDatabase("MyDb"));';
|
|
74
|
+
programCsContent = programCsContent.replace('builder.Services.AddControllers();', `builder.Services.AddControllers();\n\n${dbContextService}`);
|
|
75
|
+
|
|
76
|
+
const corsPolicy = `
|
|
77
|
+
builder.Services.AddCors(options =>
|
|
78
|
+
{
|
|
79
|
+
options.AddDefaultPolicy(
|
|
80
|
+
policy =>
|
|
81
|
+
{
|
|
82
|
+
policy.WithOrigins("http://localhost:3000", "http://localhost:5173")
|
|
83
|
+
.AllowAnyHeader()
|
|
84
|
+
.AllowAnyMethod();
|
|
85
|
+
});
|
|
86
|
+
});`;
|
|
87
|
+
programCsContent = programCsContent.replace('var app = builder.Build();', `${corsPolicy}\n\nvar app = builder.Build();\n\napp.UseCors();`);
|
|
88
|
+
|
|
89
|
+
await fs.writeFile(programCsPath, programCsContent);
|
|
90
|
+
|
|
91
|
+
console.log(chalk.blue(' -> Generating controllers with CRUD logic...'));
|
|
92
|
+
await fs.remove(path.join(projectDir, 'Controllers', 'WeatherForecastController.cs'));
|
|
93
|
+
await fs.remove(path.join(projectDir, 'WeatherForecast.cs'));
|
|
94
|
+
|
|
95
|
+
const controllersToGenerate = new Set(Array.from(modelsToGenerate.keys()));
|
|
96
|
+
endpoints.forEach(ep => {
|
|
97
|
+
if (ep.controllerName !== 'Default') controllersToGenerate.add(ep.controllerName);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
for (const controllerName of controllersToGenerate) {
|
|
101
|
+
const controllerEndpoints = endpoints.filter(
|
|
102
|
+
ep => ep.controllerName === controllerName
|
|
103
|
+
);
|
|
104
|
+
await renderAndWrite(
|
|
105
|
+
getTemplatePath('dotnet/partials/Controller.cs.ejs'),
|
|
106
|
+
path.join(projectDir, 'Controllers', `${controllerName}Controller.cs`),
|
|
107
|
+
{ projectName, controllerName, endpoints: controllerEndpoints }
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(chalk.blue(' -> Generating Docker files...'));
|
|
112
|
+
await renderAndWrite(
|
|
113
|
+
getTemplatePath('dotnet/partials/Dockerfile.ejs'),
|
|
114
|
+
path.join(projectDir, 'Dockerfile'),
|
|
115
|
+
{ projectName }
|
|
116
|
+
);
|
|
117
|
+
await renderAndWrite(
|
|
118
|
+
getTemplatePath('dotnet/partials/docker-compose.yml.ejs'),
|
|
119
|
+
path.join(projectDir, 'docker-compose.yml'),
|
|
120
|
+
{ projectName }
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
await renderAndWrite(
|
|
124
|
+
getTemplatePath('dotnet/partials/README.md.ejs'),
|
|
125
|
+
path.join(projectDir, 'README.md'),
|
|
126
|
+
{ projectName }
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
console.log(chalk.green(' -> C# backend generation is complete!'));
|
|
130
|
+
|
|
131
|
+
} catch (error) {
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|