nest-mongoose-crud 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -32,22 +32,130 @@ yarn add nest-mongoose-crud
32
32
  ```ts
33
33
  // src/post/schemas/post.schema.ts
34
34
  import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
35
- import { Document } from 'mongoose';
35
+ import mongoose, { Document, Schema as MongooseSchema } from 'mongoose';
36
+ import { User } from 'src/user/schemas/user.schema';
37
+
38
+ export type PostDocument = Post & Document;
39
+
40
+ export enum PostStatus {
41
+ DRAFT = 'draft',
42
+ PUBLISHED = 'published',
43
+ ARCHIVED = 'archived',
44
+ DELETED = 'deleted',
45
+ }
46
+
47
+ export enum PostVisibility {
48
+ PUBLIC = 'public',
49
+ PRIVATE = 'private',
50
+ UNLISTED = 'unlisted',
51
+ }
36
52
 
37
53
  @Schema({ timestamps: true })
38
54
  export class Post {
39
- @Prop({ required: true })
55
+ @Prop({ required: true, index: true, text: true })
40
56
  title: string;
41
57
 
42
- @Prop()
58
+ @Prop({ required: true, index: true, text: true })
43
59
  content: string;
44
60
 
45
- @Prop({ type: String, ref: 'User' })
46
- author: string;
61
+ @Prop({
62
+ type: String,
63
+ enum: PostStatus,
64
+ default: PostStatus.DRAFT,
65
+ index: true,
66
+ })
67
+ status: PostStatus;
68
+
69
+ @Prop({
70
+ type: String,
71
+ enum: PostVisibility,
72
+ default: PostVisibility.PUBLIC,
73
+ index: true,
74
+ })
75
+ visibility: PostVisibility;
76
+
77
+ // --- MANY-TO-ONE RELATIONSHIP WITH USER ---
78
+ @Prop({
79
+ type: mongoose.Schema.Types.ObjectId,
80
+ ref: 'User',
81
+ required: true,
82
+ index: true,
83
+ })
84
+ author: User;
85
+
86
+ // --- FIELDS FOR SEARCHING ---
87
+ @Prop([String])
88
+ keywords: string[];
89
+
90
+ @Prop([String])
91
+ categories: string[];
92
+
93
+ // --- FIELDS FOR RANGE QUERIES ---
94
+ @Prop({ default: 0 })
95
+ viewCount: number;
96
+
97
+ @Prop({ default: 0 })
98
+ likeCount: number;
99
+
100
+ @Prop({ default: 0 })
101
+ commentCount: number;
102
+
103
+ @Prop({ type: Date })
104
+ publishedAt: Date;
105
+
106
+ @Prop()
107
+ readingTime: number; // in minutes
108
+
109
+ // --- FIELDS FOR FILTERING ---
110
+ @Prop({ default: false, index: true })
111
+ isFeatured: boolean;
112
+
113
+ @Prop({ default: false, index: true })
114
+ isPinned: boolean;
115
+
116
+ @Prop({ default: false, index: true })
117
+ allowComments: boolean;
118
+
119
+ @Prop({ default: true })
120
+ allowSharing: boolean;
121
+
122
+ @Prop([String])
123
+ tags: string[];
124
+
125
+ // --- METADATA & SEO ---
126
+ @Prop()
127
+ excerpt: string;
128
+
129
+ @Prop()
130
+ coverImage: string;
131
+
132
+ @Prop()
133
+ slug: string;
134
+
135
+ @Prop()
136
+ metaTitle: string;
137
+
138
+ @Prop()
139
+ metaDescription: string;
140
+
141
+ @Prop({ type: MongooseSchema.Types.Mixed })
142
+ metadata: Record<string, any>;
47
143
  }
48
144
 
49
- export type PostDocument = Post & Document;
50
145
  export const PostSchema = SchemaFactory.createForClass(Post);
146
+
147
+ // --- COMPOUND INDEXES FOR OPTIMIZED QUERIES ---
148
+
149
+ // Text search index on title and content
150
+ PostSchema.index({ title: 'text', content: 'text' });
151
+
152
+ // For user's post feed
153
+ PostSchema.index({
154
+ status: 1,
155
+ visibility: 1,
156
+ publishedAt: -1,
157
+ isFeatured: 1,
158
+ });
51
159
  ```
