crud-api-express 1.0.4 → 1.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/dist/index.d.ts CHANGED
@@ -44,8 +44,14 @@ declare class CrudController<T extends Document> {
44
44
  private model;
45
45
  private endpoint;
46
46
  private router;
47
+ private routes;
47
48
  constructor(model: Model<T>, endpoint: string, options?: CrudOptions<T>);
48
49
  private configureRoutes;
49
50
  getRouter(): Router;
51
+ getRoutes(): {
52
+ method: string;
53
+ path: string;
54
+ params?: string[];
55
+ }[];
50
56
  }
51
57
  export default CrudController;
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ class CrudController {
5
5
  this.model = model;
6
6
  this.endpoint = endpoint;
7
7
  this.router = Router();
8
+ this.routes = [];
8
9
  this.configureRoutes(options);
9
10
  }
10
11
  configureRoutes(options) {
@@ -12,13 +13,18 @@ class CrudController {
12
13
  const applyMiddleware = (routeHandler) => {
13
14
  return [...middleware, routeHandler];
14
15
  };
16
+ // Helper to register a route
17
+ const registerRoute = (method, path, params) => {
18
+ this.routes.push({ method, path, params });
19
+ };
15
20
  // Create
16
21
  if (methods.includes('POST')) {
17
- this.router.post(`/${this.endpoint}`, applyMiddleware(async (req, res) => {
22
+ const path = `/${this.endpoint}`;
23
+ this.router.post(path, applyMiddleware(async (req, res) => {
18
24
  const method = 'POST';
19
25
  try {
20
- const item = new this.model(req.body);
21
- const result = await item.save();
26
+ console.log("debug", req.body);
27
+ const result = await this.model.create(req.body);
22
28
  if (options.relatedModel && options.relatedMethods?.includes('POST')) {
23
29
  await options.relatedModel.create({ [options.relatedField]: result._id, ...req.body });
24
30
  }
@@ -28,9 +34,12 @@ class CrudController {
28
34
  onError(res, method, error);
29
35
  }
30
36
  }));
37
+ registerRoute('POST', path);
31
38
  }
39
+ // Read all
32
40
  if (methods.includes('GET')) {
33
- this.router.get(`/${this.endpoint}`, applyMiddleware(async (req, res) => {
41
+ const path = `/${this.endpoint}`;
42
+ this.router.get(path, applyMiddleware(async (req, res) => {
34
43
  const method = 'GET';
35
44
  try {
36
45
  const { filter, sort, page, limit } = req.query;
@@ -65,9 +74,12 @@ class CrudController {
65
74
  onError(res, method, error);
66
75
  }
67
76
  }));
77
+ registerRoute('GET', path, ['filter', 'sort', 'page', 'limit']);
68
78
  }
79
+ // Read one
69
80
  if (methods.includes('GET')) {
70
- this.router.get(`/${this.endpoint}/:id`, applyMiddleware(async (req, res) => {
81
+ const path = `/${this.endpoint}/:id`;
82
+ this.router.get(path, applyMiddleware(async (req, res) => {
71
83
  const method = 'GET';
72
84
  try {
73
85
  let item;
@@ -97,9 +109,12 @@ class CrudController {
97
109
  onError(res, method, error);
98
110
  }
99
111
  }));
112
+ registerRoute('GET', path, ['id']);
100
113
  }
114
+ // Update
101
115
  if (methods.includes('PUT')) {
102
- this.router.put(`/${this.endpoint}/:id`, applyMiddleware(async (req, res) => {
116
+ const path = `/${this.endpoint}/:id`;
117
+ this.router.put(path, applyMiddleware(async (req, res) => {
103
118
  const method = 'PUT';
104
119
  try {
105
120
  const item = await this.model.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
@@ -115,9 +130,12 @@ class CrudController {
115
130
  onError(res, method, error);
116
131
  }
117
132
  }));
133
+ registerRoute('PUT', path, ['id']);
118
134
  }
135
+ // Delete multiple
119
136
  if (methods.includes('DELETE')) {
120
- this.router.delete(`/${this.endpoint}`, applyMiddleware(async (req, res) => {
137
+ const path = `/${this.endpoint}`;
138
+ this.router.delete(path, applyMiddleware(async (req, res) => {
121
139
  const method = 'DELETE';
122
140
  try {
123
141
  const query = req.query.filter ? JSON.parse(req.query.filter) : {};
@@ -134,9 +152,12 @@ class CrudController {
134
152
  onError(res, method, error);
135
153
  }
136
154
  }));
155
+ registerRoute('DELETE', path, ['filter']);
137
156
  }
157
+ // Delete one
138
158
  if (methods.includes('DELETE')) {
139
- this.router.delete(`/${this.endpoint}/:id`, applyMiddleware(async (req, res) => {
159
+ const path = `/${this.endpoint}/:id`;
160
+ this.router.delete(path, applyMiddleware(async (req, res) => {
140
161
  const method = 'DELETE';
141
162
  try {
142
163
  const item = await this.model.findByIdAndDelete(req.params.id);
@@ -152,9 +173,12 @@ class CrudController {
152
173
  onError(res, method, error);
153
174
  }
154
175
  }));
176
+ registerRoute('DELETE', path, ['id']);
155
177
  }
178
+ // Aggregate
156
179
  if (methods.includes('GET') && options.aggregatePipeline) {
157
- this.router.get(`/${this.endpoint}/aggregate`, applyMiddleware(async (req, res) => {
180
+ const path = `/${this.endpoint}/aggregate`;
181
+ this.router.get(path, applyMiddleware(async (req, res) => {
158
182
  const method = 'GET (Aggregate)';
159
183
  try {
160
184
  const pipeline = options.aggregatePipeline ?? [];
@@ -165,12 +189,15 @@ class CrudController {
165
189
  onError(res, method, error);
166
190
  }
167
191
  }));
192
+ registerRoute('GET', path);
168
193
  }
194
+ // Custom routes
169
195
  if (options.customRoutes) {
170
196
  options.customRoutes.forEach(route => {
171
197
  const { method, path, handler } = route;
172
198
  if (methods.includes(method.toUpperCase())) {
173
199
  this.router[method](`/${this.endpoint}${path}`, applyMiddleware(handler));
200
+ registerRoute(method.toUpperCase(), `/${this.endpoint}${path}`);
174
201
  }
175
202
  });
176
203
  }
@@ -178,6 +205,9 @@ class CrudController {
178
205
  getRouter() {
179
206
  return this.router;
180
207
  }
208
+ getRoutes() {
209
+ return this.routes;
210
+ }
181
211
  }
182
212
 
183
213
  export { CrudController as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crud-api-express",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
package/readme.md CHANGED
@@ -66,6 +66,7 @@ mongoose.connect(mongoURI, { useNewUrlParser: false, useUnifiedTopology: false }
66
66
  app.use(express.json());
67
67
 
68
68
  app.use('/api', exampleController.getRouter());
69
+ console.log(exampleController.getRoutes());
69
70
 
70
71
  const PORT = process.env.PORT || 3000;
71
72
  app.listen(PORT, () => {
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Request, Response, Router, NextFunction } from 'express';
1
+ import { Request, Response, Router, NextFunction } from 'express';
2
2
  import { Document, Model, Aggregate } from 'mongoose';
3
3
 
4
4
  interface CrudOptions<T extends Document> {
@@ -17,11 +17,13 @@ class CrudController<T extends Document> {
17
17
  private model: Model<T>;
18
18
  private endpoint: string;
19
19
  private router: Router;
20
+ private routes: { method: string, path: string, params?: string[] }[];
20
21
 
21
22
  constructor(model: Model<T>, endpoint: string, options: CrudOptions<T> = {}) {
22
23
  this.model = model;
23
24
  this.endpoint = endpoint;
24
25
  this.router = Router();
26
+ this.routes = [];
25
27
  this.configureRoutes(options);
26
28
  }
27
29
 
@@ -33,18 +35,23 @@ class CrudController<T extends Document> {
33
35
  methods = ['POST', 'GET', 'PUT', 'DELETE']
34
36
  } = options;
35
37
 
36
-
37
38
  const applyMiddleware = (routeHandler: (req: Request, res: Response) => void) => {
38
39
  return [...middleware, routeHandler];
39
40
  };
40
41
 
42
+ // Helper to register a route
43
+ const registerRoute = (method: string, path: string, params?: string[]) => {
44
+ this.routes.push({ method, path, params });
45
+ };
46
+
41
47
  // Create
42
48
  if (methods.includes('POST')) {
43
- this.router.post(`/${this.endpoint}`, applyMiddleware(async (req, res) => {
49
+ const path = `/${this.endpoint}`;
50
+ this.router.post(path, applyMiddleware(async (req, res) => {
44
51
  const method = 'POST';
45
52
  try {
46
- const item = new this.model(req.body);
47
- const result:any = await item.save();
53
+ console.log("debug",req.body)
54
+ const result:any = await this.model.create(req.body);
48
55
  if (options.relatedModel && options.relatedMethods?.includes('POST')) {
49
56
  await options.relatedModel.create({ [options.relatedField!]: result._id, ...req.body });
50
57
  }
@@ -53,11 +60,13 @@ class CrudController<T extends Document> {
53
60
  onError(res, method, error);
54
61
  }
55
62
  }));
63
+ registerRoute('POST', path);
56
64
  }
57
65
 
58
-
66
+ // Read all
59
67
  if (methods.includes('GET')) {
60
- this.router.get(`/${this.endpoint}`, applyMiddleware(async (req, res) => {
68
+ const path = `/${this.endpoint}`;
69
+ this.router.get(path, applyMiddleware(async (req, res) => {
61
70
  const method = 'GET';
62
71
  try {
63
72
  const { filter, sort, page, limit } = req.query;
@@ -91,10 +100,13 @@ class CrudController<T extends Document> {
91
100
  onError(res, method, error);
92
101
  }
93
102
  }));
103
+ registerRoute('GET', path, ['filter', 'sort', 'page', 'limit']);
94
104
  }
95
105
 
106
+ // Read one
96
107
  if (methods.includes('GET')) {
97
- this.router.get(`/${this.endpoint}/:id`, applyMiddleware(async (req, res) => {
108
+ const path = `/${this.endpoint}/:id`;
109
+ this.router.get(path, applyMiddleware(async (req, res) => {
98
110
  const method = 'GET';
99
111
  try {
100
112
  let item: T | null;
@@ -122,11 +134,13 @@ class CrudController<T extends Document> {
122
134
  onError(res, method, error);
123
135
  }
124
136
  }));
137
+ registerRoute('GET', path, ['id']);
125
138
  }
126
139
 
127
-
140
+ // Update
128
141
  if (methods.includes('PUT')) {
129
- this.router.put(`/${this.endpoint}/:id`, applyMiddleware(async (req, res) => {
142
+ const path = `/${this.endpoint}/:id`;
143
+ this.router.put(path, applyMiddleware(async (req, res) => {
130
144
  const method = 'PUT';
131
145
  try {
132
146
  const item = await this.model.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
@@ -141,32 +155,35 @@ class CrudController<T extends Document> {
141
155
  onError(res, method, error);
142
156
  }
143
157
  }));
158
+ registerRoute('PUT', path, ['id']);
144
159
  }
145
160
 
146
-
147
- if (methods.includes('DELETE')) {
148
- this.router.delete(`/${this.endpoint}`, applyMiddleware(async (req, res) => {
149
- const method = 'DELETE';
150
- try {
151
- const query = req.query.filter ? JSON.parse(req.query.filter as string) : {};
152
- const deleteResult:any = await this.model.deleteMany(query);
153
- if (deleteResult.deletedCount === 0) {
154
- return res.status(404).send();
155
- }
156
- if (options.relatedModel && options.relatedMethods?.includes('DELETE')) {
157
- await options.relatedModel.deleteMany({ [options.relatedField!]: { $in: query } });
158
- }
159
- onSuccess(res, method, deleteResult);
160
- } catch (error: any) {
161
- onError(res, method, error);
161
+ // Delete multiple
162
+ if (methods.includes('DELETE')) {
163
+ const path = `/${this.endpoint}`;
164
+ this.router.delete(path, applyMiddleware(async (req, res) => {
165
+ const method = 'DELETE';
166
+ try {
167
+ const query = req.query.filter ? JSON.parse(req.query.filter as string) : {};
168
+ const deleteResult:any = await this.model.deleteMany(query);
169
+ if (deleteResult.deletedCount === 0) {
170
+ return res.status(404).send();
171
+ }
172
+ if (options.relatedModel && options.relatedMethods?.includes('DELETE')) {
173
+ await options.relatedModel.deleteMany({ [options.relatedField!]: { $in: query } });
174
+ }
175
+ onSuccess(res, method, deleteResult);
176
+ } catch (error: any) {
177
+ onError(res, method, error);
178
+ }
179
+ }));
180
+ registerRoute('DELETE', path, ['filter']);
162
181
  }
163
- }));
164
- }
165
-
166
-
167
182
 
183
+ // Delete one
168
184
  if (methods.includes('DELETE')) {
169
- this.router.delete(`/${this.endpoint}/:id`, applyMiddleware(async (req, res) => {
185
+ const path = `/${this.endpoint}/:id`;
186
+ this.router.delete(path, applyMiddleware(async (req, res) => {
170
187
  const method = 'DELETE';
171
188
  try {
172
189
  const item = await this.model.findByIdAndDelete(req.params.id);
@@ -181,11 +198,13 @@ if (methods.includes('DELETE')) {
181
198
  onError(res, method, error);
182
199
  }
183
200
  }));
201
+ registerRoute('DELETE', path, ['id']);
184
202
  }
185
203
 
186
-
204
+ // Aggregate
187
205
  if (methods.includes('GET') && options.aggregatePipeline) {
188
- this.router.get(`/${this.endpoint}/aggregate`, applyMiddleware(async (req, res) => {
206
+ const path = `/${this.endpoint}/aggregate`;
207
+ this.router.get(path, applyMiddleware(async (req, res) => {
189
208
  const method = 'GET (Aggregate)';
190
209
  try {
191
210
  const pipeline:any = options.aggregatePipeline ?? [];
@@ -195,14 +214,16 @@ if (methods.includes('DELETE')) {
195
214
  onError(res, method, error);
196
215
  }
197
216
  }));
217
+ registerRoute('GET', path);
198
218
  }
199
219
 
200
-
220
+ // Custom routes
201
221
  if (options.customRoutes) {
202
222
  options.customRoutes.forEach(route => {
203
223
  const { method, path, handler } = route;
204
224
  if (methods.includes(method.toUpperCase() as 'POST' | 'GET' | 'PUT' | 'DELETE')) {
205
225
  this.router[method](`/${this.endpoint}${path}`, applyMiddleware(handler));
226
+ registerRoute(method.toUpperCase(), `/${this.endpoint}${path}`);
206
227
  }
207
228
  });
208
229
  }
@@ -211,6 +232,10 @@ if (methods.includes('DELETE')) {
211
232
  public getRouter(): Router {
212
233
  return this.router;
213
234
  }
235
+
236
+ public getRoutes(): { method: string, path: string, params?: string[] }[] {
237
+ return this.routes;
238
+ }
214
239
  }
215
240
 
216
241
  export default CrudController;