mongodb-dynamic-api 2.3.0 → 2.3.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/CHANGELOG.md +2 -0
- package/package.json +1 -1
- package/src/dynamic-api.module.js +25 -21
- package/src/guards/base-policies.guard.d.ts +28 -3
- package/src/guards/base-policies.guard.js +8 -7
- package/src/interfaces/dynamic-api-ability.interface.d.ts +2 -2
- package/src/interfaces/dynamic-api-global-state.interface.d.ts +1 -0
- package/src/interfaces/dynamic-api-policy-handler.interface.d.ts +27 -3
- package/src/interfaces/dynamic-api-route-response.type.d.ts +7 -0
- package/src/interfaces/dynamic-api-route-response.type.js +2 -0
- package/src/interfaces/dynamic-api-service-callback.interface.d.ts +38 -5
- package/src/interfaces/index.d.ts +1 -0
- package/src/interfaces/index.js +1 -0
- package/src/mixins/create-policies-guard.mixin.d.ts +1 -2
- package/src/mixins/create-policies-guard.mixin.js +8 -5
- package/src/modules/auth/auth.helper.d.ts +3 -3
- package/src/modules/auth/auth.helper.js +3 -3
- package/src/modules/auth/auth.module.d.ts +1 -1
- package/src/modules/auth/auth.module.js +5 -5
- package/src/modules/auth/interfaces/auth-options.interface.d.ts +11 -12
- package/src/modules/auth/mixins/auth-register-policies-guard.mixin.d.ts +2 -2
- package/src/modules/auth/services/base-auth.service.js +8 -8
- package/src/routes/delete-many/delete-many-controller.interface.d.ts +2 -2
- package/src/routes/delete-many/delete-many-service.interface.d.ts +2 -2
- package/src/routes/delete-one/delete-one-controller.interface.d.ts +3 -2
- package/src/routes/delete-one/delete-one-service.interface.d.ts +3 -5
- package/src/services/base/base.service.d.ts +14 -6
- package/src/services/base/base.service.js +58 -28
- package/src/services/dynamic-api-global-state/dynamic-api-global-state.service.d.ts +6 -4
- package/src/services/dynamic-api-global-state/dynamic-api-global-state.service.js +18 -12
- package/src/version.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -24,21 +24,29 @@
|
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
import { Type } from '@nestjs/common';
|
|
26
26
|
import { FilterQuery, Model, Schema } from 'mongoose';
|
|
27
|
-
import { AbilityPredicate, DynamicApiCallbackMethods } from '../../interfaces';
|
|
27
|
+
import { AbilityPredicate, DeleteResult, DynamicApiCallbackMethods, UpdateResult } from '../../interfaces';
|
|
28
28
|
import { BaseEntity } from '../../models';
|
|
29
29
|
import { DynamicApiResetPasswordOptions } from '../../modules';
|
|
30
30
|
export declare abstract class BaseService<Entity extends BaseEntity> {
|
|
31
31
|
protected readonly model: Model<Entity>;
|
|
32
|
-
|
|
33
|
-
user: unknown;
|
|
32
|
+
protected user: unknown;
|
|
34
33
|
protected readonly entity: Type<Entity>;
|
|
34
|
+
protected readonly abilityPredicate: AbilityPredicate<Entity> | undefined;
|
|
35
35
|
protected readonly passwordField: keyof Entity | undefined;
|
|
36
36
|
protected readonly resetPasswordOptions: DynamicApiResetPasswordOptions<Entity> | undefined;
|
|
37
|
-
protected readonly callbackMethods: DynamicApiCallbackMethods
|
|
37
|
+
protected readonly callbackMethods: DynamicApiCallbackMethods;
|
|
38
38
|
protected constructor(model: Model<Entity>);
|
|
39
39
|
get isSoftDeletable(): boolean;
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
protected findManyDocumentsWithAbilityPredicate(conditions?: FilterQuery<Entity>): Promise<Entity[]>;
|
|
41
|
+
protected findOneDocumentWithAbilityPredicate(_id: string | Schema.Types.ObjectId | undefined, conditions?: FilterQuery<Entity>): Promise<Entity>;
|
|
42
|
+
protected findManyDocuments<T>(entity: Type<T>, query: FilterQuery<T>): Promise<T[]>;
|
|
43
|
+
protected findOneDocument<T>(entity: Type<T>, query: FilterQuery<T>): Promise<T | undefined>;
|
|
44
|
+
protected createManyDocuments<T>(entity: Type<T>, data: Partial<T>[]): Promise<T[]>;
|
|
45
|
+
protected createOneDocument<T>(entity: Type<T>, data: Partial<T>): Promise<T>;
|
|
46
|
+
protected updateManyDocuments<T>(entity: Type<T>, query: FilterQuery<T>, data: Partial<T>): Promise<UpdateResult>;
|
|
47
|
+
protected updateOneDocument<T>(entity: Type<T>, query: FilterQuery<T>, data: Partial<T>): Promise<UpdateResult>;
|
|
48
|
+
protected deleteManyDocuments<T>(entity: Type<T>, ids: string[]): Promise<DeleteResult>;
|
|
49
|
+
protected deleteOneDocument<T>(entity: Type<T>, id: string): Promise<DeleteResult>;
|
|
42
50
|
protected buildInstance(document: Entity): Entity;
|
|
43
51
|
protected handleAbilityPredicate(document: Entity): void;
|
|
44
52
|
protected handleDuplicateKeyError(error: any): void;
|
|
@@ -3,51 +3,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BaseService = void 0;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
const builder_pattern_1 = require("builder-pattern");
|
|
6
|
+
const dynamic_api_global_state_service_1 = require("../dynamic-api-global-state/dynamic-api-global-state.service");
|
|
6
7
|
class BaseService {
|
|
7
8
|
constructor(model) {
|
|
8
9
|
this.model = model;
|
|
9
10
|
this.callbackMethods = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (this.passwordField && typeof update[this.passwordField] !== 'undefined') {
|
|
19
|
-
throw new common_1.BadRequestException(`${this.passwordField} cannot be updated using this method because it is hashed. Use reset password process instead.`);
|
|
20
|
-
}
|
|
21
|
-
const updated = await this.model.findOneAndUpdate({ _id: id }, update, { new: true }).lean().exec();
|
|
22
|
-
if (!updated) {
|
|
23
|
-
this.handleDocumentNotFound();
|
|
24
|
-
}
|
|
25
|
-
return this.buildInstance(updated);
|
|
26
|
-
},
|
|
11
|
+
findManyDocuments: this.findManyDocuments.bind(this),
|
|
12
|
+
findOneDocument: this.findOneDocument.bind(this),
|
|
13
|
+
createManyDocuments: this.createManyDocuments.bind(this),
|
|
14
|
+
createOneDocument: this.createOneDocument.bind(this),
|
|
15
|
+
updateManyDocuments: this.updateManyDocuments.bind(this),
|
|
16
|
+
updateOneDocument: this.updateOneDocument.bind(this),
|
|
17
|
+
deleteManyDocuments: this.deleteManyDocuments.bind(this),
|
|
18
|
+
deleteOneDocument: this.deleteOneDocument.bind(this),
|
|
27
19
|
};
|
|
28
20
|
}
|
|
29
21
|
get isSoftDeletable() {
|
|
30
22
|
const paths = Object.getOwnPropertyNames(this.model.schema.paths);
|
|
31
23
|
return paths.includes('deletedAt') && paths.includes('isDeleted');
|
|
32
24
|
}
|
|
33
|
-
async
|
|
34
|
-
const documents = await this.
|
|
35
|
-
.find(conditions)
|
|
36
|
-
.lean()
|
|
37
|
-
.exec();
|
|
25
|
+
async findManyDocumentsWithAbilityPredicate(conditions = {}) {
|
|
26
|
+
const documents = await this.findManyDocuments(this.entity, conditions);
|
|
38
27
|
if (this.abilityPredicate) {
|
|
39
28
|
documents.forEach((d) => this.handleAbilityPredicate(d));
|
|
40
29
|
}
|
|
41
30
|
return documents;
|
|
42
31
|
}
|
|
43
|
-
async
|
|
44
|
-
const document = await this.
|
|
45
|
-
.findOne({
|
|
32
|
+
async findOneDocumentWithAbilityPredicate(_id, conditions = {}) {
|
|
33
|
+
const document = await this.findOneDocument(this.entity, {
|
|
46
34
|
...(_id ? { _id } : {}),
|
|
47
35
|
...conditions,
|
|
48
|
-
})
|
|
49
|
-
.lean()
|
|
50
|
-
.exec();
|
|
36
|
+
});
|
|
51
37
|
if (!document) {
|
|
52
38
|
throw new common_1.BadRequestException('Document not found');
|
|
53
39
|
}
|
|
@@ -56,6 +42,50 @@ class BaseService {
|
|
|
56
42
|
}
|
|
57
43
|
return document;
|
|
58
44
|
}
|
|
45
|
+
async findManyDocuments(entity, query) {
|
|
46
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
47
|
+
return model.find(query).lean().exec();
|
|
48
|
+
}
|
|
49
|
+
async findOneDocument(entity, query) {
|
|
50
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
51
|
+
return model.findOne(query).lean().exec();
|
|
52
|
+
}
|
|
53
|
+
async createManyDocuments(entity, data) {
|
|
54
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
55
|
+
return model.create(data);
|
|
56
|
+
}
|
|
57
|
+
async createOneDocument(entity, data) {
|
|
58
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
59
|
+
return model.create(data);
|
|
60
|
+
}
|
|
61
|
+
async updateManyDocuments(entity, query, data) {
|
|
62
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
63
|
+
return model.updateMany(query, data).exec();
|
|
64
|
+
}
|
|
65
|
+
async updateOneDocument(entity, query, data) {
|
|
66
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
67
|
+
return model.updateOne(query, data).exec();
|
|
68
|
+
}
|
|
69
|
+
async deleteManyDocuments(entity, ids) {
|
|
70
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
71
|
+
const paths = Object.getOwnPropertyNames(model.schema.paths);
|
|
72
|
+
const isSoftDeletable = paths.includes('deletedAt') && paths.includes('isDeleted');
|
|
73
|
+
if (isSoftDeletable) {
|
|
74
|
+
const result = await model.updateMany({ _id: { $in: ids } }, { isDeleted: true, deletedAt: new Date() }).exec();
|
|
75
|
+
return { deletedCount: result.modifiedCount };
|
|
76
|
+
}
|
|
77
|
+
return model.deleteMany({ _id: { $in: ids } }).exec();
|
|
78
|
+
}
|
|
79
|
+
async deleteOneDocument(entity, id) {
|
|
80
|
+
const model = await dynamic_api_global_state_service_1.DynamicApiGlobalStateService.getEntityModel(entity);
|
|
81
|
+
const paths = Object.getOwnPropertyNames(model.schema.paths);
|
|
82
|
+
const isSoftDeletable = paths.includes('deletedAt') && paths.includes('isDeleted');
|
|
83
|
+
if (isSoftDeletable) {
|
|
84
|
+
const result = await model.updateOne({ _id: id }, { isDeleted: true, deletedAt: new Date() }).exec();
|
|
85
|
+
return { deletedCount: result.modifiedCount };
|
|
86
|
+
}
|
|
87
|
+
return model.deleteOne({ _id: id }).exec();
|
|
88
|
+
}
|
|
59
89
|
buildInstance(document) {
|
|
60
90
|
const { _id, id, __v, ...rest } = document;
|
|
61
91
|
return (0, builder_pattern_1.Builder)(this.entity, rest)
|
|
@@ -22,18 +22,20 @@
|
|
|
22
22
|
/// <reference types="mongoose/types/validation" />
|
|
23
23
|
/// <reference types="mongoose/types/virtuals" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
|
-
import {
|
|
25
|
+
import { Type } from '@nestjs/common';
|
|
26
|
+
import { Model, Schema } from 'mongoose';
|
|
26
27
|
import { BehaviorSubject } from 'rxjs';
|
|
27
28
|
import { DynamicApiGlobalState } from '../../interfaces';
|
|
28
29
|
export declare class DynamicApiGlobalStateService {
|
|
29
30
|
private static readonly initialized$;
|
|
30
31
|
private static readonly entitySchemas$;
|
|
31
|
-
private
|
|
32
|
+
private static connection;
|
|
33
|
+
private static _;
|
|
32
34
|
private readonly defaultGlobalState;
|
|
33
35
|
constructor(initialGlobalState?: Partial<DynamicApiGlobalState>);
|
|
34
36
|
static onInitialized(): BehaviorSubject<boolean>;
|
|
35
|
-
static addEntitySchema<T = any>(
|
|
36
|
-
static
|
|
37
|
+
static addEntitySchema<T = any>(entity: Type<T>, schema: Schema<T>): void;
|
|
38
|
+
static getEntityModel<T = any>(entity: Type<T>): Promise<Model<T, {}, {}, {}, import("mongoose").IfAny<T, any, import("mongoose").Document<unknown, {}, T> & import("mongoose").Require_id<T>>, any>>;
|
|
37
39
|
set<V>([target, value]: ([keyof DynamicApiGlobalState, value: V] | ['partial', Partial<DynamicApiGlobalState>])): void;
|
|
38
40
|
get<T = DynamicApiGlobalState>(key?: keyof DynamicApiGlobalState): T;
|
|
39
41
|
private updateState;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DynamicApiGlobalStateService = void 0;
|
|
4
|
+
const mongoose_1 = require("mongoose");
|
|
4
5
|
const rxjs_1 = require("rxjs");
|
|
5
6
|
class DynamicApiGlobalStateService {
|
|
6
7
|
constructor(initialGlobalState) {
|
|
7
|
-
this._ = {};
|
|
8
8
|
this.defaultGlobalState = {
|
|
9
|
+
uri: '',
|
|
9
10
|
connectionName: 'dynamic-api-connection',
|
|
10
11
|
isGlobalCacheEnabled: true,
|
|
11
12
|
isAuthEnabled: false,
|
|
@@ -29,37 +30,41 @@ class DynamicApiGlobalStateService {
|
|
|
29
30
|
],
|
|
30
31
|
},
|
|
31
32
|
};
|
|
32
|
-
Object.assign(
|
|
33
|
+
Object.assign(DynamicApiGlobalStateService._, this.defaultGlobalState, initialGlobalState);
|
|
33
34
|
}
|
|
34
35
|
static onInitialized() {
|
|
35
36
|
return this.initialized$;
|
|
36
37
|
}
|
|
37
|
-
static addEntitySchema(
|
|
38
|
+
static addEntitySchema(entity, schema) {
|
|
38
39
|
const entitySchemas = this.entitySchemas$.value;
|
|
39
|
-
entitySchemas[name] = schema;
|
|
40
|
+
entitySchemas[entity.name] = schema;
|
|
40
41
|
this.entitySchemas$.next(entitySchemas);
|
|
41
42
|
}
|
|
42
|
-
static
|
|
43
|
-
const schema = this.entitySchemas$.value[name];
|
|
43
|
+
static async getEntityModel(entity) {
|
|
44
|
+
const schema = this.entitySchemas$.value[entity.name];
|
|
44
45
|
if (!schema) {
|
|
45
|
-
throw new Error(`Entity schema for "${name}" not found`);
|
|
46
|
+
throw new Error(`Entity schema for "${entity.name}" not found`);
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
if (!this.connection) {
|
|
49
|
+
this.connection =
|
|
50
|
+
await (0, mongoose_1.createConnection)(this._.uri, { retryWrites: true, writeConcern: { w: 'majority' } }).asPromise();
|
|
51
|
+
}
|
|
52
|
+
return this.connection.model(entity.name, schema);
|
|
48
53
|
}
|
|
49
54
|
set([target, value]) {
|
|
50
55
|
if (target === 'partial') {
|
|
51
|
-
Object.assign(
|
|
56
|
+
Object.assign(DynamicApiGlobalStateService._, value);
|
|
52
57
|
}
|
|
53
58
|
else {
|
|
54
|
-
Object.assign(
|
|
59
|
+
Object.assign(DynamicApiGlobalStateService._, { [target]: value });
|
|
55
60
|
}
|
|
56
61
|
this.updateState();
|
|
57
62
|
}
|
|
58
63
|
get(key) {
|
|
59
|
-
return (key ?
|
|
64
|
+
return (key ? DynamicApiGlobalStateService._[key] : DynamicApiGlobalStateService._);
|
|
60
65
|
}
|
|
61
66
|
updateState() {
|
|
62
|
-
if (
|
|
67
|
+
if (DynamicApiGlobalStateService._.initialized && !DynamicApiGlobalStateService.initialized$.value) {
|
|
63
68
|
DynamicApiGlobalStateService.initialized$.next(true);
|
|
64
69
|
}
|
|
65
70
|
}
|
|
@@ -67,3 +72,4 @@ class DynamicApiGlobalStateService {
|
|
|
67
72
|
exports.DynamicApiGlobalStateService = DynamicApiGlobalStateService;
|
|
68
73
|
DynamicApiGlobalStateService.initialized$ = new rxjs_1.BehaviorSubject(false);
|
|
69
74
|
DynamicApiGlobalStateService.entitySchemas$ = new rxjs_1.BehaviorSubject({});
|
|
75
|
+
DynamicApiGlobalStateService._ = {};
|
package/src/version.json
CHANGED