52
160
 
53
161
  ### 2. Create a service by extending `BaseCrudService`
@@ -65,11 +173,6 @@ export class PostService extends BaseCrudService<PostDocument> {
65
173
  constructor(@InjectModel(Post.name) model: Model<PostDocument>) {
66
174
  super(model);
67
175
  }
68
-
69
- // optional: add custom methods or override existing ones
70
- findAllUpdate() {
71
- return this.model.find({});
72
- }
73
176
  }
74
177
  ```
75
178
 
@@ -97,28 +200,6 @@ export class PostController extends BaseController {
97
200
  constructor(protected readonly service: PostService) {
98
201
  super(service);
99
202
  }
100
-
101
- // you may override any endpoint, add new ones, etc.
102
- @Get()
103
- findAll() {
104
- return this.service.findAllUpdate();
105
- }
106
- }
107
- ```
108
-
109
- > 👇 Example user controller from the test project:
110
-
111
- ```ts
112
- const BaseCrudController = createCrudController({
113
- create: { dto: CreateUserDto },
114
- update: { dto: UpdateUserDto },
115
- });
116
-
117
- @Controller('users')
118
- export class UserController extends BaseCrudController {
119
- constructor(protected readonly service: UserService) {
120
- super(service);
121
- }
122
203
  }
123
204
  ```
124
205
 
@@ -144,39 +225,202 @@ export class PostModule {}
144
225
 
145
226
  ---
146
227
 
147
- ## 🔍 Query Features
228
+ ## 🔍 Querying
229
+
230
+ The `APIFeatures` class provides powerful querying capabilities for your CRUD APIs, allowing you to filter, sort, search, paginate, and populate your data efficiently. Below, each feature is explained in detail with practical examples using our Post model.
231
+
232
+ ### Filtering
233
+
234
+ Filtering allows you to retrieve documents that match specific criteria. There are two types: basic filtering for exact matches and advanced filtering for range queries.
235
+
236
+ #### Basic Filtering
237
+
238
+ For fields that accept multiple values (like enums, arrays, or booleans), use comma-separated values. This uses MongoDB's `$in` operator to match any of the provided values.
148
239
 
149
- `BaseCrudService` uses an internal `APIFeatures` helper to interpret
150
- standard REST query parameters. All of the following work out of the
151
- box when you call `service.findAll(query)` or hit a controller
152
- event:
240
+ **Explanation:** This is useful for filtering by categories, statuses, tags, or any field where you want to include multiple options. The query parameter value is split by commas and converted to an `$in` array.
153
241
 
154
- | Parameter | Description | Example |
155
- | ------------------------------ | ----------------------------------------------- | ----------------------- | --- |
156
- | `?field=value` | Exact match (supports comma‑separated values) | `?status=active,paused` |
157
- | `?price[gte]=10&price[lte]=50` | Comparison operators (`gte`, `gt`, `lte`, `lt`) | |
158
- | `?sort=createdAt,-title` | Sort by one or more fields | |
159
- | `?fields=name,email` | Project specific fields | |
160
- | `?page=2&limit=20` | Pagination | |
161
- | `?search=term:field1,field2` | Case‑insensitive regex search | |
162
- | `?populate=author:email | comments:body` | Populate mongoose refs | |
242
+ **Example:** Get posts that are either published or archived.
163
243
 
