create-backlist 7.3.0 → 7.4.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 +483 -470
- package/bin/qa.js +103 -0
- package/package.json +7 -3
- package/src/analyzer.js +221 -21
- package/src/env-resolver.js +70 -0
- 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 -0
- package/src/qa/qa-engine.js +909 -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/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
|
+
}
|