@elsikora/nestjs-crud-automator 1.7.0 → 1.8.0-dev.1
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 +272 -226
- package/dist/cjs/class/api/service-base.class.d.ts +7 -6
- package/dist/cjs/class/api/service-base.class.js +7 -6
- package/dist/cjs/class/api/service-base.class.js.map +1 -1
- package/dist/cjs/class/metadata-storage.class.js +2 -0
- package/dist/cjs/class/metadata-storage.class.js.map +1 -1
- package/dist/cjs/class/utility/dto/strategy/request.class.js +1 -0
- package/dist/cjs/class/utility/dto/strategy/request.class.js.map +1 -1
- package/dist/cjs/constant/number.constant.js +1 -0
- package/dist/cjs/constant/number.constant.js.map +1 -1
- package/dist/cjs/decorator/api/controller.decorator.js +2 -0
- package/dist/cjs/decorator/api/controller.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/function/create.decorator.js +8 -3
- package/dist/cjs/decorator/api/function/create.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/function/decorator.js +2 -0
- package/dist/cjs/decorator/api/function/decorator.js.map +1 -1
- package/dist/cjs/decorator/api/function/delete.decorator.js +8 -3
- package/dist/cjs/decorator/api/function/delete.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/function/get-list.decorator.js +16 -4
- package/dist/cjs/decorator/api/function/get-list.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/function/get-many.decorator.js +12 -4
- package/dist/cjs/decorator/api/function/get-many.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/function/get.decorator.js +12 -4
- package/dist/cjs/decorator/api/function/get.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/function/update.decorator.js +9 -4
- package/dist/cjs/decorator/api/function/update.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/method.decorator.js +2 -0
- package/dist/cjs/decorator/api/method.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/property/boolean.decorator.js +2 -0
- package/dist/cjs/decorator/api/property/boolean.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/property/date.decorator.js +2 -0
- package/dist/cjs/decorator/api/property/date.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/property/enum.decorator.js +2 -0
- package/dist/cjs/decorator/api/property/enum.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/property/number.decorator.js +4 -0
- package/dist/cjs/decorator/api/property/number.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/property/object.decorator.js +2 -0
- package/dist/cjs/decorator/api/property/object.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/property/string.decorator.js +21 -3
- package/dist/cjs/decorator/api/property/string.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/property/uuid.decorator.js +2 -0
- package/dist/cjs/decorator/api/property/uuid.decorator.js.map +1 -1
- package/dist/cjs/decorator/api/service.decorator.js +55 -12
- package/dist/cjs/decorator/api/service.decorator.js.map +1 -1
- package/dist/cjs/factory/api/controller.factory.js +13 -0
- package/dist/cjs/factory/api/controller.factory.js.map +1 -1
- package/dist/cjs/interface/decorator/api/function/create-executor-properties.interface.d.ts +2 -1
- package/dist/cjs/interface/decorator/api/function/delete-executor-properties.interface.d.ts +3 -2
- package/dist/cjs/interface/decorator/api/function/get-executor-properties.interface.d.ts +2 -1
- package/dist/cjs/interface/decorator/api/function/get-list-executor-properties.interface.d.ts +2 -1
- package/dist/cjs/interface/decorator/api/function/get-many-executor-properties.interface.d.ts +2 -1
- package/dist/cjs/interface/decorator/api/function/update-executor-properties.interface.d.ts +3 -2
- package/dist/cjs/utility/api/controller/get-list/transform-filter.utility.js +5 -0
- package/dist/cjs/utility/api/controller/get-list/transform-filter.utility.js.map +1 -1
- package/dist/cjs/utility/api/controller/get-list/transform-operation.utility.js +2 -0
- package/dist/cjs/utility/api/controller/get-list/transform-operation.utility.js.map +1 -1
- package/dist/cjs/utility/api/controller/handle-request-relations.utility.js +2 -0
- package/dist/cjs/utility/api/controller/handle-request-relations.utility.js.map +1 -1
- package/dist/cjs/utility/api/controller/write-dto-swagger.utility.js +3 -0
- package/dist/cjs/utility/api/controller/write-dto-swagger.utility.js.map +1 -1
- package/dist/cjs/utility/api/filter-order-by-from-entity.utility.js +2 -0
- package/dist/cjs/utility/api/filter-order-by-from-entity.utility.js.map +1 -1
- package/dist/cjs/utility/dto/build-decorator.utility.js +1 -0
- package/dist/cjs/utility/dto/build-decorator.utility.js.map +1 -1
- package/dist/cjs/utility/dto/generate-filter-decorator.utility.js +2 -0
- package/dist/cjs/utility/dto/generate-filter-decorator.utility.js.map +1 -1
- package/dist/cjs/utility/dto/generate.utility.js +17 -0
- package/dist/cjs/utility/dto/generate.utility.js.map +1 -1
- package/dist/cjs/utility/dto/get-decorator-config.utility.js +1 -0
- package/dist/cjs/utility/dto/get-decorator-config.utility.js.map +1 -1
- package/dist/cjs/utility/dto/validate-property-config.utility.js +1 -0
- package/dist/cjs/utility/dto/validate-property-config.utility.js.map +1 -1
- package/dist/cjs/utility/generate-entity-information.utility.js +5 -0
- package/dist/cjs/utility/generate-entity-information.utility.js.map +1 -1
- package/dist/cjs/utility/get-entity-columns.utility.js +1 -0
- package/dist/cjs/utility/get-entity-columns.utility.js.map +1 -1
- package/dist/cjs/utility/is-error-of-type.utility.js +2 -0
- package/dist/cjs/utility/is-error-of-type.utility.js.map +1 -1
- package/dist/cjs/utility/logger.utility.d.ts +9 -0
- package/dist/cjs/utility/logger.utility.js +11 -0
- package/dist/cjs/utility/logger.utility.js.map +1 -1
- package/dist/cjs/validator/all-or-none-of-listed-properties.validator.js +1 -0
- package/dist/cjs/validator/all-or-none-of-listed-properties.validator.js.map +1 -1
- package/dist/cjs/validator/has-at-least-one-and-only-one-of-listed-properties.validator.js +1 -0
- package/dist/cjs/validator/has-at-least-one-and-only-one-of-listed-properties.validator.js.map +1 -1
- package/dist/cjs/validator/has-at-least-one-of-listed-properties.validator.js +1 -0
- package/dist/cjs/validator/has-at-least-one-of-listed-properties.validator.js.map +1 -1
- package/dist/cjs/validator/has-at-least-one-property.validator.js +1 -0
- package/dist/cjs/validator/has-at-least-one-property.validator.js.map +1 -1
- package/dist/cjs/validator/has-paired-custom-suffixes-fields.validator.js +6 -0
- package/dist/cjs/validator/has-paired-custom-suffixes-fields.validator.js.map +1 -1
- package/dist/cjs/validator/only-one-of-listed-properties.validator.js +1 -0
- package/dist/cjs/validator/only-one-of-listed-properties.validator.js.map +1 -1
- package/dist/esm/class/api/service-base.class.d.ts +7 -6
- package/dist/esm/interface/decorator/api/function/create-executor-properties.interface.d.ts +2 -1
- package/dist/esm/interface/decorator/api/function/delete-executor-properties.interface.d.ts +3 -2
- package/dist/esm/interface/decorator/api/function/get-executor-properties.interface.d.ts +2 -1
- package/dist/esm/interface/decorator/api/function/get-list-executor-properties.interface.d.ts +2 -1
- package/dist/esm/interface/decorator/api/function/get-many-executor-properties.interface.d.ts +2 -1
- package/dist/esm/interface/decorator/api/function/update-executor-properties.interface.d.ts +3 -2
- package/dist/esm/src/class/api/service-base.class.js +7 -6
- package/dist/esm/src/class/api/service-base.class.js.map +1 -1
- package/dist/esm/src/class/metadata-storage.class.js +2 -0
- package/dist/esm/src/class/metadata-storage.class.js.map +1 -1
- package/dist/esm/src/class/utility/dto/strategy/request.class.js +1 -0
- package/dist/esm/src/class/utility/dto/strategy/request.class.js.map +1 -1
- package/dist/esm/src/constant/number.constant.js +1 -0
- package/dist/esm/src/constant/number.constant.js.map +1 -1
- package/dist/esm/src/decorator/api/controller.decorator.js +2 -0
- package/dist/esm/src/decorator/api/controller.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/function/create.decorator.js +8 -3
- package/dist/esm/src/decorator/api/function/create.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/function/decorator.js +2 -0
- package/dist/esm/src/decorator/api/function/decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/function/delete.decorator.js +8 -3
- package/dist/esm/src/decorator/api/function/delete.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/function/get-list.decorator.js +16 -4
- package/dist/esm/src/decorator/api/function/get-list.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/function/get-many.decorator.js +12 -4
- package/dist/esm/src/decorator/api/function/get-many.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/function/get.decorator.js +12 -4
- package/dist/esm/src/decorator/api/function/get.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/function/update.decorator.js +9 -4
- package/dist/esm/src/decorator/api/function/update.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/method.decorator.js +2 -0
- package/dist/esm/src/decorator/api/method.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/property/boolean.decorator.js +2 -0
- package/dist/esm/src/decorator/api/property/boolean.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/property/date.decorator.js +2 -0
- package/dist/esm/src/decorator/api/property/date.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/property/enum.decorator.js +2 -0
- package/dist/esm/src/decorator/api/property/enum.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/property/number.decorator.js +4 -0
- package/dist/esm/src/decorator/api/property/number.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/property/object.decorator.js +2 -0
- package/dist/esm/src/decorator/api/property/object.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/property/string.decorator.js +21 -3
- package/dist/esm/src/decorator/api/property/string.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/property/uuid.decorator.js +2 -0
- package/dist/esm/src/decorator/api/property/uuid.decorator.js.map +1 -1
- package/dist/esm/src/decorator/api/service.decorator.js +55 -12
- package/dist/esm/src/decorator/api/service.decorator.js.map +1 -1
- package/dist/esm/src/factory/api/controller.factory.js +13 -0
- package/dist/esm/src/factory/api/controller.factory.js.map +1 -1
- package/dist/esm/src/utility/api/controller/get-list/transform-filter.utility.js +5 -0
- package/dist/esm/src/utility/api/controller/get-list/transform-filter.utility.js.map +1 -1
- package/dist/esm/src/utility/api/controller/get-list/transform-operation.utility.js +2 -0
- package/dist/esm/src/utility/api/controller/get-list/transform-operation.utility.js.map +1 -1
- package/dist/esm/src/utility/api/controller/handle-request-relations.utility.js +2 -0
- package/dist/esm/src/utility/api/controller/handle-request-relations.utility.js.map +1 -1
- package/dist/esm/src/utility/api/controller/write-dto-swagger.utility.js +3 -0
- package/dist/esm/src/utility/api/controller/write-dto-swagger.utility.js.map +1 -1
- package/dist/esm/src/utility/api/filter-order-by-from-entity.utility.js +2 -0
- package/dist/esm/src/utility/api/filter-order-by-from-entity.utility.js.map +1 -1
- package/dist/esm/src/utility/dto/build-decorator.utility.js +1 -0
- package/dist/esm/src/utility/dto/build-decorator.utility.js.map +1 -1
- package/dist/esm/src/utility/dto/generate-filter-decorator.utility.js +2 -0
- package/dist/esm/src/utility/dto/generate-filter-decorator.utility.js.map +1 -1
- package/dist/esm/src/utility/dto/generate.utility.js +17 -0
- package/dist/esm/src/utility/dto/generate.utility.js.map +1 -1
- package/dist/esm/src/utility/dto/get-decorator-config.utility.js +1 -0
- package/dist/esm/src/utility/dto/get-decorator-config.utility.js.map +1 -1
- package/dist/esm/src/utility/dto/validate-property-config.utility.js +1 -0
- package/dist/esm/src/utility/dto/validate-property-config.utility.js.map +1 -1
- package/dist/esm/src/utility/generate-entity-information.utility.js +5 -0
- package/dist/esm/src/utility/generate-entity-information.utility.js.map +1 -1
- package/dist/esm/src/utility/get-entity-columns.utility.js +1 -0
- package/dist/esm/src/utility/get-entity-columns.utility.js.map +1 -1
- package/dist/esm/src/utility/is-error-of-type.utility.js +2 -0
- package/dist/esm/src/utility/is-error-of-type.utility.js.map +1 -1
- package/dist/esm/src/utility/logger.utility.js +11 -0
- package/dist/esm/src/utility/logger.utility.js.map +1 -1
- package/dist/esm/src/validator/all-or-none-of-listed-properties.validator.js +1 -0
- package/dist/esm/src/validator/all-or-none-of-listed-properties.validator.js.map +1 -1
- package/dist/esm/src/validator/has-at-least-one-and-only-one-of-listed-properties.validator.js +1 -0
- package/dist/esm/src/validator/has-at-least-one-and-only-one-of-listed-properties.validator.js.map +1 -1
- package/dist/esm/src/validator/has-at-least-one-of-listed-properties.validator.js +1 -0
- package/dist/esm/src/validator/has-at-least-one-of-listed-properties.validator.js.map +1 -1
- package/dist/esm/src/validator/has-at-least-one-property.validator.js +1 -0
- package/dist/esm/src/validator/has-at-least-one-property.validator.js.map +1 -1
- package/dist/esm/src/validator/has-paired-custom-suffixes-fields.validator.js +6 -0
- package/dist/esm/src/validator/has-paired-custom-suffixes-fields.validator.js.map +1 -1
- package/dist/esm/src/validator/only-one-of-listed-properties.validator.js +1 -0
- package/dist/esm/src/validator/only-one-of-listed-properties.validator.js.map +1 -1
- package/dist/esm/utility/logger.utility.d.ts +9 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
|
|
3
|
-
</p>
|
|
2
|
+
<img src="https://6jft62zmy9nx2oea.public.blob.vercel-storage.com/nestjs-crud-automator-HhXThTDhKyqznMLCgdmWhsPa287fIi.png" width="500" alt="project-logo">
|
|
3
|
+
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">🚀 NestJS-Crud-Automator</h1>
|
|
6
|
-
<p align="center"><em>
|
|
6
|
+
<p align="center"><em>Automate CRUD operations in NestJS with powerful decorators and type-safe APIs</em></p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
9
|
<a aria-label="ElsiKora logo" href="https://elsikora.com">
|
|
10
10
|
<img src="https://img.shields.io/badge/MADE%20BY%20ElsiKora-333333.svg?style=for-the-badge" alt="ElsiKora">
|
|
11
|
-
</a> <img src="https://img.shields.io/badge/version-blue.svg?style=for-the-badge&logo=npm&logoColor=white" alt="version"> <img src="https://img.shields.io/badge/typescript-blue.svg?style=for-the-badge&logo=typescript&logoColor=white" alt="typescript"> <img src="https://img.shields.io/badge/nestjs-red.svg?style=for-the-badge&logo=nestjs&logoColor=white" alt="nestjs"> <img src="https://img.shields.io/badge/typeorm-orange.svg?style=for-the-badge&logo=
|
|
11
|
+
</a> <img src="https://img.shields.io/badge/version-blue.svg?style=for-the-badge&logo=npm&logoColor=white" alt="version"> <img src="https://img.shields.io/badge/typescript-blue.svg?style=for-the-badge&logo=typescript&logoColor=white" alt="typescript"> <img src="https://img.shields.io/badge/nestjs-red.svg?style=for-the-badge&logo=nestjs&logoColor=white" alt="nestjs"> <img src="https://img.shields.io/badge/typeorm-orange.svg?style=for-the-badge&logo=typeorm&logoColor=white" alt="typeorm"> <img src="https://img.shields.io/badge/license-green.svg?style=for-the-badge&logo=license&logoColor=white" alt="license"> <img src="https://img.shields.io/badge/swagger-green.svg?style=for-the-badge&logo=swagger&logoColor=white" alt="swagger">
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
|
|
@@ -23,19 +23,21 @@
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
## 📖 Description
|
|
26
|
-
NestJS-Crud-Automator is a comprehensive library designed to
|
|
26
|
+
NestJS-Crud-Automator is a comprehensive library designed to streamline the development of RESTful APIs in NestJS applications. It eliminates boilerplate code by providing decorators that automatically generate controllers, services, DTOs, and validation. With strong TypeScript support, it offers type-safe CRUD operations while enforcing best practices in API design. The library integrates seamlessly with TypeORM, enhances Swagger documentation, and provides built-in validation through class-validator. It's perfect for developers looking to accelerate development without sacrificing code quality or architectural principles. Whether you're building a simple API or a complex enterprise application, NestJS-Crud-Automator helps maintain clean, consistent, and well-documented endpoints with minimal effort.
|
|
27
27
|
|
|
28
28
|
## 🚀 Features
|
|
29
|
-
- ✨ **
|
|
30
|
-
- ✨ **
|
|
31
|
-
- ✨ **
|
|
32
|
-
- ✨ **
|
|
33
|
-
- ✨ **
|
|
34
|
-
- ✨ **
|
|
35
|
-
- ✨ **
|
|
36
|
-
- ✨ **
|
|
37
|
-
- ✨ **
|
|
38
|
-
- ✨ **
|
|
29
|
+
- ✨ **Automatic CRUD operations with a single decorator**
|
|
30
|
+
- ✨ **Type-safe API development with full TypeScript support**
|
|
31
|
+
- ✨ **Seamless integration with TypeORM for database operations**
|
|
32
|
+
- ✨ **Auto-generated DTOs with comprehensive validation rules**
|
|
33
|
+
- ✨ **Complete Swagger/OpenAPI documentation generation**
|
|
34
|
+
- ✨ **Customizable request/response transformers**
|
|
35
|
+
- ✨ **Built-in relation handling and eager/lazy loading support**
|
|
36
|
+
- ✨ **Automatic validation using class-validator**
|
|
37
|
+
- ✨ **Request correlation tracking for improved debugging**
|
|
38
|
+
- ✨ **Rate limiting and throttling capabilities**
|
|
39
|
+
- ✨ **Powerful filtering, pagination, and sorting for list endpoints**
|
|
40
|
+
- ✨ **Custom validation decorators for complex business rules**
|
|
39
41
|
|
|
40
42
|
## 🛠 Installation
|
|
41
43
|
```bash
|
|
@@ -52,23 +54,39 @@ pnpm add @elsikora/nestjs-crud-automator
|
|
|
52
54
|
bun add @elsikora/nestjs-crud-automator
|
|
53
55
|
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
You'll also need to install peer dependencies if you haven't already:
|
|
56
58
|
|
|
57
59
|
|
|
58
60
|
npm install @nestjs/common @nestjs/swagger typeorm class-transformer class-validator reflect-metadata
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
Once installed, you need to set up your NestJS module to import the library:
|
|
64
|
+
|
|
65
|
+
typescript
|
|
66
|
+
// app.module.ts
|
|
67
|
+
import { Module } from '@nestjs/common';
|
|
68
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
69
|
+
// Import other modules and entities as needed
|
|
70
|
+
|
|
71
|
+
@Module({
|
|
72
|
+
imports: [
|
|
73
|
+
TypeOrmModule.forRoot({
|
|
74
|
+
// your TypeORM configuration
|
|
75
|
+
}),
|
|
76
|
+
// Register your entities and other modules
|
|
77
|
+
],
|
|
78
|
+
})
|
|
79
|
+
export class AppModule {}
|
|
59
80
|
```
|
|
60
81
|
|
|
61
82
|
## 💡 Usage
|
|
62
83
|
## Basic Usage
|
|
63
84
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
### Entity Definition
|
|
67
|
-
|
|
68
|
-
First, define your TypeORM entity with the `ApiPropertyDescribe` decorators to provide metadata for Swagger and validation:
|
|
85
|
+
Create an entity using TypeORM and enhance it with property decorators:
|
|
69
86
|
|
|
70
87
|
```typescript
|
|
71
|
-
|
|
88
|
+
// user.entity.ts
|
|
89
|
+
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
|
|
72
90
|
import { ApiPropertyDescribe } from '@elsikora/nestjs-crud-automator';
|
|
73
91
|
import { EApiPropertyDescribeType, EApiPropertyStringType } from '@elsikora/nestjs-crud-automator';
|
|
74
92
|
|
|
@@ -77,7 +95,7 @@ export class User {
|
|
|
77
95
|
@PrimaryGeneratedColumn('uuid')
|
|
78
96
|
@ApiPropertyDescribe({
|
|
79
97
|
type: EApiPropertyDescribeType.UUID,
|
|
80
|
-
description: 'Unique identifier'
|
|
98
|
+
description: 'Unique identifier',
|
|
81
99
|
})
|
|
82
100
|
id: string;
|
|
83
101
|
|
|
@@ -100,18 +118,19 @@ export class User {
|
|
|
100
118
|
format: EApiPropertyStringType.EMAIL,
|
|
101
119
|
minLength: 5,
|
|
102
120
|
maxLength: 100,
|
|
103
|
-
pattern: '/^[\w-\.]+@([\w-]+\.)+[\w-]{2,}$/',
|
|
104
|
-
exampleValue: 'john@example.com'
|
|
121
|
+
pattern: '/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/',
|
|
122
|
+
exampleValue: 'john.doe@example.com'
|
|
105
123
|
})
|
|
106
124
|
email: string;
|
|
107
125
|
}
|
|
108
126
|
```
|
|
109
127
|
|
|
110
|
-
|
|
128
|
+
## Creating a Service
|
|
111
129
|
|
|
112
|
-
Create a service that extends the base
|
|
130
|
+
Create a service that extends the base service class:
|
|
113
131
|
|
|
114
132
|
```typescript
|
|
133
|
+
// user.service.ts
|
|
115
134
|
import { Injectable } from '@nestjs/common';
|
|
116
135
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
117
136
|
import { Repository } from 'typeorm';
|
|
@@ -130,50 +149,57 @@ export class UserService extends ApiServiceBase<User> {
|
|
|
130
149
|
super();
|
|
131
150
|
}
|
|
132
151
|
|
|
133
|
-
// You can
|
|
152
|
+
// You can add custom methods here
|
|
134
153
|
async findByEmail(email: string): Promise<User | undefined> {
|
|
135
|
-
return this.repository.findOne({
|
|
136
|
-
where: { email }
|
|
137
|
-
});
|
|
154
|
+
return this.repository.findOne({ where: { email } });
|
|
138
155
|
}
|
|
139
156
|
}
|
|
140
157
|
```
|
|
141
158
|
|
|
142
|
-
|
|
159
|
+
## Creating a Controller
|
|
143
160
|
|
|
144
|
-
|
|
161
|
+
Create a controller with automated CRUD operations:
|
|
145
162
|
|
|
146
163
|
```typescript
|
|
164
|
+
// user.controller.ts
|
|
147
165
|
import { Controller } from '@nestjs/common';
|
|
148
166
|
import { ApiController } from '@elsikora/nestjs-crud-automator';
|
|
149
167
|
import { User } from './user.entity';
|
|
150
168
|
import { UserService } from './user.service';
|
|
151
169
|
|
|
152
|
-
@ApiController({
|
|
170
|
+
@ApiController<User>({
|
|
153
171
|
entity: User,
|
|
154
172
|
name: 'Users',
|
|
155
173
|
path: 'users',
|
|
156
174
|
routes: {
|
|
157
|
-
// Configure routes
|
|
175
|
+
// Configure specific routes if needed
|
|
158
176
|
}
|
|
159
177
|
})
|
|
160
178
|
@Controller('users')
|
|
161
179
|
export class UserController {
|
|
162
|
-
constructor(
|
|
180
|
+
constructor(
|
|
181
|
+
public service: UserService
|
|
182
|
+
) {}
|
|
183
|
+
|
|
184
|
+
// The controller methods are automatically generated
|
|
185
|
+
// You can add custom endpoints here if needed
|
|
163
186
|
}
|
|
164
187
|
```
|
|
165
188
|
|
|
166
|
-
##
|
|
167
|
-
|
|
168
|
-
### Custom Route Configuration
|
|
189
|
+
## Custom Route Configuration
|
|
169
190
|
|
|
170
|
-
|
|
191
|
+
You can customize individual routes with advanced options:
|
|
171
192
|
|
|
172
193
|
```typescript
|
|
173
|
-
|
|
174
|
-
import {
|
|
194
|
+
// user.controller.ts with route customization
|
|
195
|
+
import { Controller } from '@nestjs/common';
|
|
196
|
+
import { ApiController } from '@elsikora/nestjs-crud-automator';
|
|
197
|
+
import { EApiRouteType, EApiControllerLoadRelationsStrategy } from '@elsikora/nestjs-crud-automator';
|
|
198
|
+
import { User } from './user.entity';
|
|
199
|
+
import { UserService } from './user.service';
|
|
200
|
+
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
|
175
201
|
|
|
176
|
-
@ApiController({
|
|
202
|
+
@ApiController<User>({
|
|
177
203
|
entity: User,
|
|
178
204
|
name: 'Users',
|
|
179
205
|
path: 'users',
|
|
@@ -181,26 +207,16 @@ import { EApiControllerLoadRelationsStrategy, EApiAuthenticationType, EApiDtoTyp
|
|
|
181
207
|
[EApiRouteType.CREATE]: {
|
|
182
208
|
authentication: {
|
|
183
209
|
guard: JwtAuthGuard,
|
|
184
|
-
type:
|
|
210
|
+
type: 'user',
|
|
185
211
|
bearerStrategies: ['jwt']
|
|
186
212
|
},
|
|
187
213
|
request: {
|
|
188
214
|
validators: [
|
|
189
|
-
|
|
190
|
-
errorType: EErrorStringAction.VALIDATION_ERROR,
|
|
191
|
-
exception: BadRequestException,
|
|
192
|
-
validationFunction: (body: Partial<User>) => {
|
|
193
|
-
return body.username && body.username.length >= 3;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
215
|
+
// custom validators
|
|
196
216
|
],
|
|
197
217
|
transformers: {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
key: 'createdAt',
|
|
201
|
-
type: EApiControllerRequestTransformerType.DYNAMIC,
|
|
202
|
-
value: TRANSFORMER_VALUE_DTO_CONSTANT.REQUEST_TIMESTAMP
|
|
203
|
-
}
|
|
218
|
+
body: [
|
|
219
|
+
// request transformers
|
|
204
220
|
]
|
|
205
221
|
}
|
|
206
222
|
}
|
|
@@ -216,221 +232,251 @@ import { EApiControllerLoadRelationsStrategy, EApiAuthenticationType, EApiDtoTyp
|
|
|
216
232
|
}
|
|
217
233
|
}
|
|
218
234
|
})
|
|
235
|
+
@Controller('users')
|
|
236
|
+
export class UserController {
|
|
237
|
+
constructor(
|
|
238
|
+
public service: UserService
|
|
239
|
+
) {}
|
|
240
|
+
}
|
|
219
241
|
```
|
|
220
242
|
|
|
221
|
-
|
|
243
|
+
## Working with DTOs
|
|
222
244
|
|
|
223
|
-
|
|
245
|
+
The library automatically generates DTOs for your entities, but you can also provide custom ones:
|
|
224
246
|
|
|
225
247
|
```typescript
|
|
226
|
-
|
|
227
|
-
import {
|
|
228
|
-
import {
|
|
248
|
+
// custom-create-user.dto.ts
|
|
249
|
+
import { ApiPropertyString, ApiPropertyUUID } from '@elsikora/nestjs-crud-automator';
|
|
250
|
+
import { EApiPropertyStringType } from '@elsikora/nestjs-crud-automator';
|
|
229
251
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
@ApiPropertyDescribe({
|
|
241
|
-
type: EApiPropertyDescribeType.STRING,
|
|
242
|
-
// configuration...
|
|
243
|
-
})
|
|
244
|
-
title: string;
|
|
245
|
-
|
|
246
|
-
@ManyToOne(() => User)
|
|
247
|
-
@ApiPropertyDescribe({
|
|
248
|
-
type: EApiPropertyDescribeType.RELATION,
|
|
249
|
-
description: 'Post author'
|
|
252
|
+
export class CustomCreateUserDto {
|
|
253
|
+
@ApiPropertyString({
|
|
254
|
+
entity: { name: 'User' },
|
|
255
|
+
description: 'User name',
|
|
256
|
+
format: EApiPropertyStringType.STRING,
|
|
257
|
+
minLength: 3,
|
|
258
|
+
maxLength: 50,
|
|
259
|
+
pattern: '/^[a-zA-Z0-9_-]+$/',
|
|
260
|
+
exampleValue: 'john_doe',
|
|
261
|
+
isRequired: true
|
|
250
262
|
})
|
|
251
|
-
|
|
252
|
-
}
|
|
263
|
+
username: string;
|
|
253
264
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
[
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
relationsToLoad: ['author'],
|
|
266
|
-
servicesLoadStrategy: EApiControllerLoadRelationsStrategy.MANUAL,
|
|
267
|
-
relationsServices: {
|
|
268
|
-
author: 'userService'
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
})
|
|
275
|
-
export class PostController {
|
|
276
|
-
constructor(
|
|
277
|
-
public service: PostService,
|
|
278
|
-
public userService: UserService
|
|
279
|
-
) {}
|
|
265
|
+
@ApiPropertyString({
|
|
266
|
+
entity: { name: 'User' },
|
|
267
|
+
description: 'User email',
|
|
268
|
+
format: EApiPropertyStringType.EMAIL,
|
|
269
|
+
minLength: 5,
|
|
270
|
+
maxLength: 100,
|
|
271
|
+
pattern: '/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/',
|
|
272
|
+
exampleValue: 'john.doe@example.com',
|
|
273
|
+
isRequired: true
|
|
274
|
+
})
|
|
275
|
+
email: string;
|
|
280
276
|
}
|
|
281
277
|
```
|
|
282
278
|
|
|
283
|
-
##
|
|
279
|
+
## Request Validation
|
|
284
280
|
|
|
285
|
-
|
|
281
|
+
You can add custom validators to your endpoints:
|
|
286
282
|
|
|
287
283
|
```typescript
|
|
288
|
-
//
|
|
289
|
-
|
|
284
|
+
// user.validator.ts
|
|
285
|
+
import { EErrorStringAction, EException } from '@elsikora/nestjs-crud-automator';
|
|
286
|
+
import { BadRequestException } from '@nestjs/common';
|
|
287
|
+
import { User } from './user.entity';
|
|
288
|
+
|
|
289
|
+
export const UniqueEmailValidator = {
|
|
290
|
+
errorType: EErrorStringAction.VALIDATION_ERROR,
|
|
291
|
+
exception: BadRequestException,
|
|
292
|
+
validationFunction: async (entity: Partial<User>, userService: any) => {
|
|
293
|
+
if (!entity.email) return true;
|
|
294
|
+
const existingUser = await userService.findByEmail(entity.email);
|
|
295
|
+
return !existingUser;
|
|
296
|
+
}
|
|
297
|
+
};
|
|
290
298
|
```
|
|
291
299
|
|
|
292
|
-
|
|
293
|
-
- `eq` - Equal
|
|
294
|
-
- `ne` - Not equal
|
|
295
|
-
- `gt` - Greater than
|
|
296
|
-
- `gte` - Greater than or equal
|
|
297
|
-
- `lt` - Less than
|
|
298
|
-
- `lte` - Less than or equal
|
|
299
|
-
- `in` - In array
|
|
300
|
-
- `notin` - Not in array
|
|
301
|
-
- `cont` - Contains (for strings)
|
|
302
|
-
- `starts` - Starts with
|
|
303
|
-
- `ends` - Ends with
|
|
304
|
-
- `isnull` - Is null
|
|
305
|
-
- `notnull` - Is not null
|
|
306
|
-
- `between` - Between two values
|
|
307
|
-
|
|
308
|
-
## Custom DTOs and Validation
|
|
309
|
-
|
|
310
|
-
You can provide custom DTOs instead of auto-generated ones:
|
|
300
|
+
## Using Filters, Pagination and Sorting
|
|
311
301
|
|
|
312
|
-
|
|
313
|
-
import { IsEmail, IsString, MinLength } from 'class-validator';
|
|
314
|
-
import { ApiProperty } from '@nestjs/swagger';
|
|
302
|
+
With the GET_LIST endpoints, you get built-in filtering, pagination and sorting:
|
|
315
303
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
@MinLength(3)
|
|
320
|
-
username: string;
|
|
321
|
-
|
|
322
|
-
@ApiProperty()
|
|
323
|
-
@IsEmail()
|
|
324
|
-
email: string;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// In controller:
|
|
328
|
-
@ApiController({
|
|
329
|
-
entity: User,
|
|
330
|
-
name: 'Users',
|
|
331
|
-
path: 'users',
|
|
332
|
-
routes: {
|
|
333
|
-
[EApiRouteType.CREATE]: {
|
|
334
|
-
dto: {
|
|
335
|
-
body: CreateUserDto,
|
|
336
|
-
response: UserResponseDto
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
})
|
|
304
|
+
```typescript
|
|
305
|
+
// Example HTTP request
|
|
306
|
+
// GET /users?limit=10&page=1&orderBy=username&orderDirection=asc&username[operator]=cont&username[value]=john
|
|
341
307
|
```
|
|
342
308
|
|
|
343
|
-
##
|
|
309
|
+
## Using the Correlation ID Interceptor
|
|
344
310
|
|
|
345
|
-
|
|
311
|
+
Add the built-in correlation ID interceptor for better request tracking:
|
|
346
312
|
|
|
347
313
|
```typescript
|
|
348
|
-
|
|
314
|
+
// main.ts
|
|
315
|
+
import { NestFactory } from '@nestjs/core';
|
|
316
|
+
import { ValidationPipe } from '@nestjs/common';
|
|
317
|
+
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
318
|
+
import { CorrelationIDResponseBodyInterceptor } from '@elsikora/nestjs-crud-automator';
|
|
319
|
+
import { AppModule } from './app.module';
|
|
349
320
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
321
|
+
async function bootstrap() {
|
|
322
|
+
const app = await NestFactory.create(AppModule);
|
|
323
|
+
|
|
324
|
+
app.useGlobalInterceptors(new CorrelationIDResponseBodyInterceptor());
|
|
325
|
+
app.useGlobalPipes(new ValidationPipe({ transform: true }));
|
|
326
|
+
|
|
327
|
+
const config = new DocumentBuilder()
|
|
328
|
+
.setTitle('My API')
|
|
329
|
+
.setDescription('API Documentation')
|
|
330
|
+
.setVersion('1.0')
|
|
331
|
+
.addBearerAuth()
|
|
332
|
+
.build();
|
|
333
|
+
|
|
334
|
+
const document = SwaggerModule.createDocument(app, config);
|
|
335
|
+
SwaggerModule.setup('api', app, document);
|
|
336
|
+
|
|
337
|
+
await app.listen(3000);
|
|
338
|
+
}
|
|
339
|
+
bootstrap();
|
|
368
340
|
```
|
|
369
341
|
|
|
370
|
-
##
|
|
342
|
+
## Custom Property Decorators
|
|
371
343
|
|
|
372
|
-
|
|
344
|
+
The library provides various property decorators for different data types:
|
|
373
345
|
|
|
374
346
|
```typescript
|
|
375
|
-
|
|
347
|
+
// Example of various property decorators
|
|
348
|
+
import {
|
|
349
|
+
ApiPropertyBoolean,
|
|
350
|
+
ApiPropertyDate,
|
|
351
|
+
ApiPropertyNumber,
|
|
352
|
+
ApiPropertyObject,
|
|
353
|
+
ApiPropertyString,
|
|
354
|
+
ApiPropertyUUID,
|
|
355
|
+
ApiPropertyEnum
|
|
356
|
+
} from '@elsikora/nestjs-crud-automator';
|
|
357
|
+
import {
|
|
358
|
+
EApiPropertyDateIdentifier,
|
|
359
|
+
EApiPropertyDateType,
|
|
360
|
+
EApiPropertyNumberType,
|
|
361
|
+
EApiPropertyStringType
|
|
362
|
+
} from '@elsikora/nestjs-crud-automator';
|
|
363
|
+
|
|
364
|
+
// Example enum
|
|
365
|
+
enum UserRole {
|
|
366
|
+
ADMIN = 'admin',
|
|
367
|
+
USER = 'user'
|
|
368
|
+
}
|
|
376
369
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
},
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
370
|
+
class ExampleDto {
|
|
371
|
+
@ApiPropertyUUID({ entity: { name: 'Example' }, isRequired: true })
|
|
372
|
+
id: string;
|
|
373
|
+
|
|
374
|
+
@ApiPropertyString({
|
|
375
|
+
entity: { name: 'Example' },
|
|
376
|
+
description: 'Example name',
|
|
377
|
+
format: EApiPropertyStringType.STRING,
|
|
378
|
+
minLength: 3,
|
|
379
|
+
maxLength: 50,
|
|
380
|
+
pattern: '/^[a-zA-Z0-9 ]+$/',
|
|
381
|
+
exampleValue: 'Example Item',
|
|
382
|
+
isRequired: true
|
|
383
|
+
})
|
|
384
|
+
name: string;
|
|
385
|
+
|
|
386
|
+
@ApiPropertyBoolean({
|
|
387
|
+
entity: { name: 'Example' },
|
|
388
|
+
description: 'Is active',
|
|
389
|
+
isRequired: false
|
|
390
|
+
})
|
|
391
|
+
isActive: boolean;
|
|
392
|
+
|
|
393
|
+
@ApiPropertyNumber({
|
|
394
|
+
entity: { name: 'Example' },
|
|
395
|
+
description: 'Price',
|
|
396
|
+
format: EApiPropertyNumberType.DOUBLE,
|
|
397
|
+
minimum: 0,
|
|
398
|
+
maximum: 1000,
|
|
399
|
+
multipleOf: 0.01,
|
|
400
|
+
exampleValue: 29.99,
|
|
401
|
+
isRequired: true
|
|
402
|
+
})
|
|
403
|
+
price: number;
|
|
404
|
+
|
|
405
|
+
@ApiPropertyDate({
|
|
406
|
+
entity: { name: 'Example' },
|
|
407
|
+
format: EApiPropertyDateType.DATE_TIME,
|
|
408
|
+
identifier: EApiPropertyDateIdentifier.CREATED_AT,
|
|
409
|
+
isResponse: true
|
|
410
|
+
})
|
|
411
|
+
createdAt: Date;
|
|
412
|
+
|
|
413
|
+
@ApiPropertyEnum({
|
|
414
|
+
entity: { name: 'Example' },
|
|
415
|
+
description: 'User role',
|
|
416
|
+
enum: UserRole,
|
|
417
|
+
enumName: 'UserRole',
|
|
418
|
+
isRequired: true
|
|
419
|
+
})
|
|
420
|
+
role: UserRole;
|
|
421
|
+
}
|
|
386
422
|
```
|
|
387
423
|
|
|
388
|
-
This will ensure all responses and errors include a correlation ID for tracing through logs.
|
|
389
|
-
|
|
390
424
|
## 🛣 Roadmap
|
|
391
425
|
| Task / Feature | Status |
|
|
392
426
|
|---------------|--------|
|
|
393
|
-
|
|
|
394
|
-
|
|
|
395
|
-
| -
|
|
396
|
-
|
|
|
397
|
-
|
|
|
398
|
-
|
|
|
399
|
-
|
|
|
400
|
-
|
|
|
401
|
-
|
|
|
402
|
-
|
|
|
403
|
-
|
|
|
404
|
-
|
|
|
405
|
-
|
|
|
406
|
-
|
|
|
427
|
+
| ✅ Core CRUD operations | ✅ Done |
|
|
428
|
+
| ✅ TypeORM integration | ✅ Done |
|
|
429
|
+
| ✅ Auto-generated DTOs | ✅ Done |
|
|
430
|
+
| ✅ Swagger documentation | ✅ Done |
|
|
431
|
+
| ✅ Request validation | ✅ Done |
|
|
432
|
+
| ✅ Response transformation | ✅ Done |
|
|
433
|
+
| ✅ Request correlation tracking | ✅ Done |
|
|
434
|
+
| ✅ Filtering, pagination and sorting | ✅ Done |
|
|
435
|
+
| ✅ Custom validation decorators | ✅ Done |
|
|
436
|
+
| ✅ Authentication integration | ✅ Done |
|
|
437
|
+
| 🚧 MongoDB support | 🚧 In Progress |
|
|
438
|
+
| 🚧 GraphQL support | 🚧 In Progress |
|
|
439
|
+
| 🚧 Caching mechanisms | 🚧 In Progress |
|
|
440
|
+
| 🚧 Advanced query building | 🚧 In Progress |
|
|
441
|
+
| 🚧 Soft delete functionality | 🚧 In Progress |
|
|
442
|
+
| 🚧 Event dispatching | 🚧 In Progress |
|
|
443
|
+
| 🚧 Bulk operations | 🚧 In Progress |
|
|
444
|
+
| 🚧 File upload handling | 🚧 In Progress |
|
|
445
|
+
| 🚧 Custom migration scripts | 🚧 In Progress |
|
|
446
|
+
| 🚧 CLI for scaffold generation | 🚧 In Progress |
|
|
407
447
|
|
|
408
448
|
## ❓ FAQ
|
|
409
449
|
## Frequently Asked Questions
|
|
410
450
|
|
|
411
|
-
###
|
|
412
|
-
|
|
451
|
+
### What is NestJS-Crud-Automator?
|
|
452
|
+
NestJS-Crud-Automator is a library that automates the creation of CRUD (Create, Read, Update, Delete) operations in NestJS applications. It provides decorators and utilities to generate controllers, services, DTOs, and validation with minimal boilerplate code.
|
|
453
|
+
|
|
454
|
+
### Does it work with any database?
|
|
455
|
+
Currently, the library is optimized for TypeORM which supports multiple databases including PostgreSQL, MySQL, MariaDB, SQLite, MS SQL Server, Oracle, and MongoDB. Support for other ORMs is planned for future releases.
|
|
456
|
+
|
|
457
|
+
### How do I customize the generated endpoints?
|
|
458
|
+
You can customize the endpoints by providing configuration in the `routes` property of the `@ApiController` decorator. Each route type (CREATE, GET, GET_LIST, UPDATE, PARTIAL_UPDATE, DELETE) can be configured separately with custom authentication, validation, transformation, and relation loading strategies.
|
|
413
459
|
|
|
414
|
-
###
|
|
415
|
-
The
|
|
460
|
+
### Can I extend the generated functionality?
|
|
461
|
+
Yes! The generated CRUD operations serve as a starting point. You can extend the controllers and services with custom methods to implement business-specific logic.
|
|
416
462
|
|
|
417
|
-
###
|
|
418
|
-
Yes,
|
|
463
|
+
### Does it support validation?
|
|
464
|
+
Yes, it integrates with class-validator and provides automatic validation based on the property decorators. You can also add custom validators to the routes configuration.
|
|
419
465
|
|
|
420
|
-
### How
|
|
421
|
-
|
|
466
|
+
### How does it handle relationships?
|
|
467
|
+
The library provides automatic relation loading with configurable strategies. You can specify eager or lazy loading, and control which relations are loaded for each endpoint.
|
|
422
468
|
|
|
423
|
-
###
|
|
424
|
-
|
|
469
|
+
### Can I use it with GraphQL?
|
|
470
|
+
Currently, the library focuses on REST APIs, but GraphQL support is planned for future releases.
|
|
425
471
|
|
|
426
|
-
### How
|
|
427
|
-
|
|
472
|
+
### How do I handle authentication?
|
|
473
|
+
You can configure authentication at the route level by specifying the authentication guard, type, and strategies in the route configuration.
|
|
428
474
|
|
|
429
|
-
###
|
|
430
|
-
|
|
475
|
+
### What about performance?
|
|
476
|
+
The library is designed to be lightweight and efficient. It uses TypeORM's query builder to optimize database queries and supports pagination, filtering, and sorting for list endpoints.
|
|
431
477
|
|
|
432
|
-
###
|
|
433
|
-
|
|
478
|
+
### Can I use it with existing NestJS applications?
|
|
479
|
+
Yes, the library is designed to integrate seamlessly with existing NestJS applications. You can apply it gradually to specific modules or entities without affecting the rest of your application.
|
|
434
480
|
|
|
435
481
|
## 🔒 License
|
|
436
482
|
This project is licensed under **MIT License
|