164
- > ℹ️ The `filter()` stage strips control fields (`page`, `sort`,
165
- > `limit`, `fields`, `search`, `populate`) before building a mongoose
166
- > filter object.
244
+ ```http
245
+ GET /posts?status=published,archived
246
+ ```
247
+
248
+ This translates to MongoDB query: `{ status: { $in: ['published', 'archived'] } }`
249
+
250
+ **Example:** Get posts with specific tags.
251
+
252
+ ```http
253
+ GET /posts?tags=javascript,react,nestjs
254
+ ```
255
+
256
+ **Example:** Get featured and pinned posts.
257
+
258
+ ```http
259
+ GET /posts?isFeatured=true&isPinned=true
260
+ ```
261
+
262
+ In our Post model, you can filter by:
263
+
264
+ - **Enums:** `status` (draft, published, archived, deleted), `visibility` (public, private, unlisted)
265
+ - **Arrays:** `categories`, `tags`, `keywords`
266
+ - **Booleans:** `isFeatured`, `isPinned`, `allowComments`, `allowSharing`
267
+ - **Relationships:** `author` (user ID)
268
+
269
+ #### Advanced Filtering
270
+
271
+ For range queries and comparisons, use bracket notation with MongoDB comparison operators:
272
+
273
+ - `[gte]` - greater than or equal (`$gte`)
274
+ - `[gt]` - greater than (`$gt`)
275
+ - `[lte]` - less than or equal (`$lte`)
276
+ - `[lt]` - less than (`$lt`)
277
+
278
+ **Explanation:** These operators allow precise range filtering on numeric or date fields. The bracket notation `[operator]` is parsed to extract the field name and apply the corresponding MongoDB operator.
279
+
280
+ **Example:** Get posts with high engagement (more than 100 views and 10 likes).
281
+
282
+ ```http
283
+ GET /posts?viewCount[gte]=100&likeCount[gte]=10
284
+ ```
285
+
286
+ **Example:** Get posts published between January 1, 2024 and December 31, 2024.
287
+
288
+ ```http
289
+ GET /posts?publishedAt[gte]=2024-01-01&publishedAt[lte]=2024-12-31
290
+ ```
291
+
292
+ **Example:** Get posts with reading time between 5-15 minutes.
293
+
294
+ ```http
295
+ GET /posts?readingTime[gte]=5&readingTime[lte]=15
296
+ ```
297
+
298
+ Note: Date fields should be in ISO format (YYYY-MM-DDTHH:mm:ss.sssZ). Our Post model has `publishedAt` for publication dates and automatic `createdAt`/`updatedAt` timestamps.
299
+
300
+ You can combine multiple operators on the same field or different fields:
301
+
302
+ ```http
303
+ GET /posts?viewCount[gte]=50&commentCount[lte]=5&readingTime[gte]=3&readingTime[lte]=10
304
+ ```
305
+
306
+ ### Sorting
307
+
308
+ Sort your results by one or more fields to control the order of returned documents.
167
309
 
168
- ### Examples
310
+ **Explanation:** Separate multiple fields with commas. Prefix a field with `-` for descending order. If no sort is specified, results default to `-createdAt` (newest first). This uses MongoDB's `sort()` method.
311
+
312
+ **Example:** Sort posts by view count descending.
313
+
314
+ ```http
315
+ GET /posts?sort=-viewCount
316
+ ```
317
+
318
+ **Example:** Sort by engagement metrics in ascending order.
169
319
 
170
320
  ```http
171
- GET /posts?author=John&status[ne]=draft&sort=-createdAt&page=1&limit=10
321
+ GET /posts?sort=commentCount
172
322
  ```
173
323
 
324
+ For our Post model, you can sort by any field including: `title`, `status`, `visibility`, `publishedAt`, `viewCount`, `likeCount`, `commentCount`, `readingTime`, `isFeatured`, `isPinned`, `createdAt`, `updatedAt`, and more.
325
+
326
+ ### Limiting Fields
327
+
328
+ Control which fields are included or excluded in the response to optimize payload size and hide sensitive data.
329
+
330
+ **Explanation:** Use a comma-separated list of field names. By default, the `__v` field (Mongoose version key) is excluded. Prefix fields with `-` to exclude them instead of including only them. This uses MongoDB's `select()` method.
331
+
332
+ **Example:** Only return essential fields for a list view.
333
+
174
334
  ```http
175
- GET /posts?search=nestjs:title,content
335
+ GET /posts?fields=title,excerpt,viewCount,likeCount,publishedAt,author
176
336
  ```
177
337
 
