create-backlist 5.0.4 → 5.0.6
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
CHANGED
package/src/generators/node.js
CHANGED
|
@@ -7,13 +7,18 @@ const { analyzeFrontend } = require('../analyzer');
|
|
|
7
7
|
const { renderAndWrite, getTemplatePath } = require('./template');
|
|
8
8
|
|
|
9
9
|
async function generateNodeProject(options) {
|
|
10
|
-
|
|
10
|
+
// v5.0: Destructure all new options
|
|
11
|
+
const { projectDir, projectName, frontendSrcDir, dbType, addAuth, addSeeder, extraFeatures = [] } = options;
|
|
11
12
|
const port = 8000;
|
|
12
13
|
|
|
13
14
|
try {
|
|
14
|
-
// --- Step 1:
|
|
15
|
+
// --- Step 1: Analyze Frontend ---
|
|
15
16
|
console.log(chalk.blue(' -> Analyzing frontend for API endpoints...'));
|
|
16
|
-
const endpoints = await analyzeFrontend(
|
|
17
|
+
const endpoints = await analyzeFrontend(frontendSrcDir);
|
|
18
|
+
if (endpoints.length > 0) console.log(chalk.green(` -> Found ${endpoints.length} endpoints.`));
|
|
19
|
+
else console.log(chalk.yellow(' -> No API endpoints found. A basic project will be created.'));
|
|
20
|
+
|
|
21
|
+
// --- Step 2: Identify Models to Generate ---
|
|
17
22
|
const modelsToGenerate = new Map();
|
|
18
23
|
endpoints.forEach(ep => {
|
|
19
24
|
if (ep.schemaFields && ep.controllerName !== 'Default' && !modelsToGenerate.has(ep.controllerName)) {
|
|
@@ -21,17 +26,18 @@ async function generateNodeProject(options) {
|
|
|
21
26
|
}
|
|
22
27
|
});
|
|
23
28
|
if (addAuth && !modelsToGenerate.has('User')) {
|
|
29
|
+
console.log(chalk.yellow(' -> Authentication requires a "User" model. Creating a default one.'));
|
|
24
30
|
modelsToGenerate.set('User', { name: 'User', fields: [{ name: 'name', type: 'String' }, { name: 'email', type: 'String', isUnique: true }, { name: 'password', type: 'String' }] });
|
|
25
31
|
}
|
|
26
|
-
|
|
27
|
-
// --- Step
|
|
32
|
+
|
|
33
|
+
// --- Step 3: Base Scaffolding ---
|
|
28
34
|
console.log(chalk.blue(' -> Scaffolding Node.js project...'));
|
|
29
35
|
const destSrcDir = path.join(projectDir, 'src');
|
|
30
36
|
await fs.ensureDir(destSrcDir);
|
|
31
37
|
await fs.copy(getTemplatePath('node-ts-express/base/server.ts'), path.join(destSrcDir, 'server.ts'));
|
|
32
38
|
await fs.copy(getTemplatePath('node-ts-express/base/tsconfig.json'), path.join(projectDir, 'tsconfig.json'));
|
|
33
39
|
|
|
34
|
-
// --- Step
|
|
40
|
+
// --- Step 4: Prepare and Write package.json ---
|
|
35
41
|
const packageJsonContent = JSON.parse(await ejs.renderFile(getTemplatePath('node-ts-express/partials/package.json.ejs'), { projectName }));
|
|
36
42
|
|
|
37
43
|
if (dbType === 'mongoose') packageJsonContent.dependencies['mongoose'] = '^7.6.3';
|
|
@@ -49,8 +55,8 @@ async function generateNodeProject(options) {
|
|
|
49
55
|
if (addSeeder) {
|
|
50
56
|
packageJsonContent.devDependencies['@faker-js/faker'] = '^8.3.1';
|
|
51
57
|
if (!packageJsonContent.dependencies['chalk']) packageJsonContent.dependencies['chalk'] = '^4.1.2';
|
|
52
|
-
packageJsonContent.scripts['seed'] =
|
|
53
|
-
packageJsonContent.scripts['destroy'] =
|
|
58
|
+
packageJsonContent.scripts['seed'] = `ts-node scripts/seeder.ts`;
|
|
59
|
+
packageJsonContent.scripts['destroy'] = `ts-node scripts/seeder.ts -d`;
|
|
54
60
|
}
|
|
55
61
|
if (extraFeatures.includes('testing')) {
|
|
56
62
|
packageJsonContent.devDependencies['jest'] = '^29.7.0';
|
|
@@ -67,7 +73,7 @@ async function generateNodeProject(options) {
|
|
|
67
73
|
}
|
|
68
74
|
await fs.writeJson(path.join(projectDir, 'package.json'), packageJsonContent, { spaces: 2 });
|
|
69
75
|
|
|
70
|
-
// --- Step
|
|
76
|
+
// --- Step 5: Generate DB-specific files & Controllers ---
|
|
71
77
|
if (modelsToGenerate.size > 0) {
|
|
72
78
|
await fs.ensureDir(path.join(destSrcDir, 'controllers'));
|
|
73
79
|
if (dbType === 'mongoose') {
|
|
@@ -82,7 +88,6 @@ async function generateNodeProject(options) {
|
|
|
82
88
|
await fs.ensureDir(path.join(projectDir, 'prisma'));
|
|
83
89
|
await renderAndWrite(getTemplatePath('node-ts-express/partials/PrismaSchema.prisma.ejs'), path.join(projectDir, 'prisma', 'schema.prisma'), { modelsToGenerate: Array.from(modelsToGenerate.values()) });
|
|
84
90
|
}
|
|
85
|
-
// Generate controllers for both DB types
|
|
86
91
|
console.log(chalk.blue(' -> Generating controllers...'));
|
|
87
92
|
for (const [modelName] of modelsToGenerate.entries()) {
|
|
88
93
|
const templateFile = dbType === 'mongoose' ? 'Controller.ts.ejs' : 'PrismaController.ts.ejs';
|
|
@@ -90,7 +95,7 @@ async function generateNodeProject(options) {
|
|
|
90
95
|
}
|
|
91
96
|
}
|
|
92
97
|
|
|
93
|
-
// --- Step
|
|
98
|
+
// --- Step 6: Generate Authentication Boilerplate ---
|
|
94
99
|
if (addAuth) {
|
|
95
100
|
console.log(chalk.blue(' -> Generating authentication boilerplate...'));
|
|
96
101
|
await fs.ensureDir(path.join(destSrcDir, 'routes'));
|
|
@@ -112,12 +117,34 @@ async function generateNodeProject(options) {
|
|
|
112
117
|
}
|
|
113
118
|
}
|
|
114
119
|
}
|
|
115
|
-
if (addSeeder) { /* ... Seeder logic as before ... */ }
|
|
116
|
-
if (extraFeatures.includes('docker')) { /* ... Docker logic as before ... */ }
|
|
117
|
-
if (extraFeatures.includes('swagger')) { /* ... Swagger logic as before ... */ }
|
|
118
|
-
if (extraFeatures.includes('testing')) { /* ... Testing logic as before ... */ }
|
|
119
120
|
|
|
120
|
-
// --- Step
|
|
121
|
+
// --- Step 7: Generate Seeder Script ---
|
|
122
|
+
if (addSeeder) {
|
|
123
|
+
console.log(chalk.blue(' -> Generating database seeder script...'));
|
|
124
|
+
await fs.ensureDir(path.join(projectDir, 'scripts'));
|
|
125
|
+
await renderAndWrite(getTemplatePath('node-ts-express/partials/Seeder.ts.ejs'), path.join(projectDir, 'scripts', 'seeder.ts'), { projectName });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// --- Step 8: Generate Extra Features ---
|
|
129
|
+
if (extraFeatures.includes('docker')) {
|
|
130
|
+
console.log(chalk.blue(' -> Generating Docker files...'));
|
|
131
|
+
await renderAndWrite(getTemplatePath('node-ts-express/partials/Dockerfile.ejs'), path.join(projectDir, 'Dockerfile'), { dbType, port });
|
|
132
|
+
await renderAndWrite(getTemplatePath('node-ts-express/partials/docker-compose.yml.ejs'), path.join(projectDir, 'docker-compose.yml'), { projectName, dbType, port });
|
|
133
|
+
}
|
|
134
|
+
if (extraFeatures.includes('swagger')) {
|
|
135
|
+
console.log(chalk.blue(' -> Generating API documentation setup...'));
|
|
136
|
+
await fs.ensureDir(path.join(destSrcDir, 'utils'));
|
|
137
|
+
await renderAndWrite(getTemplatePath('node-ts-express/partials/ApiDocs.ts.ejs'), path.join(destSrcDir, 'utils', 'swagger.ts'), { projectName, port });
|
|
138
|
+
}
|
|
139
|
+
if (extraFeatures.includes('testing')) {
|
|
140
|
+
console.log(chalk.blue(' -> Generating testing boilerplate...'));
|
|
141
|
+
const jestConfig = `/** @type {import('ts-jest').JestConfigWithTsJest} */\nmodule.exports = {\n preset: 'ts-jest',\n testEnvironment: 'node',\n verbose: true,\n};`;
|
|
142
|
+
await fs.writeFile(path.join(projectDir, 'jest.config.js'), jestConfig);
|
|
143
|
+
await fs.ensureDir(path.join(projectDir, 'src', '__tests__'));
|
|
144
|
+
await renderAndWrite(getTemplatePath('node-ts-express/partials/App.test.ts.ejs'), path.join(projectDir, 'src', '__tests__', 'api.test.ts'), { addAuth });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// --- Step 9: Generate Main Route File & Inject Logic into Server ---
|
|
121
148
|
await renderAndWrite(getTemplatePath('node-ts-express/partials/routes.ts.ejs'), path.join(destSrcDir, 'routes.ts'), { endpoints, addAuth, dbType });
|
|
122
149
|
|
|
123
150
|
let serverFileContent = await fs.readFile(path.join(destSrcDir, 'server.ts'), 'utf-8');
|
|
@@ -143,17 +170,27 @@ async function generateNodeProject(options) {
|
|
|
143
170
|
serverFileContent = serverFileContent.replace(listenRegex, `${swaggerInjector}\n$1`);
|
|
144
171
|
await fs.writeFile(path.join(destSrcDir, 'server.ts'), serverFileContent);
|
|
145
172
|
|
|
146
|
-
// --- Step
|
|
147
|
-
console.log(chalk.magenta(' -> Installing dependencies...'));
|
|
173
|
+
// --- Step 10: Install Dependencies & Run Post-install Scripts ---
|
|
174
|
+
console.log(chalk.magenta(' -> Installing dependencies... This may take a moment.'));
|
|
148
175
|
await execa('npm', ['install'], { cwd: projectDir });
|
|
149
176
|
if (dbType === 'prisma') {
|
|
150
177
|
console.log(chalk.blue(' -> Running `prisma generate`...'));
|
|
151
178
|
await execa('npx', ['prisma', 'generate'], { cwd: projectDir });
|
|
152
179
|
}
|
|
153
180
|
|
|
154
|
-
// --- Step
|
|
155
|
-
|
|
156
|
-
|
|
181
|
+
// --- Step 11: Generate Final Files (.env.example) ---
|
|
182
|
+
let envContent = `PORT=${port}\n`;
|
|
183
|
+
if (dbType === 'mongoose') {
|
|
184
|
+
envContent += `MONGO_URI=mongodb://root:example@db:27017/${projectName}?authSource=admin\n`;
|
|
185
|
+
} else if (dbType === 'prisma') {
|
|
186
|
+
envContent += `DATABASE_URL="postgresql://user:password@db:5432/${projectName}?schema=public"\n`;
|
|
187
|
+
}
|
|
188
|
+
if (addAuth) envContent += `JWT_SECRET=your_super_secret_jwt_key_12345\n`;
|
|
189
|
+
if (extraFeatures.includes('docker')) {
|
|
190
|
+
envContent += `\n# Docker-compose credentials (used in docker-compose.yml)\nDB_USER=user\nDB_PASSWORD=password\nDB_NAME=${projectName}`;
|
|
191
|
+
}
|
|
192
|
+
await fs.writeFile(path.join(projectDir, '.env.example'), envContent);
|
|
193
|
+
|
|
157
194
|
} catch (error) {
|
|
158
195
|
throw error;
|
|
159
196
|
}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
const ejs = require('ejs');
|
|
2
1
|
const fs = require('fs-extra');
|
|
2
|
+
const ejs = require('ejs');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
5
|
-
async function renderAndWrite(templatePath,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
async function renderAndWrite(templatePath, outPath, data) {
|
|
6
|
+
try {
|
|
7
|
+
const tpl = await fs.readFile(templatePath, 'utf-8');
|
|
8
|
+
const code = ejs.render(tpl, data || {}, { filename: templatePath }); // filename helps with EJS errors
|
|
9
|
+
await fs.outputFile(outPath, code);
|
|
10
|
+
} catch (err) {
|
|
11
|
+
console.error('EJS render failed for:', templatePath);
|
|
12
|
+
console.error('Data keys:', Object.keys(data || {}));
|
|
13
|
+
throw err;
|
|
14
|
+
}
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
function getTemplatePath(subpath) {
|
|
@@ -1,42 +1,44 @@
|
|
|
1
|
-
// Auto-generated by create-backlist
|
|
1
|
+
// Auto-generated by create-backlist on <%= new Date().toISOString() %>
|
|
2
2
|
import { Request, Response } from 'express';
|
|
3
3
|
import bcrypt from 'bcryptjs';
|
|
4
4
|
import jwt from 'jsonwebtoken';
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
<% if (dbType === 'mongoose') { %>
|
|
7
|
+
import User from '../models/User.model';
|
|
8
|
+
<% } else if (dbType === 'prisma') { %>
|
|
9
|
+
import { prisma } from '../server';
|
|
10
|
+
<% } %>
|
|
6
11
|
|
|
7
12
|
// @desc Register a new user
|
|
8
13
|
export const registerUser = async (req: Request, res: Response) => {
|
|
9
14
|
const { name, email, password } = req.body;
|
|
10
15
|
|
|
11
16
|
try {
|
|
12
|
-
|
|
17
|
+
<% if (dbType === 'mongoose') { %>
|
|
18
|
+
// Mongoose Logic
|
|
13
19
|
let user = await User.findOne({ email });
|
|
14
20
|
if (user) {
|
|
15
21
|
return res.status(400).json({ message: 'User already exists' });
|
|
16
22
|
}
|
|
17
|
-
|
|
18
|
-
// Create a new user instance
|
|
19
|
-
user = new User({
|
|
20
|
-
name,
|
|
21
|
-
email,
|
|
22
|
-
password, // Password will be hashed by the pre-save hook in the model
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// Save the user to the database
|
|
23
|
+
user = new User({ name, email, password });
|
|
26
24
|
await user.save();
|
|
25
|
+
<% } else if (dbType === 'prisma') { %>
|
|
26
|
+
// Prisma Logic
|
|
27
|
+
const existingUser = await prisma.user.findUnique({ where: { email } });
|
|
28
|
+
if (existingUser) {
|
|
29
|
+
return res.status(400).json({ message: 'User already exists' });
|
|
30
|
+
}
|
|
31
|
+
const hashedPassword = await bcrypt.hash(password, 10);
|
|
32
|
+
const user = await prisma.user.create({
|
|
33
|
+
data: { name, email, password: hashedPassword },
|
|
34
|
+
});
|
|
35
|
+
<% } %>
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
const payload = {
|
|
30
|
-
user: {
|
|
31
|
-
id: user.id,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// Sign the token
|
|
37
|
+
const payload = { user: { id: user.id } };
|
|
36
38
|
jwt.sign(
|
|
37
39
|
payload,
|
|
38
40
|
process.env.JWT_SECRET as string,
|
|
39
|
-
{ expiresIn: '5h' },
|
|
41
|
+
{ expiresIn: '5h' },
|
|
40
42
|
(err, token) => {
|
|
41
43
|
if (err) throw err;
|
|
42
44
|
res.status(201).json({ token });
|
|
@@ -53,26 +55,24 @@ export const loginUser = async (req: Request, res: Response) => {
|
|
|
53
55
|
const { email, password } = req.body;
|
|
54
56
|
|
|
55
57
|
try {
|
|
56
|
-
|
|
58
|
+
<% if (dbType === 'mongoose') { %>
|
|
59
|
+
// Mongoose Logic
|
|
57
60
|
const user = await User.findOne({ email });
|
|
61
|
+
<% } else if (dbType === 'prisma') { %>
|
|
62
|
+
// Prisma Logic
|
|
63
|
+
const user = await prisma.user.findUnique({ where: { email } });
|
|
64
|
+
<% } %>
|
|
65
|
+
|
|
58
66
|
if (!user) {
|
|
59
67
|
return res.status(400).json({ message: 'Invalid Credentials' });
|
|
60
68
|
}
|
|
61
69
|
|
|
62
|
-
// Compare entered password with stored hashed password
|
|
63
70
|
const isMatch = await bcrypt.compare(password, user.password);
|
|
64
71
|
if (!isMatch) {
|
|
65
72
|
return res.status(400).json({ message: 'Invalid Credentials' });
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
const payload = {
|
|
70
|
-
user: {
|
|
71
|
-
id: user.id,
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// Sign the token
|
|
75
|
+
const payload = { user: { id: user.id } };
|
|
76
76
|
jwt.sign(
|
|
77
77
|
payload,
|
|
78
78
|
process.env.JWT_SECRET as string,
|
|
@@ -1,125 +1,50 @@
|
|
|
1
|
-
// Auto-generated by create-backlist
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// PUT: api/<%= controllerName.toLowerCase() %>/{id}
|
|
52
|
-
// Updates a specific item.
|
|
53
|
-
[HttpPut("{id}")]
|
|
54
|
-
public async Task<IActionResult> Put<%= controllerName %>(Guid id, <%= controllerName %> item)
|
|
55
|
-
{
|
|
56
|
-
if (id != item.Id)
|
|
57
|
-
{
|
|
58
|
-
return BadRequest();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
_context.Entry(item).State = EntityState.Modified;
|
|
62
|
-
|
|
63
|
-
try
|
|
64
|
-
{
|
|
65
|
-
await _context.SaveChangesAsync();
|
|
66
|
-
}
|
|
67
|
-
catch (DbUpdateConcurrencyException)
|
|
68
|
-
{
|
|
69
|
-
if (!ItemExists(id))
|
|
70
|
-
{
|
|
71
|
-
return NotFound();
|
|
72
|
-
}
|
|
73
|
-
else
|
|
74
|
-
{
|
|
75
|
-
throw;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return NoContent();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// POST: api/<%= controllerName.toLowerCase() %>
|
|
83
|
-
// Creates a new item.
|
|
84
|
-
[HttpPost]
|
|
85
|
-
public async Task<ActionResult<<%= controllerName %>>> Post<%= controllerName %>(<%= controllerName %> item)
|
|
86
|
-
{
|
|
87
|
-
if (_context.<%= controllerName %>s == null)
|
|
88
|
-
{
|
|
89
|
-
return Problem("Entity set '<%= controllerName %>s' is null.");
|
|
90
|
-
}
|
|
91
|
-
// Ensure a new Guid is created for the new item
|
|
92
|
-
item.Id = Guid.NewGuid();
|
|
93
|
-
_context.<%= controllerName %>s.Add(item);
|
|
94
|
-
await _context.SaveChangesAsync();
|
|
95
|
-
|
|
96
|
-
return CreatedAtAction(nameof(Get<%= controllerName %>), new { id = item.Id }, item);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// DELETE: api/<%= controllerName.toLowerCase() %>/{id}
|
|
100
|
-
// Deletes a specific item.
|
|
101
|
-
[HttpDelete("{id}")]
|
|
102
|
-
public async Task<IActionResult> Delete<%= controllerName %>(Guid id)
|
|
103
|
-
{
|
|
104
|
-
if (_context.<%= controllerName %>s == null)
|
|
105
|
-
{
|
|
106
|
-
return NotFound();
|
|
107
|
-
}
|
|
108
|
-
var item = await _context.<%= controllerName %>s.FindAsync(id);
|
|
109
|
-
if (item == null)
|
|
110
|
-
{
|
|
111
|
-
return NotFound();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
_context.<%= controllerName %>s.Remove(item);
|
|
115
|
-
await _context.SaveChangesAsync();
|
|
116
|
-
|
|
117
|
-
return NoContent();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private bool ItemExists(Guid id)
|
|
121
|
-
{
|
|
122
|
-
return (_context.<%= controllerName %>s?.Any(e => e.Id == id)).GetValueOrDefault();
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
1
|
+
// Auto-generated by create-backlist on <%= new Date().toISOString() %>
|
|
2
|
+
import { Request, Response } from 'express';
|
|
3
|
+
|
|
4
|
+
export const create<%= modelName %> = async (req: Request, res: Response) => {
|
|
5
|
+
try {
|
|
6
|
+
// TODO: implement create logic
|
|
7
|
+
res.status(201).json({ message: '<%= modelName %> created', data: req.body });
|
|
8
|
+
} catch (error) {
|
|
9
|
+
res.status(500).json({ message: 'Error creating <%= modelName %>', error });
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const getAll<%= modelName %>s = async (_req: Request, res: Response) => {
|
|
14
|
+
try {
|
|
15
|
+
// TODO: implement list logic
|
|
16
|
+
res.status(200).json([]);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
res.status(500).json({ message: 'Error fetching <%= modelName %>s', error });
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const get<%= modelName %>ById = async (req: Request, res: Response) => {
|
|
23
|
+
try {
|
|
24
|
+
const { id } = req.params;
|
|
25
|
+
// TODO: implement get by id logic
|
|
26
|
+
res.status(200).json({ id });
|
|
27
|
+
} catch (error) {
|
|
28
|
+
res.status(500).json({ message: 'Error fetching <%= modelName %>', error });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const update<%= modelName %>ById = async (req: Request, res: Response) => {
|
|
33
|
+
try {
|
|
34
|
+
const { id } = req.params;
|
|
35
|
+
// TODO: implement update logic
|
|
36
|
+
res.status(200).json({ id, ...req.body });
|
|
37
|
+
} catch (error) {
|
|
38
|
+
res.status(500).json({ message: 'Error updating <%= modelName %>', error });
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const delete<%= modelName %>ById = async (req: Request, res: Response) => {
|
|
43
|
+
try {
|
|
44
|
+
const { id } = req.params;
|
|
45
|
+
// TODO: implement delete logic
|
|
46
|
+
res.status(204).send();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
res.status(500).json({ message: 'Error deleting <%= modelName %>', error });
|
|
49
|
+
}
|
|
50
|
+
};
|