nexpgen 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,191 @@
1
+ {{#if isClass}}
2
+ const multer = require('multer');
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+
6
+ class ImageUploadHelper {
7
+ constructor() {
8
+ this.uploadDir = path.join(process.cwd(), 'config', 'uploads', 'images');
9
+ this.publicDir = path.join(process.cwd(), 'public', 'images');
10
+ this.storage = this.setupStorage();
11
+ this.upload = this.setupMulter();
12
+ this.ensureDirectories();
13
+ }
14
+
15
+ ensureDirectories() {
16
+ // Ensure upload directory exists
17
+ if (!fs.existsSync(this.uploadDir)) {
18
+ fs.mkdirSync(this.uploadDir, { recursive: true });
19
+ }
20
+ // Ensure public images directory exists
21
+ if (!fs.existsSync(this.publicDir)) {
22
+ fs.mkdirSync(this.publicDir, { recursive: true });
23
+ }
24
+ }
25
+
26
+ setupStorage() {
27
+ return multer.diskStorage({
28
+ destination: (req, file, cb) => {
29
+ cb(null, this.uploadDir);
30
+ },
31
+ filename: (req, file, cb) => {
32
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
33
+ const ext = path.extname(file.originalname);
34
+ cb(null, file.fieldname + '-' + uniqueSuffix + ext);
35
+ }
36
+ });
37
+ }
38
+
39
+ setupMulter() {
40
+ const fileFilter = (req, file, cb) => {
41
+ const allowedTypes = /jpeg|jpg|png|gif|webp/;
42
+ const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
43
+ const mimetype = allowedTypes.test(file.mimetype);
44
+
45
+ if (mimetype && extname) {
46
+ return cb(null, true);
47
+ } else {
48
+ cb(new Error('Only image files are allowed!'));
49
+ }
50
+ };
51
+
52
+ return multer({
53
+ storage: this.storage,
54
+ limits: {
55
+ fileSize: 5 * 1024 * 1024 // 5MB limit
56
+ },
57
+ fileFilter: fileFilter
58
+ });
59
+ }
60
+
61
+ getSingleUpload(fieldName) {
62
+ return this.upload.single(fieldName);
63
+ }
64
+
65
+ getMultipleUpload(fieldName, maxCount = 5) {
66
+ return this.upload.array(fieldName, maxCount);
67
+ }
68
+
69
+ deleteFile(filePath) {
70
+ try {
71
+ const fullPath = path.isAbsolute(filePath)
72
+ ? filePath
73
+ : path.join(this.uploadDir, filePath);
74
+
75
+ if (fs.existsSync(fullPath)) {
76
+ fs.unlinkSync(fullPath);
77
+ return true;
78
+ }
79
+ return false;
80
+ } catch (error) {
81
+ console.error(`Error deleting file: ${error.message}`);
82
+ return false;
83
+ }
84
+ }
85
+
86
+ getUploadPath() {
87
+ return this.uploadDir;
88
+ }
89
+
90
+ getPublicPath() {
91
+ return this.publicDir;
92
+ }
93
+ }
94
+
95
+ module.exports = new ImageUploadHelper();
96
+ {{else}}
97
+ const multer = require('multer');
98
+ const path = require('path');
99
+ const fs = require('fs');
100
+
101
+ const uploadDir = path.join(process.cwd(), 'config', 'uploads', 'images');
102
+ const publicDir = path.join(process.cwd(), 'public', 'images');
103
+
104
+ const ensureDirectories = () => {
105
+ // Ensure upload directory exists
106
+ if (!fs.existsSync(uploadDir)) {
107
+ fs.mkdirSync(uploadDir, { recursive: true });
108
+ }
109
+ // Ensure public images directory exists
110
+ if (!fs.existsSync(publicDir)) {
111
+ fs.mkdirSync(publicDir, { recursive: true });
112
+ }
113
+ };
114
+
115
+ ensureDirectories();
116
+
117
+ const setupStorage = () => {
118
+ return multer.diskStorage({
119
+ destination: (req, file, cb) => {
120
+ cb(null, uploadDir);
121
+ },
122
+ filename: (req, file, cb) => {
123
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
124
+ const ext = path.extname(file.originalname);
125
+ cb(null, file.fieldname + '-' + uniqueSuffix + ext);
126
+ }
127
+ });
128
+ };
129
+
130
+ const fileFilter = (req, file, cb) => {
131
+ const allowedTypes = /jpeg|jpg|png|gif|webp/;
132
+ const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
133
+ const mimetype = allowedTypes.test(file.mimetype);
134
+
135
+ if (mimetype && extname) {
136
+ return cb(null, true);
137
+ } else {
138
+ cb(new Error('Only image files are allowed!'));
139
+ }
140
+ };
141
+
142
+ const upload = multer({
143
+ storage: setupStorage(),
144
+ limits: {
145
+ fileSize: 5 * 1024 * 1024 // 5MB limit
146
+ },
147
+ fileFilter: fileFilter
148
+ });
149
+
150
+ const getSingleUpload = (fieldName) => {
151
+ return upload.single(fieldName);
152
+ };
153
+
154
+ const getMultipleUpload = (fieldName, maxCount = 5) => {
155
+ return upload.array(fieldName, maxCount);
156
+ };
157
+
158
+ const deleteFile = (filePath) => {
159
+ try {
160
+ const fullPath = path.isAbsolute(filePath)
161
+ ? filePath
162
+ : path.join(uploadDir, filePath);
163
+
164
+ if (fs.existsSync(fullPath)) {
165
+ fs.unlinkSync(fullPath);
166
+ return true;
167
+ }
168
+ return false;
169
+ } catch (error) {
170
+ console.error(`Error deleting file: ${error.message}`);
171
+ return false;
172
+ }
173
+ };
174
+
175
+ const getUploadPath = () => {
176
+ return uploadDir;
177
+ };
178
+
179
+ const getPublicPath = () => {
180
+ return publicDir;
181
+ };
182
+
183
+ module.exports = {
184
+ getSingleUpload,
185
+ getMultipleUpload,
186
+ deleteFile,
187
+ getUploadPath,
188
+ getPublicPath
189
+ };
190
+ {{/if}}
191
+
@@ -0,0 +1,171 @@
1
+ {{#if isClass}}
2
+ class TimeConverterHelper {
3
+ constructor() {
4
+ this.timeZones = {
5
+ UTC: 'UTC',
6
+ EST: 'America/New_York',
7
+ PST: 'America/Los_Angeles',
8
+ GMT: 'Europe/London',
9
+ IST: 'Asia/Kolkata'
10
+ };
11
+ }
12
+
13
+ toUTC(date) {
14
+ return new Date(date.toUTCString());
15
+ }
16
+
17
+ toLocal(date, timeZone = 'UTC') {
18
+ return new Date(date.toLocaleString('en-US', { timeZone }));
19
+ }
20
+
21
+ format(date, format = 'YYYY-MM-DD HH:mm:ss') {
22
+ const year = date.getFullYear();
23
+ const month = String(date.getMonth() + 1).padStart(2, '0');
24
+ const day = String(date.getDate()).padStart(2, '0');
25
+ const hours = String(date.getHours()).padStart(2, '0');
26
+ const minutes = String(date.getMinutes()).padStart(2, '0');
27
+ const seconds = String(date.getSeconds()).padStart(2, '0');
28
+
29
+ return format
30
+ .replace('YYYY', year)
31
+ .replace('MM', month)
32
+ .replace('DD', day)
33
+ .replace('HH', hours)
34
+ .replace('mm', minutes)
35
+ .replace('ss', seconds);
36
+ }
37
+
38
+ addDays(date, days) {
39
+ const result = new Date(date);
40
+ result.setDate(result.getDate() + days);
41
+ return result;
42
+ }
43
+
44
+ addHours(date, hours) {
45
+ const result = new Date(date);
46
+ result.setHours(result.getHours() + hours);
47
+ return result;
48
+ }
49
+
50
+ addMinutes(date, minutes) {
51
+ const result = new Date(date);
52
+ result.setMinutes(result.getMinutes() + minutes);
53
+ return result;
54
+ }
55
+
56
+ differenceInDays(date1, date2) {
57
+ const diffTime = Math.abs(date2 - date1);
58
+ return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
59
+ }
60
+
61
+ differenceInHours(date1, date2) {
62
+ const diffTime = Math.abs(date2 - date1);
63
+ return Math.ceil(diffTime / (1000 * 60 * 60));
64
+ }
65
+
66
+ differenceInMinutes(date1, date2) {
67
+ const diffTime = Math.abs(date2 - date1);
68
+ return Math.ceil(diffTime / (1000 * 60));
69
+ }
70
+
71
+ isBefore(date1, date2) {
72
+ return date1 < date2;
73
+ }
74
+
75
+ isAfter(date1, date2) {
76
+ return date1 > date2;
77
+ }
78
+
79
+ isSameDay(date1, date2) {
80
+ return date1.toDateString() === date2.toDateString();
81
+ }
82
+ }
83
+
84
+ module.exports = new TimeConverterHelper();
85
+ {{else}}
86
+ const toUTC = (date) => {
87
+ return new Date(date.toUTCString());
88
+ };
89
+
90
+ const toLocal = (date, timeZone = 'UTC') => {
91
+ return new Date(date.toLocaleString('en-US', { timeZone }));
92
+ };
93
+
94
+ const format = (date, formatStr = 'YYYY-MM-DD HH:mm:ss') => {
95
+ const year = date.getFullYear();
96
+ const month = String(date.getMonth() + 1).padStart(2, '0');
97
+ const day = String(date.getDate()).padStart(2, '0');
98
+ const hours = String(date.getHours()).padStart(2, '0');
99
+ const minutes = String(date.getMinutes()).padStart(2, '0');
100
+ const seconds = String(date.getSeconds()).padStart(2, '0');
101
+
102
+ return formatStr
103
+ .replace('YYYY', year)
104
+ .replace('MM', month)
105
+ .replace('DD', day)
106
+ .replace('HH', hours)
107
+ .replace('mm', minutes)
108
+ .replace('ss', seconds);
109
+ };
110
+
111
+ const addDays = (date, days) => {
112
+ const result = new Date(date);
113
+ result.setDate(result.getDate() + days);
114
+ return result;
115
+ };
116
+
117
+ const addHours = (date, hours) => {
118
+ const result = new Date(date);
119
+ result.setHours(result.getHours() + hours);
120
+ return result;
121
+ };
122
+
123
+ const addMinutes = (date, minutes) => {
124
+ const result = new Date(date);
125
+ result.setMinutes(result.getMinutes() + minutes);
126
+ return result;
127
+ };
128
+
129
+ const differenceInDays = (date1, date2) => {
130
+ const diffTime = Math.abs(date2 - date1);
131
+ return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
132
+ };
133
+
134
+ const differenceInHours = (date1, date2) => {
135
+ const diffTime = Math.abs(date2 - date1);
136
+ return Math.ceil(diffTime / (1000 * 60 * 60));
137
+ };
138
+
139
+ const differenceInMinutes = (date1, date2) => {
140
+ const diffTime = Math.abs(date2 - date1);
141
+ return Math.ceil(diffTime / (1000 * 60));
142
+ };
143
+
144
+ const isBefore = (date1, date2) => {
145
+ return date1 < date2;
146
+ };
147
+
148
+ const isAfter = (date1, date2) => {
149
+ return date1 > date2;
150
+ };
151
+
152
+ const isSameDay = (date1, date2) => {
153
+ return date1.toDateString() === date2.toDateString();
154
+ };
155
+
156
+ module.exports = {
157
+ toUTC,
158
+ toLocal,
159
+ format,
160
+ addDays,
161
+ addHours,
162
+ addMinutes,
163
+ differenceInDays,
164
+ differenceInHours,
165
+ differenceInMinutes,
166
+ isBefore,
167
+ isAfter,
168
+ isSameDay
169
+ };
170
+ {{/if}}
171
+
@@ -0,0 +1,302 @@
1
+ {{#if isClass}}
2
+ class {{className}}Middleware {
3
+ constructor() {
4
+ this.name = '{{name}}';
5
+ }
6
+
7
+ {{#if isAuth}}
8
+ authenticate(req, res, next) {
9
+ try {
10
+ // TODO: Implement authentication logic
11
+ const token = req.headers.authorization?.split(' ')[1];
12
+
13
+ if (!token) {
14
+ return res.status(401).json({
15
+ success: false,
16
+ message: 'Authentication token required'
17
+ });
18
+ }
19
+
20
+ // TODO: Verify token
21
+ // const decoded = jwt.verify(token, process.env.JWT_SECRET);
22
+ // req.user = decoded;
23
+
24
+ next();
25
+ } catch (error) {
26
+ res.status(401).json({
27
+ success: false,
28
+ message: 'Invalid or expired token'
29
+ });
30
+ }
31
+ }
32
+
33
+ authorize(...roles) {
34
+ return (req, res, next) => {
35
+ try {
36
+ // TODO: Check if user has required role
37
+ // if (!roles.includes(req.user.role)) {
38
+ // return res.status(403).json({
39
+ // success: false,
40
+ // message: 'Insufficient permissions'
41
+ // });
42
+ // }
43
+ next();
44
+ } catch (error) {
45
+ res.status(403).json({
46
+ success: false,
47
+ message: 'Authorization failed'
48
+ });
49
+ }
50
+ };
51
+ }
52
+ {{/if}}
53
+
54
+ {{#if isValidation}}
55
+ validate(validationSchema) {
56
+ return (req, res, next) => {
57
+ try {
58
+ // TODO: Implement validation using Joi/Yup
59
+ // const { error, value } = validationSchema.validate(req.body);
60
+ // if (error) {
61
+ // return res.status(400).json({
62
+ // success: false,
63
+ // message: 'Validation error',
64
+ // errors: error.details.map(detail => detail.message)
65
+ // });
66
+ // }
67
+ // req.validatedData = value;
68
+ next();
69
+ } catch (error) {
70
+ res.status(400).json({
71
+ success: false,
72
+ message: 'Validation failed',
73
+ error: error.message
74
+ });
75
+ }
76
+ };
77
+ }
78
+ {{/if}}
79
+
80
+ {{#if isErrorHandler}}
81
+ errorHandler(err, req, res, next) {
82
+ console.error('Error:', err);
83
+
84
+ // Default error
85
+ let statusCode = err.statusCode || 500;
86
+ let message = err.message || 'Internal server error';
87
+
88
+ // Handle specific error types
89
+ if (err.name === 'ValidationError') {
90
+ statusCode = 400;
91
+ message = 'Validation error';
92
+ } else if (err.name === 'UnauthorizedError') {
93
+ statusCode = 401;
94
+ message = 'Unauthorized';
95
+ } else if (err.name === 'CastError') {
96
+ statusCode = 400;
97
+ message = 'Invalid ID format';
98
+ }
99
+
100
+ res.status(statusCode).json({
101
+ success: false,
102
+ message: message,
103
+ ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
104
+ });
105
+ }
106
+
107
+ notFound(req, res, next) {
108
+ res.status(404).json({
109
+ success: false,
110
+ message: `Route ${req.originalUrl} not found`
111
+ });
112
+ }
113
+ {{/if}}
114
+
115
+ {{#if isRateLimit}}
116
+ rateLimiter(windowMs = 15 * 60 * 1000, max = 100) {
117
+ const requests = new Map();
118
+
119
+ return (req, res, next) => {
120
+ const ip = req.ip || req.connection.remoteAddress;
121
+ const now = Date.now();
122
+
123
+ if (!requests.has(ip)) {
124
+ requests.set(ip, { count: 1, resetTime: now + windowMs });
125
+ return next();
126
+ }
127
+
128
+ const record = requests.get(ip);
129
+
130
+ if (now > record.resetTime) {
131
+ record.count = 1;
132
+ record.resetTime = now + windowMs;
133
+ return next();
134
+ }
135
+
136
+ if (record.count >= max) {
137
+ return res.status(429).json({
138
+ success: false,
139
+ message: 'Too many requests, please try again later'
140
+ });
141
+ }
142
+
143
+ record.count++;
144
+ next();
145
+ };
146
+ }
147
+ {{/if}}
148
+ }
149
+
150
+ module.exports = new {{className}}Middleware();
151
+ {{else}}
152
+ {{#if isAuth}}
153
+ const authenticate = (req, res, next) => {
154
+ try {
155
+ // TODO: Implement authentication logic
156
+ const token = req.headers.authorization?.split(' ')[1];
157
+
158
+ if (!token) {
159
+ return res.status(401).json({
160
+ success: false,
161
+ message: 'Authentication token required'
162
+ });
163
+ }
164
+
165
+ // TODO: Verify token
166
+ // const decoded = jwt.verify(token, process.env.JWT_SECRET);
167
+ // req.user = decoded;
168
+
169
+ next();
170
+ } catch (error) {
171
+ res.status(401).json({
172
+ success: false,
173
+ message: 'Invalid or expired token'
174
+ });
175
+ }
176
+ };
177
+
178
+ const authorize = (...roles) => {
179
+ return (req, res, next) => {
180
+ try {
181
+ // TODO: Check if user has required role
182
+ // if (!roles.includes(req.user.role)) {
183
+ // return res.status(403).json({
184
+ // success: false,
185
+ // message: 'Insufficient permissions'
186
+ // });
187
+ // }
188
+ next();
189
+ } catch (error) {
190
+ res.status(403).json({
191
+ success: false,
192
+ message: 'Authorization failed'
193
+ });
194
+ }
195
+ };
196
+ };
197
+
198
+ module.exports = { authenticate, authorize };
199
+ {{/if}}
200
+
201
+ {{#if isValidation}}
202
+ const validate = (validationSchema) => {
203
+ return (req, res, next) => {
204
+ try {
205
+ // TODO: Implement validation using Joi/Yup
206
+ // const { error, value } = validationSchema.validate(req.body);
207
+ // if (error) {
208
+ // return res.status(400).json({
209
+ // success: false,
210
+ // message: 'Validation error',
211
+ // errors: error.details.map(detail => detail.message)
212
+ // });
213
+ // }
214
+ // req.validatedData = value;
215
+ next();
216
+ } catch (error) {
217
+ res.status(400).json({
218
+ success: false,
219
+ message: 'Validation failed',
220
+ error: error.message
221
+ });
222
+ }
223
+ };
224
+ };
225
+
226
+ module.exports = { validate };
227
+ {{/if}}
228
+
229
+ {{#if isErrorHandler}}
230
+ const errorHandler = (err, req, res, next) => {
231
+ console.error('Error:', err);
232
+
233
+ // Default error
234
+ let statusCode = err.statusCode || 500;
235
+ let message = err.message || 'Internal server error';
236
+
237
+ // Handle specific error types
238
+ if (err.name === 'ValidationError') {
239
+ statusCode = 400;
240
+ message = 'Validation error';
241
+ } else if (err.name === 'UnauthorizedError') {
242
+ statusCode = 401;
243
+ message = 'Unauthorized';
244
+ } else if (err.name === 'CastError') {
245
+ statusCode = 400;
246
+ message = 'Invalid ID format';
247
+ }
248
+
249
+ res.status(statusCode).json({
250
+ success: false,
251
+ message: message,
252
+ ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
253
+ });
254
+ };
255
+
256
+ const notFound = (req, res, next) => {
257
+ res.status(404).json({
258
+ success: false,
259
+ message: `Route ${req.originalUrl} not found`
260
+ });
261
+ };
262
+
263
+ module.exports = { errorHandler, notFound };
264
+ {{/if}}
265
+
266
+ {{#if isRateLimit}}
267
+ const rateLimiter = (windowMs = 15 * 60 * 1000, max = 100) => {
268
+ const requests = new Map();
269
+
270
+ return (req, res, next) => {
271
+ const ip = req.ip || req.connection.remoteAddress;
272
+ const now = Date.now();
273
+
274
+ if (!requests.has(ip)) {
275
+ requests.set(ip, { count: 1, resetTime: now + windowMs });
276
+ return next();
277
+ }
278
+
279
+ const record = requests.get(ip);
280
+
281
+ if (now > record.resetTime) {
282
+ record.count = 1;
283
+ record.resetTime = now + windowMs;
284
+ return next();
285
+ }
286
+
287
+ if (record.count >= max) {
288
+ return res.status(429).json({
289
+ success: false,
290
+ message: 'Too many requests, please try again later'
291
+ });
292
+ }
293
+
294
+ record.count++;
295
+ next();
296
+ };
297
+ };
298
+
299
+ module.exports = { rateLimiter };
300
+ {{/if}}
301
+ {{/if}}
302
+
@@ -0,0 +1,56 @@
1
+ {{#if isClass}}
2
+ const express = require('express');
3
+ const {{camelCaseName}}Controller = require('../controllers/{{name}}.controller');
4
+
5
+ class {{className}}Routes {
6
+ constructor() {
7
+ this.router = express.Router();
8
+ this.setupRoutes();
9
+ }
10
+
11
+ setupRoutes() {
12
+ // GET /api/{{name}}s - Get all {{name}}s
13
+ this.router.get('/', {{camelCaseName}}Controller.getAll);
14
+
15
+ // GET /api/{{name}}s/:id - Get {{name}} by ID
16
+ this.router.get('/:id', {{camelCaseName}}Controller.getById);
17
+
18
+ // POST /api/{{name}}s - Create new {{name}}
19
+ this.router.post('/', {{camelCaseName}}Controller.create);
20
+
21
+ // PUT /api/{{name}}s/:id - Update {{name}}
22
+ this.router.put('/:id', {{camelCaseName}}Controller.update);
23
+
24
+ // DELETE /api/{{name}}s/:id - Delete {{name}}
25
+ this.router.delete('/:id', {{camelCaseName}}Controller.remove);
26
+ }
27
+
28
+ getRouter() {
29
+ return this.router;
30
+ }
31
+ }
32
+
33
+ module.exports = new {{className}}Routes().getRouter();
34
+ {{else}}
35
+ const express = require('express');
36
+ const router = express.Router();
37
+ const {{camelCaseName}}Controller = require('../controllers/{{name}}.controller');
38
+
39
+ // GET /api/{{name}}s - Get all {{name}}s
40
+ router.get('/', {{camelCaseName}}Controller.getAll);
41
+
42
+ // GET /api/{{name}}s/:id - Get {{name}} by ID
43
+ router.get('/:id', {{camelCaseName}}Controller.getById);
44
+
45
+ // POST /api/{{name}}s - Create new {{name}}
46
+ router.post('/', {{camelCaseName}}Controller.create);
47
+
48
+ // PUT /api/{{name}}s/:id - Update {{name}}
49
+ router.put('/:id', {{camelCaseName}}Controller.update);
50
+
51
+ // DELETE /api/{{name}}s/:id - Delete {{name}}
52
+ router.delete('/:id', {{camelCaseName}}Controller.remove);
53
+
54
+ module.exports = router;
55
+ {{/if}}
56
+