338
+ **Example:** Return all fields except content and metadata for performance.
339
+
178
340
  ```http
179
- GET /posts?populate=author:name,email
341
+ GET /posts?fields=-content,-metadata,-__v
342
+ ```
343
+
344
+ **Example:** Get only SEO-related fields.
345
+
346
+ ```http
347
+ GET /posts?fields=slug,metaTitle,metaDescription,coverImage
348
+ ```
349
+
350
+ ### Pagination
351
+
352
+ Split large result sets into manageable pages for better performance and user experience.
353
+
354
+ **Explanation:** Use `page` (default: 1) and `limit` (default: 10) parameters. The API calculates the skip value as `(page - 1) * limit`. The response includes pagination metadata like total count, current page, total pages, and next/previous page numbers.
355
+
356
+ **Example:** Get the second page with 20 posts per page.
357
+
358
+ ```http
359
+ GET /posts?page=2&limit=20
360
+ ```
361
+
362
+ This skips the first 20 documents and returns documents 21-40.
363
+
364
+ **Example:** Get featured posts with pagination.
365
+
366
+ ```http
367
+ GET /posts?isFeatured=true&page=1&limit=5
368
+ ```
369
+
370
+ ### Searching
371
+
372
+ Perform case-insensitive text searches across multiple fields using regex.
373
+
374
+ **Explanation:** The format is `?search=searchTerm:field1,field2,field3`. The search term is applied as a regex pattern to each specified field, combined with MongoDB's `$or` operator. This is efficient when fields have text indexes.
375
+
376
+ **Example:** Search for "javascript" in the title or content fields.
377
+
378
+ ```http
379
+ GET /posts?search=javascript:title,content
380
+ ```
381
+
382
+ **Example:** Search across title, content, and keywords.
383
+
384
+ ```http
385
+ GET /posts?search=react:title,content,keywords
386
+ ```
387
+
388
+ **Example:** Search in excerpt and meta description for SEO content.
389
+
390
+ ```http
391
+ GET /posts?search=seo:excerpt,metaDescription
392
+ ```
393
+
394
+ This creates: `{ $or: [{ title: { $regex: 'javascript', $options: 'i' } }, { content: { $regex: 'javascript', $options: 'i' } }] }`
395
+
396
+ In our Post model, `title` and `content` have text indexes, making searches fast. You can also search in `excerpt`, `metaTitle`, `metaDescription`, or array fields like `keywords`, `categories`, `tags`.
397
+
398
+ ### Population
399
+
400
+ Populate referenced documents to include related data in your response, avoiding multiple queries.
401
+
402
+ **Explanation:** Specify the reference path and optionally which fields to select from the populated document. This reduces payload size by only including necessary fields. Use `|` to separate multiple population paths. Population occurs after filtering, sorting, etc., for optimal performance.
403
+
404
+ **Format:** `?populate=path:field1,field2,field3`
405
+
406
+ **Example:** Populate the author field, but only include firstName, lastName, and email from the User model.
407
+
408
+ ```http
409
+ GET /posts?populate=author:firstName,lastName,email
410
+ ```
411
+
412
+ **Example:** Get author details and role for permission checks.
413
+
414
+ ```http
415
+ GET /posts?populate=author:firstName,lastName,email,role,status
416
+ ```
417
+
418
+ In our Post model, `author` references the User model. Without field selection, all User fields would be included; with selection, only the specified fields are returned, improving performance and security. You can also populate deeply to include nested relationships.
419
+
420
+ **Example:** Combine with other queries - get published posts by active users.
421
+
422
+ ```http
423
+ GET /posts?status=published&populate=author:status&author.status=active
180
424
  ```
181
425
 
182
426
  ---
@@ -192,10 +436,6 @@ interface EndpointConfig {
192
436
  dto?: DtoClass; // class used by ValidationPipe
193
437
  guards?: any[];
194
438
  interceptors?: any[];
195
- pipes?: any[];
196
- status?: number; // HTTP status code
197
- enabled?: boolean; // turn off an endpoint
198
- validationOptions?: ValidationPipeOptions;
199
439
  }
200
440
 
