@asad_dev/leo-generator 1.6.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/COMMAND_REFERENCE.md +412 -0
  3. package/README.md +486 -0
  4. package/dist/app/modules/imagemodule/imagemodule.constants.js +18 -0
  5. package/dist/app/modules/imagemodule/imagemodule.controller.js +98 -0
  6. package/dist/app/modules/imagemodule/imagemodule.interface.js +2 -0
  7. package/dist/app/modules/imagemodule/imagemodule.model.js +10 -0
  8. package/dist/app/modules/imagemodule/imagemodule.route.js +20 -0
  9. package/dist/app/modules/imagemodule/imagemodule.service.js +137 -0
  10. package/dist/app/modules/imagemodule/imagemodule.validation.js +12 -0
  11. package/dist/app/modules/skiptest/skiptest.controller.js +81 -0
  12. package/dist/app/modules/skiptest/skiptest.route.js +19 -0
  13. package/dist/app/modules/skiptest/skiptest.service.js +129 -0
  14. package/dist/app/modules/skiptest/skiptest.validation.js +12 -0
  15. package/dist/app/modules/testmodule/testmodule.constants.js +18 -0
  16. package/dist/app/modules/testmodule/testmodule.controller.js +81 -0
  17. package/dist/app/modules/testmodule/testmodule.interface.js +2 -0
  18. package/dist/app/modules/testmodule/testmodule.model.js +11 -0
  19. package/dist/app/modules/testmodule/testmodule.route.js +19 -0
  20. package/dist/app/modules/testmodule/testmodule.service.js +129 -0
  21. package/dist/app/modules/testmodule/testmodule.validation.js +14 -0
  22. package/dist/helpers/fileHelper.js +44 -0
  23. package/dist/index.js +586 -0
  24. package/dist/templates/constants.template.js +24 -0
  25. package/dist/templates/controller.template.js +108 -0
  26. package/dist/templates/route.template.js +68 -0
  27. package/dist/templates/service.template.js +184 -0
  28. package/dist/types.js +2 -0
  29. package/dist/utils/documentationUpdater.js +430 -0
  30. package/dist/utils/fieldParser.js +163 -0
  31. package/dist/utils/helperGenerator.js +87 -0
  32. package/dist/utils/interfaceGenerator.js +158 -0
  33. package/dist/utils/modelGenerator.js +140 -0
  34. package/dist/utils/postmanApi.js +113 -0
  35. package/dist/utils/postmanGenerator.js +283 -0
  36. package/dist/utils/swaggerGenerator.js +444 -0
  37. package/dist/utils/validationGenerator.js +170 -0
  38. package/package.json +58 -0
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateControllerContent = void 0;
4
+ const generateControllerContent = (camelCaseName, folderName, fields) => {
5
+ // Check if there are any file/image fields
6
+ const hasImageField = fields.some((field) => field.name === "image" || field.name === "images" || field.name === "media" || field.type.toLowerCase() === "image");
7
+ // Generate filterable fields (string and enum types)
8
+ const filterableFields = fields.filter(f => f.type.toLowerCase() === "string" || f.type.toLowerCase() === "enum");
9
+ return `import { Request, Response } from 'express';
10
+ import { ${camelCaseName}Services } from './${folderName}.service';
11
+ import catchAsync from '../../../shared/catchAsync';
12
+ import sendResponse from '../../../shared/sendResponse';
13
+ import { StatusCodes } from 'http-status-codes';
14
+ import pick from '../../../shared/pick';
15
+ import { ${folderName}Filterables } from './${folderName}.constants';
16
+ import { paginationFields } from '../../../interfaces/pagination';
17
+
18
+ const create${camelCaseName} = catchAsync(async (req: Request, res: Response) => {
19
+ ${hasImageField
20
+ ? `const { images, media, ...${folderName}Data } = req.body;
21
+
22
+ if (images && images.length > 0) {
23
+ ${folderName}Data.images = images;
24
+ }
25
+
26
+ if (media && media.length > 0) {
27
+ ${folderName}Data.media = media;
28
+ }`
29
+ : `const ${folderName}Data = req.body;`}
30
+
31
+ const result = await ${camelCaseName}Services.create${camelCaseName}(
32
+ req.user!,
33
+ ${folderName}Data
34
+ );
35
+
36
+ sendResponse(res, {
37
+ statusCode: StatusCodes.CREATED,
38
+ success: true,
39
+ message: '${camelCaseName} created successfully',
40
+ data: result,
41
+ });
42
+ });
43
+
44
+ const update${camelCaseName} = catchAsync(async (req: Request, res: Response) => {
45
+ const { id } = req.params;
46
+ const ${folderName}Data = req.body;
47
+
48
+ const result = await ${camelCaseName}Services.update${camelCaseName}(id, ${folderName}Data);
49
+
50
+ sendResponse(res, {
51
+ statusCode: StatusCodes.OK,
52
+ success: true,
53
+ message: '${camelCaseName} updated successfully',
54
+ data: result,
55
+ });
56
+ });
57
+
58
+ const getSingle${camelCaseName} = catchAsync(async (req: Request, res: Response) => {
59
+ const { id } = req.params;
60
+ const result = await ${camelCaseName}Services.getSingle${camelCaseName}(id);
61
+
62
+ sendResponse(res, {
63
+ statusCode: StatusCodes.OK,
64
+ success: true,
65
+ message: '${camelCaseName} retrieved successfully',
66
+ data: result,
67
+ });
68
+ });
69
+
70
+ const getAll${camelCaseName}s = catchAsync(async (req: Request, res: Response) => {
71
+ const filterables = pick(req.query, ${folderName}Filterables);
72
+ const pagination = pick(req.query, paginationFields);
73
+
74
+ const result = await ${camelCaseName}Services.getAll${camelCaseName}s(
75
+ req.user!,
76
+ filterables,
77
+ pagination
78
+ );
79
+
80
+ sendResponse(res, {
81
+ statusCode: StatusCodes.OK,
82
+ success: true,
83
+ message: '${camelCaseName}s retrieved successfully',
84
+ data: result,
85
+ });
86
+ });
87
+
88
+ const delete${camelCaseName} = catchAsync(async (req: Request, res: Response) => {
89
+ const { id } = req.params;
90
+ const result = await ${camelCaseName}Services.delete${camelCaseName}(id);
91
+
92
+ sendResponse(res, {
93
+ statusCode: StatusCodes.OK,
94
+ success: true,
95
+ message: '${camelCaseName} deleted successfully',
96
+ data: result,
97
+ });
98
+ });
99
+
100
+ export const ${camelCaseName}Controller = {
101
+ create${camelCaseName},
102
+ update${camelCaseName},
103
+ getSingle${camelCaseName},
104
+ getAll${camelCaseName}s,
105
+ delete${camelCaseName},
106
+ };`;
107
+ };
108
+ exports.generateControllerContent = generateControllerContent;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateRouteContent = void 0;
4
+ const generateRouteContent = (camelCaseName, folderName, fields) => {
5
+ // Check if there are any file/image fields
6
+ const hasImageField = fields.some((field) => field.name === "image" || field.name === "images" || field.name === "media" || field.type.toLowerCase() === "image");
7
+ return `import express from 'express';
8
+ import { ${camelCaseName}Controller } from './${folderName}.controller';
9
+ import { ${camelCaseName}Validations } from './${folderName}.validation';
10
+ import validateRequest from '../../middleware/validateRequest';
11
+ import auth from '../../middleware/auth';
12
+ import { USER_ROLES } from '../../../enum/user';
13
+ ${hasImageField ? `import { fileAndBodyProcessorUsingDiskStorage } from '../../middleware/processReqBody';` : ""}
14
+
15
+ const router = express.Router();
16
+
17
+ router.get(
18
+ '/',
19
+ auth(
20
+ USER_ROLES.SUPER_ADMIN,
21
+ USER_ROLES.ADMIN
22
+ ),
23
+ ${camelCaseName}Controller.getAll${camelCaseName}s
24
+ );
25
+
26
+ router.get(
27
+ '/:id',
28
+ auth(
29
+ USER_ROLES.SUPER_ADMIN,
30
+ USER_ROLES.ADMIN
31
+ ),
32
+ ${camelCaseName}Controller.getSingle${camelCaseName}
33
+ );
34
+
35
+ router.post(
36
+ '/',
37
+ auth(
38
+ USER_ROLES.SUPER_ADMIN,
39
+ USER_ROLES.ADMIN
40
+ ),
41
+ ${hasImageField ? `fileAndBodyProcessorUsingDiskStorage(),` : ""}
42
+ validateRequest(${camelCaseName}Validations.create${camelCaseName}ZodSchema),
43
+ ${camelCaseName}Controller.create${camelCaseName}
44
+ );
45
+
46
+ router.patch(
47
+ '/:id',
48
+ auth(
49
+ USER_ROLES.SUPER_ADMIN,
50
+ USER_ROLES.ADMIN
51
+ ),
52
+ ${hasImageField ? `fileAndBodyProcessorUsingDiskStorage(),` : ""}
53
+ validateRequest(${camelCaseName}Validations.update${camelCaseName}ZodSchema),
54
+ ${camelCaseName}Controller.update${camelCaseName}
55
+ );
56
+
57
+ router.delete(
58
+ '/:id',
59
+ auth(
60
+ USER_ROLES.SUPER_ADMIN,
61
+ USER_ROLES.ADMIN
62
+ ),
63
+ ${camelCaseName}Controller.delete${camelCaseName}
64
+ );
65
+
66
+ export const ${camelCaseName}Routes = router;`;
67
+ };
68
+ exports.generateRouteContent = generateRouteContent;
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateServiceContent = void 0;
4
+ const generateServiceContent = (camelCaseName, folderName, fields, hasFile = false) => {
5
+ // Check if there are any file/image fields or if hasFile flag is true
6
+ const hasImageField = hasFile || fields.some((field) => field.name === "image" || field.name === "images" || field.name === "media" || field.type.toLowerCase() === "image");
7
+ // Check for reference fields for population
8
+ const referenceFields = fields.filter((field) => {
9
+ var _a;
10
+ return field.type.toLowerCase() === "objectid" ||
11
+ (field.type.toLowerCase() === "array" && ((_a = field.arrayItemType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "objectid");
12
+ });
13
+ const populateString = referenceFields.length > 0
14
+ ? `.populate('${referenceFields.map(f => f.name).join("').populate('")}')`
15
+ : "";
16
+ // Generate filterable fields (string and enum types)
17
+ const filterableFields = fields.filter(f => f.type.toLowerCase() === "string" || f.type.toLowerCase() === "enum");
18
+ // Generate searchable fields (string types only)
19
+ const searchableFields = fields.filter(f => f.type.toLowerCase() === "string");
20
+ return `import { StatusCodes } from 'http-status-codes';
21
+ import ApiError from '../../../errors/ApiError';
22
+ import { I${camelCaseName}Filterables, I${camelCaseName} } from './${folderName}.interface';
23
+ import { ${camelCaseName} } from './${folderName}.model';
24
+ import { JwtPayload } from 'jsonwebtoken';
25
+ import { IPaginationOptions } from '../../../interfaces/pagination';
26
+ import { paginationHelper } from '../../../helpers/paginationHelper';
27
+ import { ${folderName}SearchableFields } from './${folderName}.constants';
28
+ import { Types } from 'mongoose';
29
+ ${hasImageField
30
+ ? `import removeFile from '../../../helpers/fileHelper';`
31
+ : ""}
32
+
33
+ const create${camelCaseName} = async (
34
+ user: JwtPayload,
35
+ payload: I${camelCaseName}
36
+ ): Promise<I${camelCaseName}> => {
37
+ try {
38
+ const result = await ${camelCaseName}.create(payload);
39
+ if (!result) {
40
+ ${hasImageField ? `await removeFile(payload.images || payload.media);` : ""}
41
+ throw new ApiError(
42
+ StatusCodes.BAD_REQUEST,
43
+ 'Failed to create ${camelCaseName}, please try again with valid data.'
44
+ );
45
+ }
46
+
47
+ return result;
48
+ } catch (error: any) {
49
+ ${hasImageField ? `if (payload.images || payload.media) await removeFile(payload.images || payload.media);` : ""}
50
+ if (error.code === 11000) {
51
+ throw new ApiError(StatusCodes.CONFLICT, 'Duplicate entry found');
52
+ }
53
+ throw error;
54
+ }
55
+ };
56
+
57
+ const getAll${camelCaseName}s = async (
58
+ user: JwtPayload,
59
+ filterables: I${camelCaseName}Filterables,
60
+ pagination: IPaginationOptions
61
+ ) => {
62
+ const { searchTerm, ...filterData } = filterables;
63
+ const { page, skip, limit, sortBy, sortOrder } = paginationHelper.calculatePagination(pagination);
64
+
65
+ const andConditions = [];
66
+
67
+ // Search functionality
68
+ if (searchTerm) {
69
+ andConditions.push({
70
+ $or: ${folderName}SearchableFields.map((field) => ({
71
+ [field]: {
72
+ $regex: searchTerm,
73
+ $options: 'i',
74
+ },
75
+ })),
76
+ });
77
+ }
78
+
79
+ // Filter functionality
80
+ if (Object.keys(filterData).length) {
81
+ andConditions.push({
82
+ $and: Object.entries(filterData).map(([key, value]) => ({
83
+ [key]: value,
84
+ })),
85
+ });
86
+ }
87
+
88
+ const whereConditions = andConditions.length ? { $and: andConditions } : {};
89
+
90
+ const [result, total] = await Promise.all([
91
+ ${camelCaseName}
92
+ .find(whereConditions)
93
+ .skip(skip)
94
+ .limit(limit)
95
+ .sort({ [sortBy]: sortOrder })${populateString},
96
+ ${camelCaseName}.countDocuments(whereConditions),
97
+ ]);
98
+
99
+ return {
100
+ meta: {
101
+ page,
102
+ limit,
103
+ total,
104
+ totalPages: Math.ceil(total / limit),
105
+ },
106
+ data: result,
107
+ };
108
+ };
109
+
110
+ const getSingle${camelCaseName} = async (id: string): Promise<I${camelCaseName}> => {
111
+ if (!Types.ObjectId.isValid(id)) {
112
+ throw new ApiError(StatusCodes.BAD_REQUEST, 'Invalid ${camelCaseName} ID');
113
+ }
114
+
115
+ const result = await ${camelCaseName}.findById(id)${populateString};
116
+ if (!result) {
117
+ throw new ApiError(
118
+ StatusCodes.NOT_FOUND,
119
+ 'Requested ${folderName} not found, please try again with valid id'
120
+ );
121
+ }
122
+
123
+ return result;
124
+ };
125
+
126
+ const update${camelCaseName} = async (
127
+ id: string,
128
+ payload: Partial<I${camelCaseName}>
129
+ ): Promise<I${camelCaseName} | null> => {
130
+ if (!Types.ObjectId.isValid(id)) {
131
+ throw new ApiError(StatusCodes.BAD_REQUEST, 'Invalid ${camelCaseName} ID');
132
+ }
133
+
134
+ const result = await ${camelCaseName}.findByIdAndUpdate(
135
+ new Types.ObjectId(id),
136
+ { $set: payload },
137
+ {
138
+ new: true,
139
+ runValidators: true,
140
+ }
141
+ )${populateString};
142
+
143
+ if (!result) {
144
+ throw new ApiError(
145
+ StatusCodes.NOT_FOUND,
146
+ 'Requested ${folderName} not found, please try again with valid id'
147
+ );
148
+ }
149
+
150
+ return result;
151
+ };
152
+
153
+ const delete${camelCaseName} = async (id: string): Promise<I${camelCaseName}> => {
154
+ if (!Types.ObjectId.isValid(id)) {
155
+ throw new ApiError(StatusCodes.BAD_REQUEST, 'Invalid ${camelCaseName} ID');
156
+ }
157
+
158
+ const result = await ${camelCaseName}.findByIdAndDelete(id);
159
+ if (!result) {
160
+ throw new ApiError(
161
+ StatusCodes.NOT_FOUND,
162
+ 'Something went wrong while deleting ${folderName}, please try again with valid id.'
163
+ );
164
+ }
165
+
166
+ ${hasImageField
167
+ ? `// Remove associated files
168
+ if (result.image || result.images || result.media) {
169
+ await removeFile(result.image || result.images || result.media);
170
+ }`
171
+ : ""}
172
+
173
+ return result;
174
+ };
175
+
176
+ export const ${camelCaseName}Services = {
177
+ create${camelCaseName},
178
+ getAll${camelCaseName}s,
179
+ getSingle${camelCaseName},
180
+ update${camelCaseName},
181
+ delete${camelCaseName},
182
+ };`;
183
+ };
184
+ exports.generateServiceContent = generateServiceContent;
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });