mongodb-dynamic-api 1.2.0-beta.5 → 1.2.0-beta.7
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/CHANGELOG.md +4 -0
- package/README/swagger.md +32 -0
- package/README.md +123 -5
- package/package.json +7 -5
- package/src/builders/route-decorators.builder.js +5 -1
- package/src/dynamic-api.module.d.ts +3 -2
- package/src/dynamic-api.module.js +43 -21
- package/src/helpers/config.helper.d.ts +61 -0
- package/src/helpers/config.helper.js +95 -0
- package/src/helpers/index.d.ts +1 -0
- package/src/helpers/index.js +1 -0
- package/src/index.d.ts +0 -1
- package/src/index.js +0 -1
- package/src/interfaces/dynamic-api-options.interface.d.ts +5 -4
- package/src/interfaces/route-config.interface.d.ts +2 -1
- package/src/mixins/entity-presenter.mixin.d.ts +2 -33
- package/src/mixins/entity-presenter.mixin.js +3 -2
- package/src/modules/create-many/create-many-controller.interface.d.ts +3 -1
- package/src/modules/create-many/create-many-controller.mixin.js +8 -2
- package/src/modules/create-many/create-many.helper.d.ts +2 -2
- package/src/modules/create-many/create-many.helper.js +4 -8
- package/src/modules/create-many/create-many.module.d.ts +2 -2
- package/src/modules/create-many/create-many.module.js +2 -2
- package/src/modules/create-one/create-one-controller.mixin.js +1 -1
- package/src/modules/create-one/create-one.helper.d.ts +2 -2
- package/src/modules/create-one/create-one.helper.js +4 -8
- package/src/modules/create-one/create-one.module.d.ts +2 -2
- package/src/modules/create-one/create-one.module.js +2 -2
- package/src/modules/delete-one/delete-one.helper.d.ts +2 -2
- package/src/modules/delete-one/delete-one.helper.js +4 -8
- package/src/modules/delete-one/delete-one.module.d.ts +2 -2
- package/src/modules/delete-one/delete-one.module.js +2 -2
- package/src/modules/duplicate-one/base-duplicate-one.service.d.ts +1 -1
- package/src/modules/duplicate-one/duplicate-one-controller.interface.d.ts +1 -1
- package/src/modules/duplicate-one/duplicate-one-controller.mixin.js +1 -1
- package/src/modules/duplicate-one/duplicate-one-service.interface.d.ts +1 -1
- package/src/modules/duplicate-one/duplicate-one.helper.d.ts +2 -2
- package/src/modules/duplicate-one/duplicate-one.helper.js +4 -8
- package/src/modules/duplicate-one/duplicate-one.module.d.ts +2 -2
- package/src/modules/duplicate-one/duplicate-one.module.js +2 -2
- package/src/modules/get-many/get-many.helper.d.ts +2 -2
- package/src/modules/get-many/get-many.helper.js +4 -8
- package/src/modules/get-many/get-many.module.d.ts +2 -2
- package/src/modules/get-many/get-many.module.js +2 -2
- package/src/modules/get-one/get-one.helper.d.ts +2 -2
- package/src/modules/get-one/get-one.helper.js +4 -8
- package/src/modules/get-one/get-one.module.d.ts +2 -2
- package/src/modules/get-one/get-one.module.js +2 -2
- package/src/modules/replace-one/replace-one-controller.mixin.js +1 -1
- package/src/modules/replace-one/replace-one.helper.d.ts +2 -2
- package/src/modules/replace-one/replace-one.helper.js +4 -8
- package/src/modules/replace-one/replace-one.module.d.ts +2 -2
- package/src/modules/replace-one/replace-one.module.js +2 -2
- package/src/modules/update-one/update-one-controller.mixin.js +1 -1
- package/src/modules/update-one/update-one.helper.d.ts +2 -2
- package/src/modules/update-one/update-one.helper.js +4 -8
- package/src/modules/update-one/update-one.module.d.ts +2 -2
- package/src/modules/update-one/update-one.module.js +2 -2
- package/src/version.json +3 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/src/dynamic-api.constant.d.ts +0 -2
- package/src/dynamic-api.constant.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.0-beta.7](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/prerelease...1.2.0-beta.7) (2024-03-02)
|
|
4
|
+
|
|
5
|
+
## [1.2.0-beta.6](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/prerelease...1.2.0-beta.6) (2024-03-01)
|
|
6
|
+
|
|
3
7
|
## [1.2.0-beta.5](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/prerelease...1.2.0-beta.5) (2024-03-01)
|
|
4
8
|
|
|
5
9
|
## [1.2.0-beta.4](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/prerelease...1.2.0-beta.4) (2024-02-29)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[back to README](../README.md)
|
|
2
|
+
|
|
3
|
+
## User API - Swagger UI screenshots
|
|
4
|
+
|
|
5
|
+
#### Get many users
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
#### Get one user
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
#### Create many users
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
#### Create one user
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
#### Update one user
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
#### Delete one user
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
#### Replace one user
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
#### Duplicate one user
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
#### Generated Schemas
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
[back to README](../README.md)
|
package/README.md
CHANGED
|
@@ -56,17 +56,135 @@
|
|
|
56
56
|
|
|
57
57
|
<p style="text-align: justify; width: 100%;font-size: 15px;">
|
|
58
58
|
|
|
59
|
-
**mongodb-dynamic-api** is an auto generated CRUD API for MongoDB using NestJS.
|
|
59
|
+
**mongodb-dynamic-api** is an auto generated CRUD API for MongoDB using NestJS 10.
|
|
60
60
|
|
|
61
61
|
</p>
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
65
|
## npm package <img src="https://pbs.twimg.com/media/EDoWJbUXYAArclg.png" width="24" height="24" />
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
```text
|
|
67
|
+
npm install --save mongodb-dynamic-api
|
|
68
|
+
```
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
---
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
### HOW TO ENJOY IT
|
|
73
|
+
|
|
74
|
+
- Start a new [nest](https://docs.nestjs.com/) project with **typescript** (use the `--strict` option)
|
|
75
|
+
```text
|
|
76
|
+
nest new --strict your-project-name
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- Go to your project root and install the [mongodb-dynamic-api](https://www.npmjs.com/package/mongodb-dynamic-api) package
|
|
80
|
+
```text
|
|
81
|
+
npm i -S mongodb-dynamic-api
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- Add DynamicApiModule to your app.module.ts and pass the MongoDB connection string to the `forRoot` method
|
|
85
|
+
```typescript
|
|
86
|
+
@Module({
|
|
87
|
+
imports: [
|
|
88
|
+
// ...
|
|
89
|
+
DynamicApiModule.forRoot(
|
|
90
|
+
// <- pass the MongoDB connection string here
|
|
91
|
+
),
|
|
92
|
+
// ...
|
|
93
|
+
],
|
|
94
|
+
controllers: [AppController],
|
|
95
|
+
providers: [AppService],
|
|
96
|
+
})
|
|
97
|
+
export class AppModule {}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- Ok, now let's add our first content. This content will be a simple `User` with a `name` and an `email` field.
|
|
101
|
+
```typescript
|
|
102
|
+
// user.ts
|
|
103
|
+
@Schema({ collection: 'users' })
|
|
104
|
+
export class User extends BaseEntity { // <- you must extend BaseEntity
|
|
105
|
+
@Prop({ type: String })
|
|
106
|
+
name: string;
|
|
107
|
+
|
|
108
|
+
@Prop({ type: String })
|
|
109
|
+
email: string;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
```typescript
|
|
113
|
+
// users.module.ts
|
|
114
|
+
@Module({
|
|
115
|
+
imports: [
|
|
116
|
+
DynamicApiModule.forFeature({ // <- use the forFeature method to add the User content
|
|
117
|
+
entity: User,
|
|
118
|
+
controllerOptions: {
|
|
119
|
+
path: 'users',
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
],
|
|
123
|
+
})
|
|
124
|
+
export class UsersModule {}
|
|
125
|
+
```
|
|
126
|
+
```typescript
|
|
127
|
+
// app.module.ts
|
|
128
|
+
@Module({
|
|
129
|
+
imports: [
|
|
130
|
+
// ...
|
|
131
|
+
DynamicApiModule.forRoot('...'),
|
|
132
|
+
UsersModule, // <- add the module to the imports after the DynamicApiModule
|
|
133
|
+
],
|
|
134
|
+
controllers: [AppController],
|
|
135
|
+
providers: [AppService],
|
|
136
|
+
})
|
|
137
|
+
export class AppModule {}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**That's all !** *You now have a fully functional CRUD API for the `User` content at the `/users` path.*
|
|
141
|
+
|
|
142
|
+
___
|
|
143
|
+
### Swagger (optional but recommended)
|
|
144
|
+
```typescript
|
|
145
|
+
async function bootstrap() {
|
|
146
|
+
const app = await NestFactory.create(AppModule);
|
|
147
|
+
// ...
|
|
148
|
+
enableDynamicAPISwagger(app); // <- add this line in your main.ts file
|
|
149
|
+
|
|
150
|
+
await app.listen(3000);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
The `enableDynamicAPISwagger` function will automatically build the swagger documentation.
|
|
154
|
+
This method can be called with optional parameters to specify more documentation options.
|
|
155
|
+
|
|
156
|
+
Do not forget to add the `@ApiProperty` decorator to your entity properties to have a better swagger documentation.
|
|
157
|
+
```typescript
|
|
158
|
+
// user.entity.ts
|
|
159
|
+
@Schema({ collection: 'users' })
|
|
160
|
+
export class UserEntity extends BaseEntity {
|
|
161
|
+
@ApiProperty() // <- add this line
|
|
162
|
+
@Prop({ type: String })
|
|
163
|
+
name: string;
|
|
164
|
+
|
|
165
|
+
@ApiProperty() // <- add this line
|
|
166
|
+
@Prop({ type: String })
|
|
167
|
+
email: string;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
go to the swagger API path (default to `/openapi`) and you will see the auto generated API
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+

|
|
175
|
+
|
|
176
|
+
[more screenshots](/README/swagger.md)
|
|
177
|
+
|
|
178
|
+
___
|
|
179
|
+
### Versioning (optional)
|
|
180
|
+
```typescript
|
|
181
|
+
async function bootstrap() {
|
|
182
|
+
const app = await NestFactory.create(AppModule);
|
|
183
|
+
// ...
|
|
184
|
+
enableDynamicAPIVersioning(app); // <- add this line in your main.ts file
|
|
185
|
+
|
|
186
|
+
await app.listen(3000);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
The `enableDynamicAPIVersioning` function will automatically add versioning to the API. By default it will use the URI versioning type.
|
|
190
|
+
This method can be called with a second optional parameter to specify more options.
|
package/package.json
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongodb-dynamic-api",
|
|
3
|
-
"version": "1.2.0-beta.
|
|
3
|
+
"version": "1.2.0-beta.7",
|
|
4
4
|
"description": "Auto generated CRUD API for MongoDB using NestJS",
|
|
5
|
-
"author": "Mickaël NODANCHE <mikeonline75@gmail.com> (https://cv-mikeonline.web.app)",
|
|
6
|
-
"homepage": "https://mikedev75015.github.io",
|
|
7
|
-
"license": "MIT",
|
|
8
5
|
"readmeFilename": "README.md",
|
|
9
6
|
"main": "index.js",
|
|
10
7
|
"types": "index.d.ts",
|
|
@@ -33,9 +30,14 @@
|
|
|
33
30
|
"dynamic-api",
|
|
34
31
|
"crud"
|
|
35
32
|
],
|
|
33
|
+
"author": "Mickaël NODANCHE <mikeonline75@gmail.com> (https://cv-mikeonline.web.app)",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/MikeDev75015/mongodb-dynamic-api/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://mikedev75015.github.io",
|
|
36
39
|
"dependencies": {
|
|
37
40
|
"@nestjs/common": "^10.3.2",
|
|
38
|
-
"@nestjs/config": "^3.2.0",
|
|
39
41
|
"@nestjs/core": "^10.3.2",
|
|
40
42
|
"@nestjs/mongoose": "^10.0.4",
|
|
41
43
|
"@nestjs/platform-express": "^10.3.2",
|
|
@@ -15,6 +15,7 @@ class RouteDecoratorsBuilder {
|
|
|
15
15
|
this.presenter = presenter;
|
|
16
16
|
this.responseRouteTypeIsArray = [
|
|
17
17
|
'GetMany',
|
|
18
|
+
'CreateMany',
|
|
18
19
|
];
|
|
19
20
|
}
|
|
20
21
|
build() {
|
|
@@ -57,7 +58,10 @@ class RouteDecoratorsBuilder {
|
|
|
57
58
|
type: this.presenter ?? this.entity,
|
|
58
59
|
isArray: this.responseRouteTypeIsArray.includes(this.routeType),
|
|
59
60
|
}),
|
|
60
|
-
...(this.body ? [(0, swagger_1.ApiBody)({
|
|
61
|
+
...(this.body ? [(0, swagger_1.ApiBody)({
|
|
62
|
+
type: this.body,
|
|
63
|
+
...(this.routeType === 'DuplicateOne' ? { required: false } : {})
|
|
64
|
+
})] : []),
|
|
61
65
|
...(this.param && paramKey
|
|
62
66
|
? [
|
|
63
67
|
(0, swagger_1.ApiParam)({
|
|
@@ -2,6 +2,7 @@ import { DynamicModule } from '@nestjs/common';
|
|
|
2
2
|
import { DynamicApiOptions } from './interfaces';
|
|
3
3
|
import { BaseEntity } from './models';
|
|
4
4
|
export declare class DynamicApiModule {
|
|
5
|
-
static
|
|
6
|
-
static
|
|
5
|
+
static connectionName: string;
|
|
6
|
+
static forRoot(uri: string): DynamicModule;
|
|
7
|
+
static forFeature<Entity extends BaseEntity>({ entity, controllerOptions: { path, apiTag, version: controllerVersion, validationPipeOptions: controllerValidationPipeOptions, }, routes, }: DynamicApiOptions<Entity>): DynamicModule;
|
|
7
8
|
}
|
|
@@ -10,27 +10,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.DynamicApiModule = void 0;
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
12
|
const mongoose_1 = require("@nestjs/mongoose");
|
|
13
|
+
const lodash_1 = require("lodash");
|
|
13
14
|
const decorators_1 = require("./decorators");
|
|
14
|
-
const dynamic_api_constant_1 = require("./dynamic-api.constant");
|
|
15
15
|
const modules_1 = require("./modules");
|
|
16
16
|
let DynamicApiModule = DynamicApiModule_1 = class DynamicApiModule {
|
|
17
|
-
static forRoot(
|
|
18
|
-
if (!
|
|
19
|
-
throw new Error('You must provide a
|
|
17
|
+
static forRoot(uri) {
|
|
18
|
+
if (!uri) {
|
|
19
|
+
throw new Error('You must provide a valid mongodb uri in the forRoot method to use MongoDB Dynamic API');
|
|
20
20
|
}
|
|
21
21
|
return {
|
|
22
22
|
module: DynamicApiModule_1,
|
|
23
23
|
imports: [
|
|
24
|
-
mongoose_1.MongooseModule.forRoot(
|
|
25
|
-
`${process.env.BDD_URL}/${process.env.BDD_BASE}?retryWrites=true&w=majority`, {
|
|
26
|
-
connectionName: process.env.BBD_CONNECTION_NAME || dynamic_api_constant_1.DEFAULT_BDD_CONNECTION_NAME,
|
|
27
|
-
}),
|
|
24
|
+
mongoose_1.MongooseModule.forRoot(uri, { connectionName: DynamicApiModule_1.connectionName }),
|
|
28
25
|
],
|
|
29
26
|
};
|
|
30
27
|
}
|
|
31
|
-
static forFeature({ entity, controllerOptions: { path, apiTag, version:
|
|
32
|
-
const { indexes, hooks } = Reflect.getOwnMetadata(decorators_1.DYNAMIC_API_SCHEMA_OPTIONS_METADATA, entity);
|
|
28
|
+
static forFeature({ entity, controllerOptions: { path, apiTag, version: controllerVersion, validationPipeOptions: controllerValidationPipeOptions, }, routes = [], }) {
|
|
29
|
+
const { indexes, hooks } = Reflect.getOwnMetadata(decorators_1.DYNAMIC_API_SCHEMA_OPTIONS_METADATA, entity) ?? {};
|
|
33
30
|
const schema = mongoose_1.SchemaFactory.createForClass(entity);
|
|
31
|
+
schema.set('timestamps', true);
|
|
34
32
|
if (indexes) {
|
|
35
33
|
indexes.forEach(({ fields, options }) => {
|
|
36
34
|
schema.index(fields, options);
|
|
@@ -41,33 +39,56 @@ let DynamicApiModule = DynamicApiModule_1 = class DynamicApiModule {
|
|
|
41
39
|
schema[method](type, { document: true, query: true, ...options }, callback);
|
|
42
40
|
});
|
|
43
41
|
}
|
|
44
|
-
const databaseModule = mongoose_1.MongooseModule.forFeature([{ name: entity.name, schema }],
|
|
42
|
+
const databaseModule = mongoose_1.MongooseModule.forFeature([{ name: entity.name, schema }], DynamicApiModule_1.connectionName);
|
|
43
|
+
if (!routes.length) {
|
|
44
|
+
const contentName = (0, lodash_1.lowerCase)(entity.name);
|
|
45
|
+
routes = [
|
|
46
|
+
{ type: 'GetMany', description: `Get many ${contentName}` },
|
|
47
|
+
{ type: 'GetOne', description: `Get one ${contentName} by id` },
|
|
48
|
+
{ type: 'CreateMany', description: `Create many ${contentName}` },
|
|
49
|
+
{ type: 'CreateOne', description: `Create one ${contentName}` },
|
|
50
|
+
{ type: 'ReplaceOne', description: `Replace one ${contentName}` },
|
|
51
|
+
{ type: 'UpdateOne', description: `Update one ${contentName}` },
|
|
52
|
+
{ type: 'DuplicateOne', description: `Duplicate one ${contentName}` },
|
|
53
|
+
{ type: 'DeleteOne', description: `Delete one ${contentName}` },
|
|
54
|
+
];
|
|
55
|
+
}
|
|
45
56
|
return {
|
|
46
57
|
module: DynamicApiModule_1,
|
|
47
58
|
imports: [
|
|
48
59
|
...routes
|
|
49
|
-
.map(({ type, description, version: routeVersion, dTOs }) => {
|
|
50
|
-
const version = routeVersion ??
|
|
60
|
+
.map(({ type, description, version: routeVersion, dTOs, validationPipeOptions: routeValidationPipeOptions, }) => {
|
|
61
|
+
const version = routeVersion ?? controllerVersion;
|
|
62
|
+
let module;
|
|
51
63
|
switch (type) {
|
|
52
64
|
case 'CreateMany':
|
|
53
|
-
|
|
65
|
+
module = modules_1.CreateManyModule;
|
|
66
|
+
break;
|
|
54
67
|
case 'CreateOne':
|
|
55
|
-
|
|
68
|
+
module = modules_1.CreateOneModule;
|
|
69
|
+
break;
|
|
56
70
|
case 'DeleteOne':
|
|
57
|
-
|
|
71
|
+
module = modules_1.DeleteOneModule;
|
|
72
|
+
break;
|
|
58
73
|
case 'DuplicateOne':
|
|
59
|
-
|
|
74
|
+
module = modules_1.DuplicateOneModule;
|
|
75
|
+
break;
|
|
60
76
|
case 'GetMany':
|
|
61
|
-
|
|
77
|
+
module = modules_1.GetManyModule;
|
|
78
|
+
break;
|
|
62
79
|
case 'GetOne':
|
|
63
|
-
|
|
80
|
+
module = modules_1.GetOneModule;
|
|
81
|
+
break;
|
|
64
82
|
case 'ReplaceOne':
|
|
65
|
-
|
|
83
|
+
module = modules_1.ReplaceOneModule;
|
|
84
|
+
break;
|
|
66
85
|
case 'UpdateOne':
|
|
67
|
-
|
|
86
|
+
module = modules_1.UpdateOneModule;
|
|
87
|
+
break;
|
|
68
88
|
default:
|
|
69
89
|
throw new Error(`Route for ${type} is not implemented`);
|
|
70
90
|
}
|
|
91
|
+
return module.forFeature(databaseModule, entity, path, apiTag, version, description, dTOs, routeValidationPipeOptions ?? controllerValidationPipeOptions);
|
|
71
92
|
})
|
|
72
93
|
.filter((module) => module),
|
|
73
94
|
],
|
|
@@ -75,6 +96,7 @@ let DynamicApiModule = DynamicApiModule_1 = class DynamicApiModule {
|
|
|
75
96
|
}
|
|
76
97
|
};
|
|
77
98
|
exports.DynamicApiModule = DynamicApiModule;
|
|
99
|
+
DynamicApiModule.connectionName = 'dynamic-api-connection';
|
|
78
100
|
exports.DynamicApiModule = DynamicApiModule = DynamicApiModule_1 = __decorate([
|
|
79
101
|
(0, common_1.Module)({})
|
|
80
102
|
], DynamicApiModule);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { INestApplication, ValidationPipeOptions, VersioningOptions } from '@nestjs/common';
|
|
2
|
+
import { SwaggerDocumentOptions } from '@nestjs/swagger';
|
|
3
|
+
import { ExternalDocumentationObject, ParameterObject, SecuritySchemeObject, ServerVariableObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';
|
|
4
|
+
type DynamicAPISwaggerExtraConfig = {
|
|
5
|
+
termsOfService?: string;
|
|
6
|
+
contact?: {
|
|
7
|
+
name: string;
|
|
8
|
+
url: string;
|
|
9
|
+
email: string;
|
|
10
|
+
};
|
|
11
|
+
license?: {
|
|
12
|
+
name: string;
|
|
13
|
+
url: string;
|
|
14
|
+
};
|
|
15
|
+
servers?: {
|
|
16
|
+
url: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
variables?: Record<string, ServerVariableObject>;
|
|
19
|
+
}[];
|
|
20
|
+
externalDocs?: {
|
|
21
|
+
description: string;
|
|
22
|
+
url: string;
|
|
23
|
+
};
|
|
24
|
+
basePath?: string;
|
|
25
|
+
tags?: {
|
|
26
|
+
name: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
externalDocs?: ExternalDocumentationObject;
|
|
29
|
+
}[];
|
|
30
|
+
extensions?: {
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
};
|
|
33
|
+
security?: {
|
|
34
|
+
[key: string]: SecuritySchemeObject;
|
|
35
|
+
};
|
|
36
|
+
globalParameters?: ParameterObject[];
|
|
37
|
+
securityRequirements?: {
|
|
38
|
+
[key: string]: string[];
|
|
39
|
+
};
|
|
40
|
+
bearerAuth?: SecuritySchemeObject;
|
|
41
|
+
oAuth2?: SecuritySchemeObject;
|
|
42
|
+
apiKey?: SecuritySchemeObject;
|
|
43
|
+
basicAuth?: SecuritySchemeObject;
|
|
44
|
+
cookieAuth?: {
|
|
45
|
+
cookieName: string;
|
|
46
|
+
options: SecuritySchemeObject;
|
|
47
|
+
securityName: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
type DynamicAPISwaggerOptions = {
|
|
51
|
+
title?: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
version?: string;
|
|
54
|
+
path?: string;
|
|
55
|
+
swaggerConfig?: DynamicAPISwaggerExtraConfig;
|
|
56
|
+
swaggerOptions?: SwaggerDocumentOptions;
|
|
57
|
+
};
|
|
58
|
+
declare function enableDynamicAPISwagger(app: INestApplication, options?: DynamicAPISwaggerOptions): void;
|
|
59
|
+
declare function enableDynamicAPIVersioning(app: INestApplication, options?: VersioningOptions): void;
|
|
60
|
+
declare function enableDynamicAPIValidation(app: INestApplication, options?: ValidationPipeOptions): void;
|
|
61
|
+
export { enableDynamicAPISwagger, enableDynamicAPIVersioning, enableDynamicAPIValidation, DynamicAPISwaggerOptions, DynamicAPISwaggerExtraConfig, };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.enableDynamicAPIValidation = exports.enableDynamicAPIVersioning = exports.enableDynamicAPISwagger = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
6
|
+
const version_json_1 = require("../version.json");
|
|
7
|
+
function buildExtraConfig(config, swaggerConfig) {
|
|
8
|
+
Object.keys(swaggerConfig).forEach((key) => {
|
|
9
|
+
const value = swaggerConfig[key];
|
|
10
|
+
switch (key) {
|
|
11
|
+
case 'termsOfService':
|
|
12
|
+
config.setTermsOfService(value);
|
|
13
|
+
break;
|
|
14
|
+
case 'contact':
|
|
15
|
+
config.setContact(value.name, value.url, value.email);
|
|
16
|
+
break;
|
|
17
|
+
case 'license':
|
|
18
|
+
config.setLicense(value.name, value.url);
|
|
19
|
+
break;
|
|
20
|
+
case 'servers':
|
|
21
|
+
value.forEach((server) => {
|
|
22
|
+
config.addServer(server.url, server.description, server.variables);
|
|
23
|
+
});
|
|
24
|
+
break;
|
|
25
|
+
case 'externalDocs':
|
|
26
|
+
config.setExternalDoc(value.description, value.url);
|
|
27
|
+
break;
|
|
28
|
+
case 'basePath':
|
|
29
|
+
config.setBasePath(value);
|
|
30
|
+
break;
|
|
31
|
+
case 'tags':
|
|
32
|
+
value.forEach((tag) => {
|
|
33
|
+
config.addTag(tag.name, tag.description, tag.externalDocs);
|
|
34
|
+
});
|
|
35
|
+
break;
|
|
36
|
+
case 'extensions':
|
|
37
|
+
Object.keys(value).forEach((extensionKey) => {
|
|
38
|
+
config.addExtension(extensionKey, value[extensionKey]);
|
|
39
|
+
});
|
|
40
|
+
break;
|
|
41
|
+
case 'security':
|
|
42
|
+
Object.keys(value).forEach((securityKey) => {
|
|
43
|
+
config.addSecurity(securityKey, value[securityKey]);
|
|
44
|
+
});
|
|
45
|
+
break;
|
|
46
|
+
case 'globalParameters':
|
|
47
|
+
config.addGlobalParameters(...value);
|
|
48
|
+
break;
|
|
49
|
+
case 'securityRequirements':
|
|
50
|
+
Object.keys(value).forEach((securityKey) => {
|
|
51
|
+
config.addSecurityRequirements(securityKey, value[securityKey]);
|
|
52
|
+
});
|
|
53
|
+
break;
|
|
54
|
+
case 'bearerAuth':
|
|
55
|
+
config.addBearerAuth(value);
|
|
56
|
+
break;
|
|
57
|
+
case 'oAuth2':
|
|
58
|
+
config.addOAuth2(value);
|
|
59
|
+
break;
|
|
60
|
+
case 'apiKey':
|
|
61
|
+
config.addApiKey(value);
|
|
62
|
+
break;
|
|
63
|
+
case 'basicAuth':
|
|
64
|
+
config.addBasicAuth(value);
|
|
65
|
+
break;
|
|
66
|
+
case 'cookieAuth':
|
|
67
|
+
config.addCookieAuth(value.cookieName, value.options, value.securityName);
|
|
68
|
+
break;
|
|
69
|
+
default:
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function enableDynamicAPISwagger(app, options = {}) {
|
|
75
|
+
const { title = 'MongoDB Dynamic API', description = 'Auto generated CRUD for MongoDB', version = version_json_1.default?.version?.split('-beta')[0], path = '/openapi', swaggerConfig, swaggerOptions, } = options ?? {};
|
|
76
|
+
const config = new swagger_1.DocumentBuilder()
|
|
77
|
+
.setTitle(title)
|
|
78
|
+
.setDescription(description)
|
|
79
|
+
.setVersion(version);
|
|
80
|
+
buildExtraConfig(config, swaggerConfig ?? {});
|
|
81
|
+
const document = swagger_1.SwaggerModule.createDocument(app, config.build(), swaggerOptions);
|
|
82
|
+
swagger_1.SwaggerModule.setup(path, app, document);
|
|
83
|
+
}
|
|
84
|
+
exports.enableDynamicAPISwagger = enableDynamicAPISwagger;
|
|
85
|
+
function enableDynamicAPIVersioning(app, options) {
|
|
86
|
+
app.enableVersioning({
|
|
87
|
+
type: common_1.VersioningType.URI,
|
|
88
|
+
...options,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
exports.enableDynamicAPIVersioning = enableDynamicAPIVersioning;
|
|
92
|
+
function enableDynamicAPIValidation(app, options = {}) {
|
|
93
|
+
app.useGlobalPipes(new common_1.ValidationPipe(options));
|
|
94
|
+
}
|
|
95
|
+
exports.enableDynamicAPIValidation = enableDynamicAPIValidation;
|
package/src/helpers/index.d.ts
CHANGED
package/src/helpers/index.js
CHANGED
|
@@ -14,4 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./config.helper"), exports);
|
|
17
18
|
__exportStar(require("./route-decorators.helper"), exports);
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { Type } from '@nestjs/common';
|
|
1
|
+
import { Type, ValidationPipeOptions } from '@nestjs/common';
|
|
2
2
|
import { BaseEntity } from '../models';
|
|
3
3
|
import { RouteConfig } from './route-config.interface';
|
|
4
4
|
interface ControllerOptions {
|
|
5
5
|
path: string;
|
|
6
6
|
apiTag?: string;
|
|
7
7
|
version?: string;
|
|
8
|
+
validationPipeOptions?: ValidationPipeOptions;
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
interface DynamicApiOptions<Entity extends BaseEntity> {
|
|
10
11
|
entity: Type<Entity>;
|
|
11
12
|
controllerOptions: ControllerOptions;
|
|
12
|
-
routes
|
|
13
|
+
routes?: RouteConfig<Entity>[];
|
|
13
14
|
}
|
|
14
|
-
export {};
|
|
15
|
+
export { DynamicApiOptions, ControllerOptions };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type } from '@nestjs/common';
|
|
1
|
+
import { Type, ValidationPipeOptions } from '@nestjs/common';
|
|
2
2
|
import { BaseEntity } from '../models';
|
|
3
3
|
type RouteType = 'GetMany' | 'GetOne' | 'CreateOne' | 'CreateMany' | 'UpdateOne' | 'ReplaceOne' | 'DeleteOne' | 'DuplicateOne';
|
|
4
4
|
type DTOsBundle = {
|
|
@@ -12,5 +12,6 @@ interface RouteConfig<Entity extends BaseEntity> {
|
|
|
12
12
|
description?: string;
|
|
13
13
|
version?: string;
|
|
14
14
|
dTOs?: DTOsBundle;
|
|
15
|
+
validationPipeOptions?: ValidationPipeOptions;
|
|
15
16
|
}
|
|
16
17
|
export { DTOsBundle, RouteType, RouteConfig };
|
|
@@ -1,38 +1,7 @@
|
|
|
1
|
-
/// <reference types="mongoose/types/aggregate" />
|
|
2
|
-
/// <reference types="mongoose/types/callback" />
|
|
3
|
-
/// <reference types="mongoose/types/collection" />
|
|
4
|
-
/// <reference types="mongoose/types/connection" />
|
|
5
|
-
/// <reference types="mongoose/types/cursor" />
|
|
6
|
-
/// <reference types="mongoose/types/document" />
|
|
7
|
-
/// <reference types="mongoose/types/error" />
|
|
8
|
-
/// <reference types="mongoose/types/expressions" />
|
|
9
|
-
/// <reference types="mongoose/types/helpers" />
|
|
10
|
-
/// <reference types="mongoose/types/middlewares" />
|
|
11
|
-
/// <reference types="mongoose/types/indexes" />
|
|
12
|
-
/// <reference types="mongoose/types/models" />
|
|
13
|
-
/// <reference types="mongoose/types/mongooseoptions" />
|
|
14
|
-
/// <reference types="mongoose/types/pipelinestage" />
|
|
15
|
-
/// <reference types="mongoose/types/populate" />
|
|
16
|
-
/// <reference types="mongoose/types/query" />
|
|
17
|
-
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
|
-
/// <reference types="mongoose/types/session" />
|
|
20
|
-
/// <reference types="mongoose/types/types" />
|
|
21
|
-
/// <reference types="mongoose/types/utility" />
|
|
22
|
-
/// <reference types="mongoose/types/validation" />
|
|
23
|
-
/// <reference types="mongoose/types/virtuals" />
|
|
24
|
-
/// <reference types="mongoose" />
|
|
25
|
-
/// <reference types="mongoose/types/inferschematype" />
|
|
26
1
|
import { Type } from '@nestjs/common';
|
|
27
2
|
import { BaseEntity } from '../models';
|
|
28
|
-
declare function EntityPresenterMixin<Entity extends BaseEntity>(entity: Type<Entity
|
|
29
|
-
new (...args: any[]): {
|
|
30
|
-
_id: import("mongoose").Schema.Types.ObjectId;
|
|
31
|
-
__v: number;
|
|
32
|
-
id: string;
|
|
33
|
-
createdAt: Date;
|
|
34
|
-
updatedAt: Date;
|
|
35
|
-
};
|
|
3
|
+
declare function EntityPresenterMixin<Entity extends BaseEntity>(entity: Type<Entity>, keysToExclude?: (keyof Entity)[]): {
|
|
4
|
+
new (...args: any[]): {};
|
|
36
5
|
apply(this: Function, thisArg: any, argArray?: any): any;
|
|
37
6
|
call(this: Function, thisArg: any, ...argArray: any[]): any;
|
|
38
7
|
bind(this: Function, thisArg: any, ...argArray: any[]): any;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EntityPresenterMixin = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
5
|
+
function EntityPresenterMixin(entity, keysToExclude) {
|
|
6
|
+
class EntityPresenter extends (keysToExclude ? (0, swagger_1.OmitType)(entity, keysToExclude) : entity) {
|
|
6
7
|
}
|
|
7
8
|
return EntityPresenter;
|
|
8
9
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { BaseEntity } from '../../models';
|
|
2
2
|
import { CreateManyService } from './create-many-service.interface';
|
|
3
3
|
interface CreateManyController<Entity extends BaseEntity> {
|
|
4
|
-
createMany
|
|
4
|
+
createMany(body: {
|
|
5
|
+
list: any;
|
|
6
|
+
}): Promise<Entity[]>;
|
|
5
7
|
}
|
|
6
8
|
type CreateManyControllerConstructor<Entity extends BaseEntity> = new (service: CreateManyService<Entity>) => CreateManyController<Entity>;
|
|
7
9
|
export type { CreateManyController, CreateManyControllerConstructor };
|