201
441
  interface CrudControllerConfig {
@@ -204,11 +444,6 @@ interface CrudControllerConfig {
204
444
  delete?: EndpointConfig;
205
445
  getAll?: EndpointConfig;
206
446
  getOne?: EndpointConfig;
207
- global?: {
208
- guards?: any[];
209
- interceptors?: any[];
210
- pipes?: any[];
211
- };
212
447
  }
213
448
  ```
214
449
 
@@ -216,38 +451,120 @@ interface CrudControllerConfig {
216
451
 
217
452
  ```ts
218
453
  const BaseController = createCrudController({
219
- global: {
220
- guards: [AuthGuard],
221
- interceptors: [LoggingInterceptor],
222
- },
223
454
  getAll: {
224
- guards: [AdminGuard],
225
- interceptors: [CacheInterceptor],
455
+ guards: [AdminGuard, SomeOtherGuard, ...],
456
+ interceptors: [CacheInterceptor, SomeOtherInterceptor, ...],
226
457
  },
227
- create: { dto: CreatePostDto, status: 201 },
458
+ create: { dto: CreatePostDto },
228
459
  });
229
460
  ```
230
461
 
231
- #### Disable an endpoint entirely
462
+ #### Override validation options
232
463
 
233
464
  ```ts
234
465
  const BaseController = createCrudController({
235
- delete: { enabled: false },
466
+ create: {
467
+ dto: CreateDto,
468
+ },
236
469
  });
237
470
  ```
238
471
 
239
- #### Override validation options
472
+ ---
473
+
474
+ ## Override example
475
+
476
+ The following shows a simple way to override a generated endpoint by
477
+ providing a custom service method and a controller handler. You can
478
+ either override a handler via the `createCrudController` options
479
+ (`handler`), or replace the route entirely by extending the base
480
+ controller — this example demonstrates a common pattern: custom service
481
+ logic plus an explicit controller method that calls it.
240
482
 
241
483
  ```ts
242
- const BaseController = createCrudController({
484
+ // src/post/post.service.ts
485
+ import { Injectable } from '@nestjs/common';
486
+ import { InjectModel } from '@nestjs/mongoose';
487
+ import { Model } from 'mongoose';
488
+ import { Post, PostDocument } from './schemas/post.schema';
489
+ import { CreatePostUpdated } from './dto/create-post-update.dto';
490
+
491
+ import { BaseCrudService } from 'nest-mongoose-crud'; // Adjust path as needed
492
+
493
+ @Injectable()
494
+ export class PostService extends BaseCrudService<PostDocument> {
495
+ constructor(@InjectModel(Post.name) postModel: Model<PostDocument>) {
496
+ super(postModel);
497
+ }
498
+
499
+ create(updatePostDto: CreatePostUpdated) {
500
+ return 'create one updated!!';
501
+ }
502
+ }
503
+ ```
504
+
505
+ ```ts
506
+ // src/post/post.controller.ts
507
+ import {
508
+ Body,
509
+ Controller,
510
+ Post,
511
+ Type,
512
+ UsePipes,
513
+ ValidationPipe,
514
+ } from '@nestjs/common';
515
+
516
+ import { createCrudController } from 'nest-mongoose-crud'; // Adjust path as needed
517
+ import { PostService } from './post.service';
518
+ import { CreatePostDto } from './dto/create-post.dto';
519
+ import { UpdatePostDto } from './dto/update-post.dto';
520
+ import { LogRequest1Interceptor } from './interceptors/log-request-1/log-request-1.interceptor';
521
+ import { LogRequest2Interceptor } from './interceptors/log-request-2/log-request-2.interceptor';
522
+ import { LogRequest1Guard } from './guards/log-request-1/log-request-1.guard';
523
+ import { CreatePostUpdated } from './dto/create-post-update.dto';
524
+ import { LogRequest2Guard } from './guards/log-request-1/log-request-2.guard';
525
+
526
+ const BaseController: Type<any> = createCrudController({
243
527
  create: {
244
- dto: CreateDto,
245
- validationOptions: { whitelist: false, transform: false },
528
+ dto: CreatePostDto,
529
+ interceptors: [LogRequest1Interceptor, LogRequest2Interceptor],
530
+ },
531
+
532
+ update: {
533
+ dto: UpdatePostDto,
534
+ },
535
+
536
+ getAll: {
537
+ guards: [LogRequest1Guard, LogRequest2Guard],
538
+ interceptors: [LogRequest1Interceptor, LogRequest2Interceptor],
246
539
  },
247
540
  });
541
+
542
+ @Controller('posts')
543
+ export class PostController extends BaseController {
544
+ constructor(private service: PostService) {
545
+ super(service);
546
+ }
547
+
548
+ @Post()
549
+ @UsePipes(
550
+ new ValidationPipe({
551
+ transform: true,
552
+ whitelist: true,
553
+ forbidNonWhitelisted: true,
554
+ }),
555
+ )
556
+ create(@Body() dto: CreatePostUpdated) {
557
+ return this.service.create(dto);
558
+ }
559
+ }
248
560
  ```
249
561
 
250
- ---
562
+ This snippet demonstrates:
563
+
564
+ - overriding service behaviour by extending `BaseCrudService`;
565
+ - exposing a custom controller route that delegates to the service;
566
+ - mixing generated options (via `createCrudController`) with explicit
567
+ controller methods when you need full control.
251
568
 
252
569
  ## 📦 Additional Utilities
253
570
 
@@ -1 +1 @@
1
- {"version":3,"file":"create-crud.controller.utils.d.ts","sourceRoot":"","sources":["../../src/utils/create-crud.controller.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,IAAI,EAQJ,UAAU,EAIX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIpC,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE;QAClB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QACf,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;QACrB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;KACf,CAAC;CACH;AA2BD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,QAAQ,EACrD,MAAM,GAAE,oBAAyB,GAChC,IAAI,CAAC,GAAG,CAAC,CA+EX"}
1
+ {"version":3,"file":"create-crud.controller.utils.d.ts","sourceRoot":"","sources":["../../src/utils/create-crud.controller.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,IAAI,EAQJ,UAAU,EAIX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIpC,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE;QAClB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QACf,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;QACrB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;KACf,CAAC;CACH;AA2BD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,QAAQ,EACrD,MAAM,GAAE,oBAAyB,GAChC,IAAI,CAAC,GAAG,CAAC,CAgFX"}
@@ -73,6 +73,7 @@ function createCrudController(config = {}) {
73
73
  ], BaseController.prototype, "findAll", null);
74
74
  __decorate([
75
75
  (0, common_1.Get)(':id'),
76
+ applyEndpointDecorators(config.getOne),
76
77
  __param(0, (0, common_1.Param)('id')),
77
78
  __param(1, (0, common_1.Query)()),
78
79
  __metadata("design:type", Function),
@@ -1 +1 @@
1
- {"version":3,"file":"create-crud.controller.utils.js","sourceRoot":"","sources":["../../src/utils/create-crud.controller.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AA2EA,oDAiFC;AA5JD,2CAiBwB;AAiCxB,SAAS,uBAAuB,CAAC,MAAuB;IACtD,MAAM,UAAU,GAAU,EAAE,CAAC;IAE7B,IAAI,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QACjC,UAAU,CAAC,IAAI,CAAC,IAAA,wBAAe,EAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC1B,UAAU,CAAC,IAAI,CAAC,IAAA,iBAAQ,EAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,sFAAsF;IACtF,8EAA8E;IAE9E,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,IAAA,iBAAQ,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,wBAAe,EAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAgB,oBAAoB,CAClC,SAA+B,EAAE;IAEjC,MAAe,cAAc;QAC3B,YAA+B,OAA2B;YAA3B,YAAO,GAAP,OAAO,CAAoB;QAAG,CAAC;QAIxD,AAAN,KAAK,CAAC,OAAO,CAAU,KAAa;YAClC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAGK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU,EAAW,KAAa;YAC1D,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;gBACxB,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAIK,AAAN,KAAK,CAAC,MAAM,CASV,OAAY;YAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;QAIK,AAAN,KAAK,CAAC,MAAM,CACG,EAAU,EASvB,OAAY;YAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAIK,AAAN,KAAK,CAAC,KAAK,CACI,EAAU,EASvB,OAAY;YAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAIK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU;YAClC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC;KACF;IAtEO;QAFL,IAAA,YAAG,GAAE;QACL,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QACxB,WAAA,IAAA,cAAK,GAAE,CAAA;;;;iDAErB;IAGK;QADL,IAAA,YAAG,EAAC,KAAK,CAAC;QACG,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;QAAc,WAAA,IAAA,cAAK,GAAE,CAAA;;;;gDAQ7C;IAIK;QAFL,IAAA,aAAI,GAAE;QACN,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QAEpC,WAAA,IAAA,aAAI,EACH,IAAI,uBAAc,CAAC;YACjB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,oBAAoB,EAAE,IAAI;YAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG;SACjC,CAAC,CACH,CAAA;;;;gDAIF;IAIK;QAFL,IAAA,YAAG,EAAC,KAAK,CAAC;QACV,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QAEpC,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;QACX,WAAA,IAAA,aAAI,EACH,IAAI,uBAAc,CAAC;YACjB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,oBAAoB,EAAE,IAAI;YAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG;SACjC,CAAC,CACH,CAAA;;;;gDAIF;IAIK;QAFL,IAAA,cAAK,EAAC,KAAK,CAAC;QACZ,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QAEpC,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;QACX,WAAA,IAAA,aAAI,EACH,IAAI,uBAAc,CAAC;YACjB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,oBAAoB,EAAE,IAAI;YAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG;SACjC,CAAC,CACH,CAAA;;;;+CAIF;IAIK;QAFL,IAAA,eAAM,EAAC,KAAK,CAAC;QACb,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QACzB,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;;;;gDAExB;IAGH,OAAO,cAA2B,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"create-crud.controller.utils.js","sourceRoot":"","sources":["../../src/utils/create-crud.controller.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AA2EA,oDAkFC;AA7JD,2CAiBwB;AAiCxB,SAAS,uBAAuB,CAAC,MAAuB;IACtD,MAAM,UAAU,GAAU,EAAE,CAAC;IAE7B,IAAI,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QACjC,UAAU,CAAC,IAAI,CAAC,IAAA,wBAAe,EAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC1B,UAAU,CAAC,IAAI,CAAC,IAAA,iBAAQ,EAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,sFAAsF;IACtF,8EAA8E;IAE9E,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,IAAA,iBAAQ,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,wBAAe,EAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAgB,oBAAoB,CAClC,SAA+B,EAAE;IAEjC,MAAe,cAAc;QAC3B,YAA+B,OAA2B;YAA3B,YAAO,GAAP,OAAO,CAAoB;QAAG,CAAC;QAIxD,AAAN,KAAK,CAAC,OAAO,CAAU,KAAa;YAClC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAIK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU,EAAW,KAAa;YAC1D,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;gBACxB,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAIK,AAAN,KAAK,CAAC,MAAM,CASV,OAAY;YAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;QAIK,AAAN,KAAK,CAAC,MAAM,CACG,EAAU,EASvB,OAAY;YAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAIK,AAAN,KAAK,CAAC,KAAK,CACI,EAAU,EASvB,OAAY;YAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAIK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU;YAClC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC;KACF;IAvEO;QAFL,IAAA,YAAG,GAAE;QACL,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QACxB,WAAA,IAAA,cAAK,GAAE,CAAA;;;;iDAErB;IAIK;QAFL,IAAA,YAAG,EAAC,KAAK,CAAC;QACV,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QACzB,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;QAAc,WAAA,IAAA,cAAK,GAAE,CAAA;;;;gDAQ7C;IAIK;QAFL,IAAA,aAAI,GAAE;QACN,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QAEpC,WAAA,IAAA,aAAI,EACH,IAAI,uBAAc,CAAC;YACjB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,oBAAoB,EAAE,IAAI;YAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG;SACjC,CAAC,CACH,CAAA;;;;gDAIF;IAIK;QAFL,IAAA,YAAG,EAAC,KAAK,CAAC;QACV,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QAEpC,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;QACX,WAAA,IAAA,aAAI,EACH,IAAI,uBAAc,CAAC;YACjB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,oBAAoB,EAAE,IAAI;YAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG;SACjC,CAAC,CACH,CAAA;;;;gDAIF;IAIK;QAFL,IAAA,cAAK,EAAC,KAAK,CAAC;QACZ,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QAEpC,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;QACX,WAAA,IAAA,aAAI,EACH,IAAI,uBAAc,CAAC;YACjB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,oBAAoB,EAAE,IAAI;YAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG;SACjC,CAAC,CACH,CAAA;;;;+CAIF;IAIK;QAFL,IAAA,eAAM,EAAC,KAAK,CAAC;QACb,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC;QACzB,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;;;;gDAExB;IAGH,OAAO,cAA2B,CAAC;AACrC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nest-mongoose-crud",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A reusable handler factory utility for NestJS and Mongoose projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",