@diagramers/cli 4.0.19 → 4.0.21
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/dist/commands/api.d.ts.map +1 -1
- package/dist/commands/api.js +368 -9
- package/dist/commands/api.js.map +1 -1
- package/dist/commands/extend.d.ts.map +1 -1
- package/dist/commands/extend.js +125 -4
- package/dist/commands/extend.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +84 -5
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/services/api-generator.d.ts +1 -1
- package/dist/services/api-generator.d.ts.map +1 -1
- package/dist/services/api-generator.js +525 -223
- package/dist/services/api-generator.js.map +1 -1
- package/dist/services/project-extender.d.ts.map +1 -1
- package/dist/services/project-extender.js +422 -247
- package/dist/services/project-extender.js.map +1 -1
- package/dist/services/relation-generator.d.ts +1 -1
- package/dist/services/relation-generator.d.ts.map +1 -1
- package/dist/services/relation-generator.js +15 -1
- package/dist/services/relation-generator.js.map +1 -1
- package/dist/services/table-generator.d.ts.map +1 -1
- package/dist/services/table-generator.js +27 -18
- package/dist/services/table-generator.js.map +1 -1
- package/dist/services/template-updater.d.ts +2 -0
- package/dist/services/template-updater.d.ts.map +1 -1
- package/dist/services/template-updater.js +109 -3
- package/dist/services/template-updater.js.map +1 -1
- package/package.json +1 -1
|
@@ -125,39 +125,108 @@ class ProjectExtender {
|
|
|
125
125
|
const projectPath = process.cwd();
|
|
126
126
|
// Check if module already exists
|
|
127
127
|
const modulePath = path.join(projectPath, 'src', 'modules', moduleName);
|
|
128
|
-
if (await fs.pathExists(modulePath)) {
|
|
129
|
-
throw new Error(`Module '${moduleName}' already exists
|
|
128
|
+
if (await fs.pathExists(modulePath) && !options.force) {
|
|
129
|
+
throw new Error(`Module '${moduleName}' already exists. Use --force to override.`);
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
// Parse options
|
|
132
|
+
const fields = options.fields || ['name', 'description', 'status'];
|
|
133
|
+
const generateRoutes = options.generateRoutes !== false;
|
|
134
|
+
const generateDatabase = options.generateDatabase !== false;
|
|
135
|
+
const crud = options.crud || false;
|
|
136
|
+
console.log(chalk_1.default.blue(`📦 Generating module '${moduleName}'...`));
|
|
137
|
+
// Create module structure
|
|
138
|
+
await this.createModuleStructure(projectPath, moduleName, { fields, crud, generateRoutes, generateDatabase });
|
|
134
139
|
// Generate CRUD operations if requested
|
|
135
|
-
if (
|
|
136
|
-
|
|
140
|
+
if (crud) {
|
|
141
|
+
console.log(chalk_1.default.blue('🔧 Generating CRUD operations...'));
|
|
142
|
+
await this.generateCRUDOperations(projectPath, moduleName, { fields });
|
|
137
143
|
}
|
|
138
|
-
//
|
|
144
|
+
// Register module
|
|
139
145
|
await this.registerModule(projectPath, moduleName);
|
|
140
|
-
// Update
|
|
141
|
-
await this.
|
|
146
|
+
// Update configuration
|
|
147
|
+
await this.updateDiagramersConfig(projectPath, moduleName);
|
|
142
148
|
console.log(chalk_1.default.green(`✅ Module '${moduleName}' generated successfully!`));
|
|
149
|
+
console.log(chalk_1.default.blue(`📁 Location: src/modules/${moduleName}/`));
|
|
150
|
+
if (generateRoutes) {
|
|
151
|
+
console.log(chalk_1.default.blue(`🔗 Routes: /api/${moduleName}s`));
|
|
152
|
+
}
|
|
153
|
+
if (generateDatabase) {
|
|
154
|
+
console.log(chalk_1.default.blue(`🗄️ Database: ${moduleName} collection`));
|
|
155
|
+
}
|
|
156
|
+
if (crud) {
|
|
157
|
+
console.log(chalk_1.default.blue(`🔧 CRUD: Full CRUD operations included`));
|
|
158
|
+
}
|
|
143
159
|
}
|
|
144
160
|
async generateTable(tableName, options = {}) {
|
|
145
161
|
const projectPath = process.cwd();
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
// Parse options
|
|
163
|
+
const fields = options.fields || ['name', 'description', 'status'];
|
|
164
|
+
const databaseType = options.type || 'mongodb';
|
|
165
|
+
const generateSeeder = options.seeder !== false;
|
|
166
|
+
const force = options.force || false;
|
|
167
|
+
console.log(chalk_1.default.blue(`🗄️ Generating table '${tableName}'...`));
|
|
168
|
+
// Create table schema
|
|
169
|
+
await this.createTableSchema(projectPath, tableName, { fields, type: databaseType, force });
|
|
170
|
+
// Add to seeder if requested
|
|
171
|
+
if (generateSeeder) {
|
|
172
|
+
console.log(chalk_1.default.blue('🌱 Adding to database seeder...'));
|
|
173
|
+
await this.updateSeeder(projectPath, tableName);
|
|
174
|
+
}
|
|
149
175
|
console.log(chalk_1.default.green(`✅ Table '${tableName}' generated successfully!`));
|
|
176
|
+
console.log(chalk_1.default.blue(`📁 Schema: src/modules/${tableName}/schemas/${tableName}.schema.ts`));
|
|
177
|
+
console.log(chalk_1.default.blue(`🗄️ Database Type: ${databaseType}`));
|
|
178
|
+
if (generateSeeder) {
|
|
179
|
+
console.log(chalk_1.default.blue(`🌱 Seeder: Added to src/core/database/seeder.ts`));
|
|
180
|
+
}
|
|
150
181
|
}
|
|
151
182
|
async generateRelations(relationName, options = {}) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
183
|
+
console.log(chalk_1.default.blue(`🔗 Generating relations for '${relationName}'...`));
|
|
184
|
+
// Parse options
|
|
185
|
+
const relationType = options.type || 'one-to-many';
|
|
186
|
+
const moduleName = options.module;
|
|
187
|
+
const force = options.force || false;
|
|
188
|
+
// For now, we'll use a simple approach - the user needs to specify both tables
|
|
189
|
+
if (!options.table1 || !options.table2) {
|
|
190
|
+
throw new Error('Both table1 and table2 must be specified for relation generation. Use: --table1 <name> --table2 <name>');
|
|
191
|
+
}
|
|
192
|
+
// Import and use the relation-generator service
|
|
193
|
+
const { generateRelation } = await Promise.resolve().then(() => __importStar(require('./relation-generator')));
|
|
194
|
+
await generateRelation(moduleName, options.table1, options.table2, relationType, { force });
|
|
195
|
+
console.log(chalk_1.default.green(`✅ Relations generated successfully for '${relationName}'!`));
|
|
196
|
+
console.log(chalk_1.default.blue(`🔗 Type: ${relationType}`));
|
|
197
|
+
console.log(chalk_1.default.blue(`📦 Module: ${moduleName}`));
|
|
198
|
+
console.log(chalk_1.default.blue(`🗄️ Tables: ${options.table1} ↔ ${options.table2}`));
|
|
157
199
|
}
|
|
158
200
|
async generateEndpoint(moduleName, endpointName, options = {}) {
|
|
159
|
-
|
|
160
|
-
|
|
201
|
+
console.log(chalk_1.default.blue(`🔧 Adding endpoint '${endpointName}' to module '${moduleName}'...`));
|
|
202
|
+
// Parse options
|
|
203
|
+
const method = options.method || 'GET';
|
|
204
|
+
const customPath = options.path || endpointName;
|
|
205
|
+
const description = options.description || `${endpointName} endpoint for ${moduleName}`;
|
|
206
|
+
const generateService = options.generateService !== false;
|
|
207
|
+
const generateController = options.generateController !== false;
|
|
208
|
+
const generateRoute = options.generateRoute !== false;
|
|
209
|
+
const force = options.force || false;
|
|
210
|
+
// Pass options to the api-generator service
|
|
211
|
+
await (0, api_generator_1.generateEndpoint)(moduleName, endpointName, {
|
|
212
|
+
method,
|
|
213
|
+
path: customPath,
|
|
214
|
+
description,
|
|
215
|
+
generateService,
|
|
216
|
+
generateController,
|
|
217
|
+
generateRoute,
|
|
218
|
+
force
|
|
219
|
+
});
|
|
220
|
+
console.log(chalk_1.default.green(`✅ Endpoint '${endpointName}' added to module '${moduleName}' successfully!`));
|
|
221
|
+
if (generateService) {
|
|
222
|
+
console.log(chalk_1.default.blue(`📝 Service method generated`));
|
|
223
|
+
}
|
|
224
|
+
if (generateController) {
|
|
225
|
+
console.log(chalk_1.default.blue(`🎮 Controller method generated`));
|
|
226
|
+
}
|
|
227
|
+
if (generateRoute) {
|
|
228
|
+
console.log(chalk_1.default.blue(`🛣️ Route generated`));
|
|
229
|
+
}
|
|
161
230
|
}
|
|
162
231
|
async addServiceMethod(modulePath, moduleName, endpointName, method, description) {
|
|
163
232
|
const singularName = moduleName; // Use exact name provided by developer
|
|
@@ -1129,6 +1198,9 @@ export class ${capitalizedName}Feature {
|
|
|
1129
1198
|
}
|
|
1130
1199
|
async createModuleStructure(projectPath, moduleName, options) {
|
|
1131
1200
|
const modulePath = path.join(projectPath, 'src', 'modules', moduleName);
|
|
1201
|
+
// Convert module name to valid TypeScript identifiers
|
|
1202
|
+
const moduleNameCamelCase = moduleName.replace(/[-_]([a-z0-9])/g, (_, char) => char.toUpperCase());
|
|
1203
|
+
const moduleNameCapitalized = moduleNameCamelCase.charAt(0).toUpperCase() + moduleNameCamelCase.slice(1);
|
|
1132
1204
|
// Create module directory structure
|
|
1133
1205
|
const structure = {
|
|
1134
1206
|
'entities': 'Data models and interfaces',
|
|
@@ -1140,26 +1212,26 @@ export class ${capitalizedName}Feature {
|
|
|
1140
1212
|
for (const [dir, description] of Object.entries(structure)) {
|
|
1141
1213
|
const dirPath = path.join(modulePath, dir);
|
|
1142
1214
|
await fs.ensureDir(dirPath);
|
|
1143
|
-
// Create index file with correct file extensions
|
|
1215
|
+
// Create index file with correct file extensions - use camelCase for file names
|
|
1144
1216
|
let fileName = '';
|
|
1145
1217
|
switch (dir) {
|
|
1146
1218
|
case 'entities':
|
|
1147
|
-
fileName = `${
|
|
1219
|
+
fileName = `${moduleNameCamelCase}.entity`;
|
|
1148
1220
|
break;
|
|
1149
1221
|
case 'schemas':
|
|
1150
|
-
fileName = `${
|
|
1222
|
+
fileName = `${moduleNameCamelCase}.schema`;
|
|
1151
1223
|
break;
|
|
1152
1224
|
case 'services':
|
|
1153
|
-
fileName = `${
|
|
1225
|
+
fileName = `${moduleNameCamelCase}.service`;
|
|
1154
1226
|
break;
|
|
1155
1227
|
case 'controllers':
|
|
1156
|
-
fileName = `${
|
|
1228
|
+
fileName = `${moduleNameCamelCase}.controller`;
|
|
1157
1229
|
break;
|
|
1158
1230
|
case 'routes':
|
|
1159
|
-
fileName = `${
|
|
1231
|
+
fileName = `${moduleNameCamelCase}.routes`;
|
|
1160
1232
|
break;
|
|
1161
1233
|
default:
|
|
1162
|
-
fileName = `${
|
|
1234
|
+
fileName = `${moduleNameCamelCase}.${dir.slice(0, -1)}`;
|
|
1163
1235
|
}
|
|
1164
1236
|
const indexContent = `// ${description} for ${moduleName} module
|
|
1165
1237
|
export * from './${fileName}';
|
|
@@ -1167,22 +1239,23 @@ export * from './${fileName}';
|
|
|
1167
1239
|
await fs.writeFile(path.join(dirPath, 'index.ts'), indexContent);
|
|
1168
1240
|
}
|
|
1169
1241
|
// Create main entity
|
|
1170
|
-
await this.createEntity(modulePath,
|
|
1242
|
+
await this.createEntity(modulePath, moduleNameCamelCase, options);
|
|
1171
1243
|
// Create schema
|
|
1172
|
-
await this.createSchema(modulePath,
|
|
1244
|
+
await this.createSchema(modulePath, moduleNameCamelCase, options);
|
|
1173
1245
|
// Create service
|
|
1174
|
-
await this.createService(modulePath,
|
|
1246
|
+
await this.createService(modulePath, moduleNameCamelCase, options);
|
|
1175
1247
|
// Create controller
|
|
1176
|
-
await this.createController(modulePath,
|
|
1248
|
+
await this.createController(modulePath, moduleNameCamelCase, options);
|
|
1177
1249
|
// Create routes
|
|
1178
|
-
await this.createRoutes(modulePath,
|
|
1250
|
+
await this.createRoutes(modulePath, moduleNameCamelCase, options);
|
|
1179
1251
|
}
|
|
1180
|
-
async createEntity(modulePath,
|
|
1181
|
-
|
|
1252
|
+
async createEntity(modulePath, moduleNameCamelCase, options) {
|
|
1253
|
+
// Convert module name to valid TypeScript identifiers
|
|
1254
|
+
const moduleNameCapitalized = moduleNameCamelCase.charAt(0).toUpperCase() + moduleNameCamelCase.slice(1);
|
|
1182
1255
|
const entityContent = `import * as mongoose from 'mongoose';
|
|
1183
1256
|
import { ObjectId } from "bson";
|
|
1184
1257
|
|
|
1185
|
-
export interface I${
|
|
1258
|
+
export interface I${moduleNameCapitalized} extends mongoose.Document {
|
|
1186
1259
|
_id: ObjectId,
|
|
1187
1260
|
name: string,
|
|
1188
1261
|
description?: string,
|
|
@@ -1190,14 +1263,15 @@ export interface I${entityName} extends mongoose.Document {
|
|
|
1190
1263
|
createdAt: Date,
|
|
1191
1264
|
updatedAt: Date
|
|
1192
1265
|
}`;
|
|
1193
|
-
await fs.writeFile(path.join(modulePath, 'entities', `${
|
|
1266
|
+
await fs.writeFile(path.join(modulePath, 'entities', `${moduleNameCamelCase}.entity.ts`), entityContent);
|
|
1194
1267
|
}
|
|
1195
|
-
async createSchema(modulePath,
|
|
1196
|
-
|
|
1268
|
+
async createSchema(modulePath, moduleNameCamelCase, options) {
|
|
1269
|
+
// Convert module name to valid TypeScript identifiers
|
|
1270
|
+
const moduleNameCapitalized = moduleNameCamelCase.charAt(0).toUpperCase() + moduleNameCamelCase.slice(1);
|
|
1197
1271
|
const schemaContent = `import * as mongoose from 'mongoose';
|
|
1198
|
-
import { I${
|
|
1272
|
+
import { I${moduleNameCapitalized} } from '../entities/${moduleNameCamelCase}.entity';
|
|
1199
1273
|
|
|
1200
|
-
export const ${
|
|
1274
|
+
export const ${moduleNameCamelCase}Schema = new mongoose.Schema(
|
|
1201
1275
|
{
|
|
1202
1276
|
name: {
|
|
1203
1277
|
type: mongoose.SchemaTypes.String,
|
|
@@ -1215,57 +1289,117 @@ export const ${moduleName}Schema = new mongoose.Schema(
|
|
|
1215
1289
|
{ timestamps: true, suppressReservedKeysWarning: true },
|
|
1216
1290
|
);
|
|
1217
1291
|
|
|
1218
|
-
export const ${
|
|
1219
|
-
await fs.writeFile(path.join(modulePath, 'schemas', `${
|
|
1292
|
+
export const ${moduleNameCapitalized}Model = mongoose.model<I${moduleNameCapitalized}>('${moduleNameCapitalized}', ${moduleNameCamelCase}Schema);`;
|
|
1293
|
+
await fs.writeFile(path.join(modulePath, 'schemas', `${moduleNameCamelCase}.schema.ts`), schemaContent);
|
|
1220
1294
|
}
|
|
1221
|
-
async createService(modulePath,
|
|
1222
|
-
|
|
1295
|
+
async createService(modulePath, moduleNameCamelCase, options) {
|
|
1296
|
+
// Convert module name to valid TypeScript identifiers
|
|
1297
|
+
const moduleNameCapitalized = moduleNameCamelCase.charAt(0).toUpperCase() + moduleNameCamelCase.slice(1);
|
|
1223
1298
|
const serviceContent = `import { ObjectId } from "bson";
|
|
1224
|
-
import { ${
|
|
1299
|
+
import { ${moduleNameCapitalized}Model } from '../schemas/${moduleNameCamelCase}.schema';
|
|
1225
1300
|
|
|
1226
|
-
export class ${
|
|
1301
|
+
export class ${moduleNameCapitalized}Service {
|
|
1227
1302
|
async getAll() {
|
|
1228
|
-
|
|
1303
|
+
try {
|
|
1304
|
+
const data = await ${moduleNameCapitalized}Model.find({ status: 1 });
|
|
1305
|
+
return {
|
|
1306
|
+
Data: data,
|
|
1307
|
+
StatusCode: 1000,
|
|
1308
|
+
Message: '${moduleNameCapitalized}s retrieved successfully'
|
|
1309
|
+
};
|
|
1310
|
+
} catch (error) {
|
|
1311
|
+
throw new Error(\`Failed to retrieve ${moduleNameCamelCase}s: \${error.message}\`);
|
|
1312
|
+
}
|
|
1229
1313
|
}
|
|
1314
|
+
|
|
1230
1315
|
async getById(id: string) {
|
|
1231
|
-
|
|
1316
|
+
try {
|
|
1317
|
+
const data = await ${moduleNameCapitalized}Model.findById(id);
|
|
1318
|
+
if (!data) {
|
|
1319
|
+
throw new Error('${moduleNameCapitalized} not found');
|
|
1320
|
+
}
|
|
1321
|
+
return {
|
|
1322
|
+
Data: data,
|
|
1323
|
+
StatusCode: 1000,
|
|
1324
|
+
Message: '${moduleNameCapitalized} retrieved successfully'
|
|
1325
|
+
};
|
|
1326
|
+
} catch (error) {
|
|
1327
|
+
throw new Error(\`Failed to retrieve ${moduleNameCamelCase}: \${error.message}\`);
|
|
1328
|
+
}
|
|
1232
1329
|
}
|
|
1330
|
+
|
|
1233
1331
|
async create(data: any) {
|
|
1234
|
-
|
|
1235
|
-
|
|
1332
|
+
try {
|
|
1333
|
+
const entity = new ${moduleNameCapitalized}Model({ _id: new ObjectId(), ...data, status: 1 });
|
|
1334
|
+
const result = await ${moduleNameCapitalized}Model.create(entity);
|
|
1335
|
+
return {
|
|
1336
|
+
Data: result,
|
|
1337
|
+
StatusCode: 1000,
|
|
1338
|
+
Message: '${moduleNameCapitalized} created successfully'
|
|
1339
|
+
};
|
|
1340
|
+
} catch (error) {
|
|
1341
|
+
throw new Error(\`Failed to create ${moduleNameCamelCase}: \${error.message}\`);
|
|
1342
|
+
}
|
|
1236
1343
|
}
|
|
1344
|
+
|
|
1237
1345
|
async update(id: string, data: any) {
|
|
1238
|
-
|
|
1346
|
+
try {
|
|
1347
|
+
const result = await ${moduleNameCapitalized}Model.findByIdAndUpdate(id, { ...data }, { new: true });
|
|
1348
|
+
if (!result) {
|
|
1349
|
+
throw new Error('${moduleNameCapitalized} not found');
|
|
1350
|
+
}
|
|
1351
|
+
return {
|
|
1352
|
+
Data: result,
|
|
1353
|
+
StatusCode: 1000,
|
|
1354
|
+
Message: '${moduleNameCapitalized} updated successfully'
|
|
1355
|
+
};
|
|
1356
|
+
} catch (error) {
|
|
1357
|
+
throw new Error(\`Failed to update ${moduleNameCamelCase}: \${error.message}\`);
|
|
1358
|
+
}
|
|
1239
1359
|
}
|
|
1360
|
+
|
|
1240
1361
|
async delete(id: string) {
|
|
1241
|
-
|
|
1362
|
+
try {
|
|
1363
|
+
const result = await ${moduleNameCapitalized}Model.findByIdAndUpdate(id, { status: 0 }, { new: true });
|
|
1364
|
+
if (!result) {
|
|
1365
|
+
throw new Error('${moduleNameCapitalized} not found');
|
|
1366
|
+
}
|
|
1367
|
+
return {
|
|
1368
|
+
Data: true,
|
|
1369
|
+
StatusCode: 1000,
|
|
1370
|
+
Message: '${moduleNameCapitalized} deleted successfully'
|
|
1371
|
+
};
|
|
1372
|
+
} catch (error) {
|
|
1373
|
+
throw new Error(\`Failed to delete ${moduleNameCamelCase}: \${error.message}\`);
|
|
1374
|
+
}
|
|
1242
1375
|
}
|
|
1243
1376
|
}`;
|
|
1244
|
-
await fs.writeFile(path.join(modulePath, 'services', `${
|
|
1377
|
+
await fs.writeFile(path.join(modulePath, 'services', `${moduleNameCamelCase}.service.ts`), serviceContent);
|
|
1245
1378
|
}
|
|
1246
|
-
async createController(modulePath,
|
|
1247
|
-
|
|
1248
|
-
const
|
|
1379
|
+
async createController(modulePath, moduleNameCamelCase, options) {
|
|
1380
|
+
// Convert module name to valid TypeScript identifiers
|
|
1381
|
+
const moduleNameCapitalized = moduleNameCamelCase.charAt(0).toUpperCase() + moduleNameCamelCase.slice(1);
|
|
1382
|
+
const controllerContent = `import { ${moduleNameCapitalized}Service } from '../services/${moduleNameCamelCase}.service';
|
|
1249
1383
|
|
|
1250
1384
|
/**
|
|
1251
1385
|
* @openapi
|
|
1252
1386
|
* components:
|
|
1253
1387
|
* schemas:
|
|
1254
|
-
* ${
|
|
1388
|
+
* ${moduleNameCapitalized}:
|
|
1255
1389
|
* type: object
|
|
1256
1390
|
* properties:
|
|
1257
1391
|
* _id:
|
|
1258
1392
|
* type: string
|
|
1259
|
-
* description: ${
|
|
1393
|
+
* description: ${moduleNameCapitalized} ID
|
|
1260
1394
|
* name:
|
|
1261
1395
|
* type: string
|
|
1262
|
-
* description: Name of the ${
|
|
1396
|
+
* description: Name of the ${moduleNameCapitalized}
|
|
1263
1397
|
* description:
|
|
1264
1398
|
* type: string
|
|
1265
|
-
* description: Description of the ${
|
|
1399
|
+
* description: Description of the ${moduleNameCapitalized}
|
|
1266
1400
|
* status:
|
|
1267
1401
|
* type: integer
|
|
1268
|
-
* description: Status of the ${
|
|
1402
|
+
* description: Status of the ${moduleNameCapitalized} (1 - active, 0 - deleted)
|
|
1269
1403
|
* createdAt:
|
|
1270
1404
|
* type: string
|
|
1271
1405
|
* format: date-time
|
|
@@ -1282,19 +1416,19 @@ export class ${entityName}Service {
|
|
|
1282
1416
|
* - updatedAt
|
|
1283
1417
|
*/
|
|
1284
1418
|
|
|
1285
|
-
export class ${
|
|
1286
|
-
private service = new ${
|
|
1419
|
+
export class ${moduleNameCapitalized}Controller {
|
|
1420
|
+
private service = new ${moduleNameCapitalized}Service();
|
|
1287
1421
|
|
|
1288
1422
|
/**
|
|
1289
1423
|
* @openapi
|
|
1290
|
-
* /api/${
|
|
1424
|
+
* /api/${moduleNameCamelCase}:
|
|
1291
1425
|
* get:
|
|
1292
|
-
* summary: Get all ${
|
|
1293
|
-
* description: Retrieve a list of all active ${
|
|
1294
|
-
* tags: [${
|
|
1426
|
+
* summary: Get all ${moduleNameCapitalized}s
|
|
1427
|
+
* description: Retrieve a list of all active ${moduleNameCapitalized}s
|
|
1428
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1295
1429
|
* responses:
|
|
1296
1430
|
* 200:
|
|
1297
|
-
* description: List of ${
|
|
1431
|
+
* description: List of ${moduleNameCapitalized}s retrieved successfully
|
|
1298
1432
|
* content:
|
|
1299
1433
|
* application/json:
|
|
1300
1434
|
* schema:
|
|
@@ -1303,7 +1437,7 @@ export class ${entityName}Controller {
|
|
|
1303
1437
|
* Data:
|
|
1304
1438
|
* type: array
|
|
1305
1439
|
* items:
|
|
1306
|
-
* $ref: '#/components/schemas/${
|
|
1440
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1307
1441
|
* StatusCode:
|
|
1308
1442
|
* type: integer
|
|
1309
1443
|
* example: 1000
|
|
@@ -1311,52 +1445,68 @@ export class ${entityName}Controller {
|
|
|
1311
1445
|
* description: Bad request
|
|
1312
1446
|
*/
|
|
1313
1447
|
async getAll(req, res) {
|
|
1314
|
-
|
|
1315
|
-
|
|
1448
|
+
try {
|
|
1449
|
+
const data = await this.service.getAll();
|
|
1450
|
+
res.json(data);
|
|
1451
|
+
} catch (error) {
|
|
1452
|
+
res.status(400).json({
|
|
1453
|
+
Data: null,
|
|
1454
|
+
StatusCode: 4000,
|
|
1455
|
+
Message: error.message
|
|
1456
|
+
});
|
|
1457
|
+
}
|
|
1316
1458
|
}
|
|
1317
1459
|
|
|
1318
1460
|
/**
|
|
1319
1461
|
* @openapi
|
|
1320
|
-
* /api/${
|
|
1462
|
+
* /api/${moduleNameCamelCase}/{id}:
|
|
1321
1463
|
* get:
|
|
1322
|
-
* summary: Get ${
|
|
1323
|
-
* description: Retrieve a specific ${
|
|
1324
|
-
* tags: [${
|
|
1464
|
+
* summary: Get ${moduleNameCapitalized} by ID
|
|
1465
|
+
* description: Retrieve a specific ${moduleNameCapitalized} by its ID
|
|
1466
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1325
1467
|
* parameters:
|
|
1326
1468
|
* - in: path
|
|
1327
1469
|
* name: id
|
|
1328
1470
|
* required: true
|
|
1329
1471
|
* schema:
|
|
1330
1472
|
* type: string
|
|
1331
|
-
* description: ${
|
|
1473
|
+
* description: ${moduleNameCapitalized} ID
|
|
1332
1474
|
* responses:
|
|
1333
1475
|
* 200:
|
|
1334
|
-
* description: ${
|
|
1476
|
+
* description: ${moduleNameCapitalized} retrieved successfully
|
|
1335
1477
|
* content:
|
|
1336
1478
|
* application/json:
|
|
1337
1479
|
* schema:
|
|
1338
1480
|
* type: object
|
|
1339
1481
|
* properties:
|
|
1340
1482
|
* Data:
|
|
1341
|
-
* $ref: '#/components/schemas/${
|
|
1483
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1342
1484
|
* StatusCode:
|
|
1343
1485
|
* type: integer
|
|
1344
1486
|
* example: 1000
|
|
1345
1487
|
* 404:
|
|
1346
|
-
* description: ${
|
|
1488
|
+
* description: ${moduleNameCapitalized} not found
|
|
1347
1489
|
*/
|
|
1348
1490
|
async getById(req, res) {
|
|
1349
|
-
|
|
1350
|
-
|
|
1491
|
+
try {
|
|
1492
|
+
const data = await this.service.getById(req.params.id);
|
|
1493
|
+
res.json(data);
|
|
1494
|
+
} catch (error) {
|
|
1495
|
+
res.status(404).json({
|
|
1496
|
+
Data: null,
|
|
1497
|
+
StatusCode: 4004,
|
|
1498
|
+
Message: error.message
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1351
1501
|
}
|
|
1352
1502
|
|
|
1353
1503
|
/**
|
|
1354
1504
|
* @openapi
|
|
1355
|
-
* /api/${
|
|
1505
|
+
* /api/${moduleNameCamelCase}:
|
|
1356
1506
|
* post:
|
|
1357
|
-
* summary: Create new ${
|
|
1358
|
-
* description: Create a new ${
|
|
1359
|
-
* tags: [${
|
|
1507
|
+
* summary: Create new ${moduleNameCapitalized}
|
|
1508
|
+
* description: Create a new ${moduleNameCapitalized} record
|
|
1509
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1360
1510
|
* requestBody:
|
|
1361
1511
|
* required: true
|
|
1362
1512
|
* content:
|
|
@@ -1368,24 +1518,24 @@ export class ${entityName}Controller {
|
|
|
1368
1518
|
* properties:
|
|
1369
1519
|
* name:
|
|
1370
1520
|
* type: string
|
|
1371
|
-
* description: Name of the ${
|
|
1521
|
+
* description: Name of the ${moduleNameCapitalized}
|
|
1372
1522
|
* description:
|
|
1373
1523
|
* type: string
|
|
1374
|
-
* description: Description of the ${
|
|
1524
|
+
* description: Description of the ${moduleNameCapitalized}
|
|
1375
1525
|
* status:
|
|
1376
1526
|
* type: integer
|
|
1377
1527
|
* default: 1
|
|
1378
|
-
* description: Status of the ${
|
|
1528
|
+
* description: Status of the ${moduleNameCapitalized}
|
|
1379
1529
|
* responses:
|
|
1380
1530
|
* 201:
|
|
1381
|
-
* description: ${
|
|
1531
|
+
* description: ${moduleNameCapitalized} created successfully
|
|
1382
1532
|
* content:
|
|
1383
1533
|
* application/json:
|
|
1384
1534
|
* schema:
|
|
1385
1535
|
* type: object
|
|
1386
1536
|
* properties:
|
|
1387
1537
|
* Data:
|
|
1388
|
-
* $ref: '#/components/schemas/${
|
|
1538
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1389
1539
|
* StatusCode:
|
|
1390
1540
|
* type: integer
|
|
1391
1541
|
* example: 1000
|
|
@@ -1393,24 +1543,32 @@ export class ${entityName}Controller {
|
|
|
1393
1543
|
* description: Bad request or missing required fields
|
|
1394
1544
|
*/
|
|
1395
1545
|
async create(req, res) {
|
|
1396
|
-
|
|
1397
|
-
|
|
1546
|
+
try {
|
|
1547
|
+
const data = await this.service.create(req.body);
|
|
1548
|
+
res.status(201).json(data);
|
|
1549
|
+
} catch (error) {
|
|
1550
|
+
res.status(400).json({
|
|
1551
|
+
Data: null,
|
|
1552
|
+
StatusCode: 4000,
|
|
1553
|
+
Message: error.message
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1398
1556
|
}
|
|
1399
1557
|
|
|
1400
1558
|
/**
|
|
1401
1559
|
* @openapi
|
|
1402
|
-
* /api/${
|
|
1560
|
+
* /api/${moduleNameCamelCase}/{id}:
|
|
1403
1561
|
* put:
|
|
1404
|
-
* summary: Update ${
|
|
1405
|
-
* description: Update an existing ${
|
|
1406
|
-
* tags: [${
|
|
1562
|
+
* summary: Update ${moduleNameCapitalized}
|
|
1563
|
+
* description: Update an existing ${moduleNameCapitalized} record
|
|
1564
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1407
1565
|
* parameters:
|
|
1408
1566
|
* - in: path
|
|
1409
1567
|
* name: id
|
|
1410
1568
|
* required: true
|
|
1411
1569
|
* schema:
|
|
1412
1570
|
* type: string
|
|
1413
|
-
* description: ${
|
|
1571
|
+
* description: ${moduleNameCapitalized} ID
|
|
1414
1572
|
* requestBody:
|
|
1415
1573
|
* required: true
|
|
1416
1574
|
* content:
|
|
@@ -1420,51 +1578,59 @@ export class ${entityName}Controller {
|
|
|
1420
1578
|
* properties:
|
|
1421
1579
|
* name:
|
|
1422
1580
|
* type: string
|
|
1423
|
-
* description: Name of the ${
|
|
1581
|
+
* description: Name of the ${moduleNameCapitalized}
|
|
1424
1582
|
* description:
|
|
1425
1583
|
* type: string
|
|
1426
|
-
* description: Description of the ${
|
|
1584
|
+
* description: Description of the ${moduleNameCapitalized}
|
|
1427
1585
|
* status:
|
|
1428
1586
|
* type: integer
|
|
1429
|
-
* description: Status of the ${
|
|
1587
|
+
* description: Status of the ${moduleNameCapitalized}
|
|
1430
1588
|
* responses:
|
|
1431
1589
|
* 200:
|
|
1432
|
-
* description: ${
|
|
1590
|
+
* description: ${moduleNameCapitalized} updated successfully
|
|
1433
1591
|
* content:
|
|
1434
1592
|
* application/json:
|
|
1435
1593
|
* schema:
|
|
1436
1594
|
* type: object
|
|
1437
1595
|
* properties:
|
|
1438
1596
|
* Data:
|
|
1439
|
-
* $ref: '#/components/schemas/${
|
|
1597
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1440
1598
|
* StatusCode:
|
|
1441
1599
|
* type: integer
|
|
1442
1600
|
* example: 1000
|
|
1443
1601
|
* 404:
|
|
1444
|
-
* description: ${
|
|
1602
|
+
* description: ${moduleNameCapitalized} not found
|
|
1445
1603
|
*/
|
|
1446
1604
|
async update(req, res) {
|
|
1447
|
-
|
|
1448
|
-
|
|
1605
|
+
try {
|
|
1606
|
+
const data = await this.service.update(req.params.id, req.body);
|
|
1607
|
+
res.json(data);
|
|
1608
|
+
} catch (error) {
|
|
1609
|
+
res.status(404).json({
|
|
1610
|
+
Data: null,
|
|
1611
|
+
StatusCode: 4004,
|
|
1612
|
+
Message: error.message
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1449
1615
|
}
|
|
1450
1616
|
|
|
1451
1617
|
/**
|
|
1452
1618
|
* @openapi
|
|
1453
|
-
* /api/${
|
|
1619
|
+
* /api/${moduleNameCamelCase}/{id}:
|
|
1454
1620
|
* delete:
|
|
1455
|
-
* summary: Delete ${
|
|
1456
|
-
* description: Soft delete a ${
|
|
1457
|
-
* tags: [${
|
|
1621
|
+
* summary: Delete ${moduleNameCapitalized}
|
|
1622
|
+
* description: Soft delete a ${moduleNameCapitalized} (sets status to 0)
|
|
1623
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1458
1624
|
* parameters:
|
|
1459
1625
|
* - in: path
|
|
1460
1626
|
* name: id
|
|
1461
1627
|
* required: true
|
|
1462
1628
|
* schema:
|
|
1463
1629
|
* type: string
|
|
1464
|
-
* description: ${
|
|
1630
|
+
* description: ${moduleNameCapitalized} ID
|
|
1465
1631
|
* responses:
|
|
1466
1632
|
* 200:
|
|
1467
|
-
* description: ${
|
|
1633
|
+
* description: ${moduleNameCapitalized} deleted successfully
|
|
1468
1634
|
* content:
|
|
1469
1635
|
* application/json:
|
|
1470
1636
|
* schema:
|
|
@@ -1477,46 +1643,55 @@ export class ${entityName}Controller {
|
|
|
1477
1643
|
* type: integer
|
|
1478
1644
|
* example: 1000
|
|
1479
1645
|
* 404:
|
|
1480
|
-
* description: ${
|
|
1646
|
+
* description: ${moduleNameCapitalized} not found
|
|
1481
1647
|
*/
|
|
1482
1648
|
async delete(req, res) {
|
|
1483
|
-
|
|
1484
|
-
|
|
1649
|
+
try {
|
|
1650
|
+
const data = await this.service.delete(req.params.id);
|
|
1651
|
+
res.json(data);
|
|
1652
|
+
} catch (error) {
|
|
1653
|
+
res.status(404).json({
|
|
1654
|
+
Data: null,
|
|
1655
|
+
StatusCode: 4004,
|
|
1656
|
+
Message: error.message
|
|
1657
|
+
});
|
|
1658
|
+
}
|
|
1485
1659
|
}
|
|
1486
1660
|
}`;
|
|
1487
|
-
await fs.writeFile(path.join(modulePath, 'controllers', `${
|
|
1661
|
+
await fs.writeFile(path.join(modulePath, 'controllers', `${moduleNameCamelCase}.controller.ts`), controllerContent);
|
|
1488
1662
|
}
|
|
1489
|
-
async createRoutes(modulePath,
|
|
1490
|
-
|
|
1663
|
+
async createRoutes(modulePath, moduleNameCamelCase, options) {
|
|
1664
|
+
// Convert module name to valid TypeScript identifiers
|
|
1665
|
+
const moduleNameCapitalized = moduleNameCamelCase.charAt(0).toUpperCase() + moduleNameCamelCase.slice(1);
|
|
1491
1666
|
const routesContent = `import { Router } from 'express';
|
|
1492
|
-
import { ${
|
|
1667
|
+
import { ${moduleNameCapitalized}Controller } from '../controllers/${moduleNameCamelCase}.controller';
|
|
1493
1668
|
|
|
1494
1669
|
const router = Router();
|
|
1495
|
-
const controller = new ${
|
|
1670
|
+
const controller = new ${moduleNameCapitalized}Controller();
|
|
1496
1671
|
|
|
1497
1672
|
/**
|
|
1498
1673
|
* @openapi
|
|
1499
|
-
* /api/${
|
|
1674
|
+
* /api/${moduleNameCamelCase}/health:
|
|
1500
1675
|
* get:
|
|
1501
|
-
* summary: Health check for ${
|
|
1502
|
-
* description: Check if the ${
|
|
1503
|
-
* tags: [${
|
|
1676
|
+
* summary: Health check for ${moduleNameCapitalized} API
|
|
1677
|
+
* description: Check if the ${moduleNameCapitalized} API is running
|
|
1678
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1504
1679
|
* responses:
|
|
1505
1680
|
* 200:
|
|
1506
|
-
* description: ${
|
|
1681
|
+
* description: ${moduleNameCapitalized} API is running
|
|
1507
1682
|
*/
|
|
1508
|
-
router.get('/', (req, res) => res.send('${
|
|
1683
|
+
router.get('/health', (req, res) => res.send('${moduleNameCapitalized} API is up.'));
|
|
1509
1684
|
|
|
1510
1685
|
/**
|
|
1511
1686
|
* @openapi
|
|
1512
|
-
* /api/${
|
|
1687
|
+
* /api/${moduleNameCamelCase}/all:
|
|
1513
1688
|
* get:
|
|
1514
|
-
* summary: Get all ${
|
|
1515
|
-
* description: Retrieve a list of all active ${
|
|
1516
|
-
* tags: [${
|
|
1689
|
+
* summary: Get all ${moduleNameCapitalized}s
|
|
1690
|
+
* description: Retrieve a list of all active ${moduleNameCapitalized}s
|
|
1691
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1517
1692
|
* responses:
|
|
1518
1693
|
* 200:
|
|
1519
|
-
* description: List of ${
|
|
1694
|
+
* description: List of ${moduleNameCapitalized}s retrieved successfully
|
|
1520
1695
|
* content:
|
|
1521
1696
|
* application/json:
|
|
1522
1697
|
* schema:
|
|
@@ -1525,7 +1700,7 @@ router.get('/', (req, res) => res.send('${entityName} API is up.'));
|
|
|
1525
1700
|
* Data:
|
|
1526
1701
|
* type: array
|
|
1527
1702
|
* items:
|
|
1528
|
-
* $ref: '#/components/schemas/${
|
|
1703
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1529
1704
|
* StatusCode:
|
|
1530
1705
|
* type: integer
|
|
1531
1706
|
* example: 1000
|
|
@@ -1536,43 +1711,43 @@ router.get('/all', (req, res) => controller.getAll(req, res));
|
|
|
1536
1711
|
|
|
1537
1712
|
/**
|
|
1538
1713
|
* @openapi
|
|
1539
|
-
* /api/${
|
|
1714
|
+
* /api/${moduleNameCamelCase}/{id}:
|
|
1540
1715
|
* get:
|
|
1541
|
-
* summary: Get ${
|
|
1542
|
-
* description: Retrieve a specific ${
|
|
1543
|
-
* tags: [${
|
|
1716
|
+
* summary: Get ${moduleNameCapitalized} by ID
|
|
1717
|
+
* description: Retrieve a specific ${moduleNameCapitalized} by its ID
|
|
1718
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1544
1719
|
* parameters:
|
|
1545
1720
|
* - in: path
|
|
1546
1721
|
* name: id
|
|
1547
1722
|
* required: true
|
|
1548
1723
|
* schema:
|
|
1549
1724
|
* type: string
|
|
1550
|
-
* description: ${
|
|
1725
|
+
* description: ${moduleNameCapitalized} ID
|
|
1551
1726
|
* responses:
|
|
1552
1727
|
* 200:
|
|
1553
|
-
* description: ${
|
|
1728
|
+
* description: ${moduleNameCapitalized} retrieved successfully
|
|
1554
1729
|
* content:
|
|
1555
1730
|
* application/json:
|
|
1556
1731
|
* schema:
|
|
1557
1732
|
* type: object
|
|
1558
1733
|
* properties:
|
|
1559
1734
|
* Data:
|
|
1560
|
-
* $ref: '#/components/schemas/${
|
|
1735
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1561
1736
|
* StatusCode:
|
|
1562
1737
|
* type: integer
|
|
1563
1738
|
* example: 1000
|
|
1564
1739
|
* 404:
|
|
1565
|
-
* description: ${
|
|
1740
|
+
* description: ${moduleNameCapitalized} not found
|
|
1566
1741
|
*/
|
|
1567
1742
|
router.get('/:id', (req, res) => controller.getById(req, res));
|
|
1568
1743
|
|
|
1569
1744
|
/**
|
|
1570
1745
|
* @openapi
|
|
1571
|
-
* /api/${
|
|
1746
|
+
* /api/${moduleNameCamelCase}:
|
|
1572
1747
|
* post:
|
|
1573
|
-
* summary: Create new ${
|
|
1574
|
-
* description: Create a new ${
|
|
1575
|
-
* tags: [${
|
|
1748
|
+
* summary: Create new ${moduleNameCapitalized}
|
|
1749
|
+
* description: Create a new ${moduleNameCapitalized} record
|
|
1750
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1576
1751
|
* requestBody:
|
|
1577
1752
|
* required: true
|
|
1578
1753
|
* content:
|
|
@@ -1583,116 +1758,116 @@ router.get('/:id', (req, res) => controller.getById(req, res));
|
|
|
1583
1758
|
* - name
|
|
1584
1759
|
* properties:
|
|
1585
1760
|
* name:
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1761
|
+
* type: string
|
|
1762
|
+
* description: Name of the ${moduleNameCapitalized}
|
|
1763
|
+
* description:
|
|
1764
|
+
* type: string
|
|
1765
|
+
* description: Description of the ${moduleNameCapitalized}
|
|
1766
|
+
* status:
|
|
1767
|
+
* type: integer
|
|
1768
|
+
* default: 1
|
|
1769
|
+
* description: Status of the ${moduleNameCapitalized}
|
|
1770
|
+
* responses:
|
|
1771
|
+
* 201:
|
|
1772
|
+
* description: ${moduleNameCapitalized} created successfully
|
|
1773
|
+
* content:
|
|
1774
|
+
* application/json:
|
|
1775
|
+
* schema:
|
|
1776
|
+
* type: object
|
|
1777
|
+
* properties:
|
|
1778
|
+
* Data:
|
|
1779
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1780
|
+
* StatusCode:
|
|
1781
|
+
* type: integer
|
|
1782
|
+
* example: 1000
|
|
1783
|
+
* 400:
|
|
1784
|
+
* description: Bad request or missing required fields
|
|
1785
|
+
*/
|
|
1611
1786
|
router.post('/', (req, res) => controller.create(req, res));
|
|
1612
1787
|
|
|
1613
1788
|
/**
|
|
1614
1789
|
* @openapi
|
|
1615
|
-
* /api/${
|
|
1790
|
+
* /api/${moduleNameCamelCase}/{id}:
|
|
1616
1791
|
* put:
|
|
1617
|
-
* summary: Update ${
|
|
1618
|
-
* description: Update an existing ${
|
|
1619
|
-
* tags: [${
|
|
1792
|
+
* summary: Update ${moduleNameCapitalized}
|
|
1793
|
+
* description: Update an existing ${moduleNameCapitalized} record
|
|
1794
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1620
1795
|
* parameters:
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1796
|
+
* - in: path
|
|
1797
|
+
* name: id
|
|
1798
|
+
* required: true
|
|
1799
|
+
* schema:
|
|
1800
|
+
* type: string
|
|
1801
|
+
* description: ${moduleNameCapitalized} ID
|
|
1802
|
+
* requestBody:
|
|
1803
|
+
* required: true
|
|
1804
|
+
* content:
|
|
1805
|
+
* application/json:
|
|
1806
|
+
* schema:
|
|
1807
|
+
* type: object
|
|
1808
|
+
* properties:
|
|
1809
|
+
* name:
|
|
1635
1810
|
* type: string
|
|
1636
|
-
* description: Name of the ${
|
|
1811
|
+
* description: Name of the ${moduleNameCapitalized}
|
|
1637
1812
|
* description:
|
|
1638
1813
|
* type: string
|
|
1639
|
-
* description: Description of the ${
|
|
1814
|
+
* description: Description of the ${moduleNameCapitalized}
|
|
1640
1815
|
* status:
|
|
1641
1816
|
* type: integer
|
|
1642
|
-
* description: Status of the ${
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1817
|
+
* description: Status of the ${moduleNameCapitalized}
|
|
1818
|
+
* responses:
|
|
1819
|
+
* 200:
|
|
1820
|
+
* description: ${moduleNameCapitalized} updated successfully
|
|
1821
|
+
* content:
|
|
1822
|
+
* application/json:
|
|
1823
|
+
* schema:
|
|
1824
|
+
* type: object
|
|
1825
|
+
* properties:
|
|
1826
|
+
* Data:
|
|
1827
|
+
* $ref: '#/components/schemas/${moduleNameCapitalized}'
|
|
1828
|
+
* StatusCode:
|
|
1829
|
+
* type: integer
|
|
1830
|
+
* example: 1000
|
|
1831
|
+
* 404:
|
|
1832
|
+
* description: ${moduleNameCapitalized} not found
|
|
1833
|
+
*/
|
|
1659
1834
|
router.put('/:id', (req, res) => controller.update(req, res));
|
|
1660
1835
|
|
|
1661
1836
|
/**
|
|
1662
1837
|
* @openapi
|
|
1663
|
-
* /api/${
|
|
1838
|
+
* /api/${moduleNameCamelCase}/{id}:
|
|
1664
1839
|
* delete:
|
|
1665
|
-
* summary: Delete ${
|
|
1666
|
-
* description: Soft delete a ${
|
|
1667
|
-
* tags: [${
|
|
1840
|
+
* summary: Delete ${moduleNameCapitalized}
|
|
1841
|
+
* description: Soft delete a ${moduleNameCapitalized} (sets status to 0)
|
|
1842
|
+
* tags: [${moduleNameCapitalized}s]
|
|
1668
1843
|
* parameters:
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1844
|
+
* - in: path
|
|
1845
|
+
* name: id
|
|
1846
|
+
* required: true
|
|
1847
|
+
* schema:
|
|
1848
|
+
* type: string
|
|
1849
|
+
* description: ${moduleNameCapitalized} ID
|
|
1850
|
+
* responses:
|
|
1851
|
+
* 200:
|
|
1852
|
+
* description: ${moduleNameCapitalized} deleted successfully
|
|
1853
|
+
* content:
|
|
1854
|
+
* application/json:
|
|
1855
|
+
* schema:
|
|
1856
|
+
* type: object
|
|
1857
|
+
* properties:
|
|
1858
|
+
* Data:
|
|
1859
|
+
* type: boolean
|
|
1860
|
+
* example: true
|
|
1861
|
+
* StatusCode:
|
|
1862
|
+
* type: integer
|
|
1863
|
+
* example: 1000
|
|
1864
|
+
* 404:
|
|
1865
|
+
* description: ${moduleNameCapitalized} not found
|
|
1866
|
+
*/
|
|
1692
1867
|
router.delete('/:id', (req, res) => controller.delete(req, res));
|
|
1693
1868
|
|
|
1694
1869
|
export default router;`;
|
|
1695
|
-
await fs.writeFile(path.join(modulePath, 'routes', `${
|
|
1870
|
+
await fs.writeFile(path.join(modulePath, 'routes', `${moduleNameCamelCase}.routes.ts`), routesContent);
|
|
1696
1871
|
}
|
|
1697
1872
|
async generateCRUDOperations(projectPath, moduleName, options) {
|
|
1698
1873
|
console.log(chalk_1.default.blue(`🔄 Generating CRUD operations for ${moduleName}...`));
|
|
@@ -1750,12 +1925,12 @@ export default router;`;
|
|
|
1750
1925
|
}
|
|
1751
1926
|
}
|
|
1752
1927
|
async updateSeeder(projectPath, moduleName) {
|
|
1753
|
-
const
|
|
1928
|
+
const moduleNameCapitalized = this.capitalizeFirst(moduleName);
|
|
1754
1929
|
const seederPath = path.join(projectPath, 'src', 'core', 'database', 'seeder.ts');
|
|
1755
1930
|
if (await fs.pathExists(seederPath)) {
|
|
1756
1931
|
let seederContent = await fs.readFile(seederPath, 'utf8');
|
|
1757
1932
|
// Add import for the model
|
|
1758
|
-
const importStatement = `import { ${
|
|
1933
|
+
const importStatement = `import { ${moduleNameCapitalized}Model } from '../../modules/${moduleName}/schemas/${moduleName}.schema';`;
|
|
1759
1934
|
if (!seederContent.includes(importStatement)) {
|
|
1760
1935
|
// Add import after the last import statement
|
|
1761
1936
|
const lastImportIndex = seederContent.lastIndexOf('import');
|
|
@@ -1763,34 +1938,34 @@ export default router;`;
|
|
|
1763
1938
|
seederContent = seederContent.slice(0, lastImportEndIndex) + importStatement + '\n' + seederContent.slice(lastImportEndIndex);
|
|
1764
1939
|
}
|
|
1765
1940
|
// Add seeder function - use exact module name provided by developer
|
|
1766
|
-
const seederFunction = ` private async seed${
|
|
1941
|
+
const seederFunction = ` private async seed${moduleNameCapitalized}(data: any[]): Promise<void> {
|
|
1767
1942
|
if (data.length === 0) return;
|
|
1768
1943
|
|
|
1769
1944
|
logger.info(\`[DatabaseSeeder] Seeding \${data.length} ${moduleName} records...\`);
|
|
1770
1945
|
|
|
1771
1946
|
for (const ${moduleName}Data of data) {
|
|
1772
1947
|
try {
|
|
1773
|
-
const existing = await ${
|
|
1948
|
+
const existing = await ${moduleNameCapitalized}Model.findOne({ name: ${moduleName}Data.name });
|
|
1774
1949
|
if (!existing) {
|
|
1775
|
-
const ${moduleName} = new ${
|
|
1950
|
+
const ${moduleName} = new ${moduleNameCapitalized}Model({
|
|
1776
1951
|
...${moduleName}Data,
|
|
1777
1952
|
status: 1
|
|
1778
1953
|
});
|
|
1779
1954
|
await ${moduleName}.save();
|
|
1780
1955
|
logger.info(\`[DatabaseSeeder] Created ${moduleName}: \${${moduleName}Data.name}\`);
|
|
1781
1956
|
} else {
|
|
1782
|
-
logger.info(\`[DatabaseSeeder] ${
|
|
1957
|
+
logger.info(\`[DatabaseSeeder] ${moduleNameCapitalized} \${${moduleName}Data.name} already exists, skipping\`);
|
|
1783
1958
|
}
|
|
1784
1959
|
} catch (error) {
|
|
1785
1960
|
logger.error(\`[DatabaseSeeder] Failed to create ${moduleName} \${${moduleName}Data.name}:\`, error);
|
|
1786
1961
|
}
|
|
1787
1962
|
}
|
|
1788
1963
|
}`;
|
|
1789
|
-
if (!seederContent.includes(`seed${
|
|
1964
|
+
if (!seederContent.includes(`seed${moduleNameCapitalized}(`)) {
|
|
1790
1965
|
seederContent = seederContent.replace(/\/\/ TEMPLATE: Add new seeder functions here \(the CLI will add new functions automatically\)/, `// TEMPLATE: Add new seeder functions here (the CLI will add new functions automatically)\n${seederFunction}`);
|
|
1791
1966
|
}
|
|
1792
1967
|
// Add default seed data - use exact module name
|
|
1793
|
-
const seedDataLine = ` ${moduleName}: [ { name: '${
|
|
1968
|
+
const seedDataLine = ` ${moduleName}: [ { name: '${moduleNameCapitalized} Example', description: 'Example ${moduleName}', status: 1 } ],`;
|
|
1794
1969
|
if (!seederContent.includes(seedDataLine)) {
|
|
1795
1970
|
seederContent = seederContent.replace(/const defaultData: SeedData = \{/, `const defaultData: SeedData = {\n${seedDataLine}`);
|
|
1796
1971
|
}
|
|
@@ -1798,7 +1973,7 @@ export default router;`;
|
|
|
1798
1973
|
}
|
|
1799
1974
|
}
|
|
1800
1975
|
async createTableSchema(projectPath, tableName, options) {
|
|
1801
|
-
const
|
|
1976
|
+
const tableNameCapitalized = this.capitalizeFirst(tableName);
|
|
1802
1977
|
const fields = options.fields || ['name', 'description'];
|
|
1803
1978
|
const dbType = options.type || 'mongodb';
|
|
1804
1979
|
if (dbType === 'mongodb') {
|
|
@@ -1811,10 +1986,10 @@ export default router;`;
|
|
|
1811
1986
|
async createMongoDBSchema(projectPath, tableName, fields) {
|
|
1812
1987
|
const schemaPath = path.join(projectPath, 'src', 'schemas', `${tableName}.schema.ts`);
|
|
1813
1988
|
await fs.ensureDir(path.dirname(schemaPath));
|
|
1814
|
-
const
|
|
1989
|
+
const tableNameCapitalized = this.capitalizeFirst(tableName);
|
|
1815
1990
|
const schemaContent = `import mongoose, { Schema, Document } from 'mongoose';
|
|
1816
1991
|
|
|
1817
|
-
export interface I${
|
|
1992
|
+
export interface I${tableNameCapitalized}Document extends Document {
|
|
1818
1993
|
${fields.map(field => ` ${field}: string;`).join('\n')}
|
|
1819
1994
|
createdAt: Date;
|
|
1820
1995
|
updatedAt: Date;
|
|
@@ -1833,15 +2008,15 @@ ${fields.map(field => ` ${field}: {
|
|
|
1833
2008
|
// Indexes
|
|
1834
2009
|
${fields.map(field => `${tableName}Schema.index({ ${field}: 1 });`).join('\n')}
|
|
1835
2010
|
|
|
1836
|
-
export const ${
|
|
2011
|
+
export const ${tableNameCapitalized}Model = mongoose.model<I${tableNameCapitalized}Document>('${tableNameCapitalized}', ${tableName}Schema);
|
|
1837
2012
|
`;
|
|
1838
2013
|
await fs.writeFile(schemaPath, schemaContent);
|
|
1839
2014
|
}
|
|
1840
2015
|
async createSQLSchema(projectPath, tableName, fields, dbType) {
|
|
1841
2016
|
const schemaPath = path.join(projectPath, 'src', 'schemas', `${tableName}.sql`);
|
|
1842
2017
|
await fs.ensureDir(path.dirname(schemaPath));
|
|
1843
|
-
const
|
|
1844
|
-
const schemaContent = `-- ${
|
|
2018
|
+
const tableNameCapitalized = this.capitalizeFirst(tableName);
|
|
2019
|
+
const schemaContent = `-- ${tableNameCapitalized} table schema for ${dbType.toUpperCase()}
|
|
1845
2020
|
CREATE TABLE ${tableName}s (
|
|
1846
2021
|
id ${dbType === 'postgres' ? 'SERIAL' : 'INT AUTO_INCREMENT'} PRIMARY KEY,
|
|
1847
2022
|
${fields.map(field => ` ${field} VARCHAR(255) NOT NULL,`).join('\n')}
|