@koalarx/nest 1.6.3 → 1.7.0
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/core/database/entity.base.d.ts +6 -1
- package/core/database/entity.base.js +9 -1
- package/core/database/repository.base.d.ts +1 -2
- package/core/database/repository.base.js +30 -27
- package/core/mapping/auto-mapping-list.d.ts +1 -0
- package/core/mapping/auto-mapping-list.js +26 -4
- package/core/utils/list.js +0 -1
- package/package.json +1 -1
- package/test/repositories/in-memory-base.repository.d.ts +3 -3
- package/test/repositories/in-memory-base.repository.js +18 -9
- package/tsconfig.lib.tsbuildinfo +1 -1
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { IComparable, IComparableId } from '../utils/interfaces/icomparable';
|
|
2
2
|
import { Overwrite } from '..';
|
|
3
|
+
export declare enum EntityActionType {
|
|
4
|
+
create = 1,
|
|
5
|
+
update = 2
|
|
6
|
+
}
|
|
3
7
|
export type EntityProps<T extends IComparable<T>> = Overwrite<Omit<{
|
|
4
8
|
[K in keyof T as T[K] extends Function ? never : K]: T[K];
|
|
5
|
-
}, '_id'>, {
|
|
9
|
+
}, '_id' | '_action'>, {
|
|
6
10
|
id?: T extends {
|
|
7
11
|
id: infer U;
|
|
8
12
|
} ? U : never;
|
|
9
13
|
}>;
|
|
10
14
|
export declare abstract class EntityBase<T extends IComparable<T>> implements IComparable<T> {
|
|
11
15
|
_id: IComparableId;
|
|
16
|
+
_action: EntityActionType;
|
|
12
17
|
automap(props?: EntityProps<T>): void;
|
|
13
18
|
equals(obj: EntityBase<T>): boolean;
|
|
14
19
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EntityBase = void 0;
|
|
3
|
+
exports.EntityBase = exports.EntityActionType = void 0;
|
|
4
4
|
const auto_mapping_list_1 = require("../mapping/auto-mapping-list");
|
|
5
5
|
const list_1 = require("../utils/list");
|
|
6
|
+
var EntityActionType;
|
|
7
|
+
(function (EntityActionType) {
|
|
8
|
+
EntityActionType[EntityActionType["create"] = 1] = "create";
|
|
9
|
+
EntityActionType[EntityActionType["update"] = 2] = "update";
|
|
10
|
+
})(EntityActionType || (exports.EntityActionType = EntityActionType = {}));
|
|
6
11
|
class EntityBase {
|
|
7
12
|
_id;
|
|
13
|
+
_action = EntityActionType.create;
|
|
8
14
|
automap(props) {
|
|
9
15
|
if (props) {
|
|
10
16
|
for (const key of Object.keys(props)) {
|
|
@@ -18,6 +24,7 @@ class EntityBase {
|
|
|
18
24
|
if (this[key].entityType) {
|
|
19
25
|
value = value.map((item) => {
|
|
20
26
|
const entity = new this[key].entityType();
|
|
27
|
+
entity._action = this._action;
|
|
21
28
|
entity.automap(item);
|
|
22
29
|
return entity;
|
|
23
30
|
});
|
|
@@ -26,6 +33,7 @@ class EntityBase {
|
|
|
26
33
|
}
|
|
27
34
|
else if (EntityOnPropKey) {
|
|
28
35
|
const entity = new EntityOnPropKey();
|
|
36
|
+
entity._action = this._action;
|
|
29
37
|
entity.automap(props[key]);
|
|
30
38
|
this[key] = entity;
|
|
31
39
|
}
|
|
@@ -24,8 +24,7 @@ export declare abstract class RepositoryBase<TEntity extends EntityBase<TEntity>
|
|
|
24
24
|
protected findUnique<T>(where: T): Promise<any>;
|
|
25
25
|
protected findMany<T>(where: T, pagination?: PaginationDto): Promise<any>;
|
|
26
26
|
protected findManyAndCount<T>(where: T, pagination?: PaginationDto): Promise<ListResponse<TEntity>>;
|
|
27
|
-
protected
|
|
28
|
-
protected edit<TWhere = any>(entity: TEntity, updateWhere?: TWhere): Promise<any>;
|
|
27
|
+
protected saveChanges<TWhere = any>(entity: TEntity, updateWhere?: TWhere): any;
|
|
29
28
|
protected remove<TWhere = any>(where: TWhere, externalServices?: Promise<any>): Promise<any>;
|
|
30
29
|
private listToRelationActionList;
|
|
31
30
|
private entityToPrisma;
|
|
@@ -72,26 +72,27 @@ class RepositoryBase {
|
|
|
72
72
|
}
|
|
73
73
|
return { items: [], count };
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
const prismaEntity = this.entityToPrisma(entity
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
75
|
+
saveChanges(entity, updateWhere) {
|
|
76
|
+
const prismaEntity = this.entityToPrisma(entity);
|
|
77
|
+
if (entity._action === entity_base_1.EntityActionType.create) {
|
|
78
|
+
return this.context().create({
|
|
79
|
+
data: prismaEntity,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return this.withTransaction((client) => this.context(client)
|
|
84
|
+
.update({
|
|
85
|
+
where: updateWhere ?? { id: entity._id },
|
|
86
|
+
data: prismaEntity,
|
|
87
|
+
})
|
|
88
|
+
.then(() => {
|
|
89
|
+
const { relationUpdates, relationDeletes } = this.listToRelationActionList(entity);
|
|
90
|
+
return Promise.all([
|
|
91
|
+
...relationUpdates.map((relation) => client[relation.modelName].updateMany(relation.schema)),
|
|
92
|
+
...relationDeletes.map((relation) => client[relation.modelName].deleteMany(relation.schema)),
|
|
93
|
+
]);
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
95
96
|
}
|
|
96
97
|
async remove(where, externalServices) {
|
|
97
98
|
const entity = await this.findUnique(where);
|
|
@@ -126,7 +127,7 @@ class RepositoryBase {
|
|
|
126
127
|
modelName: (0, string_1.toCamelCase)(modelName),
|
|
127
128
|
schema: {
|
|
128
129
|
where: { id: item._id },
|
|
129
|
-
data: this.entityToPrisma(item
|
|
130
|
+
data: this.entityToPrisma(item),
|
|
130
131
|
},
|
|
131
132
|
});
|
|
132
133
|
});
|
|
@@ -135,10 +136,10 @@ class RepositoryBase {
|
|
|
135
136
|
});
|
|
136
137
|
return { relationUpdates, relationDeletes };
|
|
137
138
|
}
|
|
138
|
-
entityToPrisma(entity
|
|
139
|
+
entityToPrisma(entity) {
|
|
139
140
|
const prismaSchema = {};
|
|
140
141
|
Object.keys(entity)
|
|
141
|
-
.filter((key) => !['id', '_id'].includes(key))
|
|
142
|
+
.filter((key) => !['id', '_id', '_action'].includes(key))
|
|
142
143
|
.filter((key) => !(entity[key] instanceof Function))
|
|
143
144
|
.forEach((key) => {
|
|
144
145
|
if (entity[key] instanceof list_1.List) {
|
|
@@ -146,16 +147,17 @@ class RepositoryBase {
|
|
|
146
147
|
prismaSchema[key] = {
|
|
147
148
|
createMany: {
|
|
148
149
|
data: entity[key].toArray('added').map((item) => {
|
|
149
|
-
return this.entityToPrisma(item
|
|
150
|
+
return this.entityToPrisma(item);
|
|
150
151
|
}),
|
|
151
152
|
},
|
|
152
153
|
};
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
else if (entity[key] instanceof entity_base_1.EntityBase) {
|
|
156
|
-
prismaSchema[key] =
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
prismaSchema[key] =
|
|
158
|
+
entity[key]._action === entity_base_1.EntityActionType.create
|
|
159
|
+
? { create: this.entityToPrisma(entity[key]) }
|
|
160
|
+
: { update: this.entityToPrisma(entity[key]) };
|
|
159
161
|
}
|
|
160
162
|
else {
|
|
161
163
|
prismaSchema[key] = entity[key];
|
|
@@ -183,6 +185,7 @@ class RepositoryBase {
|
|
|
183
185
|
}
|
|
184
186
|
createEntity(data) {
|
|
185
187
|
const entity = new this._modelName();
|
|
188
|
+
entity._action = entity_base_1.EntityActionType.update;
|
|
186
189
|
entity.automap(data);
|
|
187
190
|
return entity;
|
|
188
191
|
}
|
|
@@ -21,5 +21,6 @@ export declare class AutoMappingList {
|
|
|
21
21
|
} | null | undefined;
|
|
22
22
|
static getTargets(source: Type<any>): Type<any>[];
|
|
23
23
|
static addMappedProp(source: Type<any>, propName: string): void;
|
|
24
|
+
static addExtendedPropsIntoSubClass(source: Type<any>): void;
|
|
24
25
|
}
|
|
25
26
|
export {};
|
|
@@ -11,17 +11,23 @@ class AutoMappingList {
|
|
|
11
11
|
this._mappingProfileList.add(new auto_mapping_context_1.AutoMappingContext(source, target, forMember));
|
|
12
12
|
this._mappedPropList.add(new auto_mapping_class_context_1.AutoMappingClassContext(source));
|
|
13
13
|
this._mappedPropList.add(new auto_mapping_class_context_1.AutoMappingClassContext(target));
|
|
14
|
+
this.addExtendedPropsIntoSubClass(source);
|
|
15
|
+
this.addExtendedPropsIntoSubClass(target);
|
|
14
16
|
}
|
|
15
17
|
static get(source, target) {
|
|
16
18
|
return {
|
|
17
|
-
mapContext: this._mappingProfileList.find((mp) => mp.source === source
|
|
19
|
+
mapContext: this._mappingProfileList.find((mp) => (mp.source === source ||
|
|
20
|
+
Object.getPrototypeOf(mp.source.prototype.constructor) ===
|
|
21
|
+
source) &&
|
|
22
|
+
mp.target === target),
|
|
18
23
|
propSourceContext: this._mappedPropList.find((mp) => mp.source === source),
|
|
19
24
|
propTargetContext: this._mappedPropList.find((mp) => mp.source === target),
|
|
20
25
|
};
|
|
21
26
|
}
|
|
22
27
|
static getSourceByName(sourceName) {
|
|
23
|
-
return this._mappingProfileList.find((mp) => mp.source.name === sourceName
|
|
24
|
-
|
|
28
|
+
return this._mappingProfileList.find((mp) => mp.source.name === sourceName ||
|
|
29
|
+
Object.getPrototypeOf(mp.source.prototype.constructor).name ===
|
|
30
|
+
sourceName)?.source;
|
|
25
31
|
}
|
|
26
32
|
static getPropDefinitions(source, propName) {
|
|
27
33
|
return this._mappedPropList
|
|
@@ -30,7 +36,8 @@ class AutoMappingList {
|
|
|
30
36
|
}
|
|
31
37
|
static getTargets(source) {
|
|
32
38
|
return this._mappingProfileList
|
|
33
|
-
.filter((mp) => mp.source === source
|
|
39
|
+
.filter((mp) => mp.source === source ||
|
|
40
|
+
Object.getPrototypeOf(mp.source.prototype.constructor) === source)
|
|
34
41
|
.map((mp) => mp.target)
|
|
35
42
|
.toArray();
|
|
36
43
|
}
|
|
@@ -38,6 +45,10 @@ class AutoMappingList {
|
|
|
38
45
|
let mappedClass = this._mappedPropList.find((mp) => mp.source === source);
|
|
39
46
|
if (!mappedClass) {
|
|
40
47
|
mappedClass = new auto_mapping_class_context_1.AutoMappingClassContext(source);
|
|
48
|
+
const mappedExtendedClass = this._mappedPropList.find((mp) => mp.source === Object.getPrototypeOf(source.prototype.constructor));
|
|
49
|
+
if (mappedExtendedClass) {
|
|
50
|
+
mappedClass.props.setList(mappedExtendedClass.props.toArray());
|
|
51
|
+
}
|
|
41
52
|
this._mappedPropList.add(mappedClass);
|
|
42
53
|
}
|
|
43
54
|
const metadata = Reflect.getMetadata('design:type', source.prototype, propName);
|
|
@@ -51,5 +62,16 @@ class AutoMappingList {
|
|
|
51
62
|
compositionAction,
|
|
52
63
|
});
|
|
53
64
|
}
|
|
65
|
+
static addExtendedPropsIntoSubClass(source) {
|
|
66
|
+
const mappedExtendedClass = this._mappedPropList.find((mp) => mp.source === Object.getPrototypeOf(source.prototype.constructor));
|
|
67
|
+
if (mappedExtendedClass) {
|
|
68
|
+
const mappedClass = this._mappedPropList.find((mp) => mp.source === source);
|
|
69
|
+
if (mappedClass) {
|
|
70
|
+
mappedExtendedClass.props
|
|
71
|
+
.toArray()
|
|
72
|
+
.forEach((prop) => mappedClass.props.add(prop));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
54
76
|
}
|
|
55
77
|
exports.AutoMappingList = AutoMappingList;
|
package/core/utils/list.js
CHANGED
package/package.json
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PaginationDto } from '@koalarx/nest/core/dtos/pagination.dto';
|
|
2
|
-
import { CreatedRegistreResponseBase } from '../../core/controllers/created-registre-response.base';
|
|
3
2
|
import { ListResponseBase } from '../../core/controllers/list-response.base';
|
|
4
3
|
import { EntityBase } from '../../core/database/entity.base';
|
|
5
4
|
import { IComparableId } from '../../core/utils/interfaces/icomparable';
|
|
@@ -10,8 +9,9 @@ export declare abstract class InMemoryBaseRepository<TClass extends EntityBase<a
|
|
|
10
9
|
protected findById(id: IComparableId): Promise<TClass | null>;
|
|
11
10
|
protected findMany<T extends PaginationDto>(query: T, predicate?: (value: TClass, index: number, array: TClass[]) => unknown): Promise<TClass[]>;
|
|
12
11
|
protected findManyAndCount<T extends PaginationDto>(query: T, predicate?: (value: TClass, index: number, array: TClass[]) => unknown): Promise<ListResponseBase<TClass>>;
|
|
13
|
-
protected
|
|
14
|
-
|
|
12
|
+
protected saveChanges(item: TClass, updateWhere?: (item: TClass) => boolean): Promise<{
|
|
13
|
+
id: IComparableId;
|
|
14
|
+
} | undefined>;
|
|
15
15
|
protected remove(predicate: (value: TClass, index: number, obj: TClass[]) => unknown): Promise<void>;
|
|
16
16
|
private getNewId;
|
|
17
17
|
}
|
|
@@ -4,6 +4,7 @@ exports.InMemoryBaseRepository = void 0;
|
|
|
4
4
|
const query_params_1 = require("../../core/constants/query-params");
|
|
5
5
|
const array_1 = require("@koalarx/utils/operators/array");
|
|
6
6
|
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
const entity_base_1 = require("../../core/database/entity.base");
|
|
7
8
|
class InMemoryBaseRepository {
|
|
8
9
|
typeId;
|
|
9
10
|
items = [];
|
|
@@ -11,7 +12,11 @@ class InMemoryBaseRepository {
|
|
|
11
12
|
this.typeId = typeId;
|
|
12
13
|
}
|
|
13
14
|
async findById(id) {
|
|
14
|
-
|
|
15
|
+
const entity = this.items.find((item) => item._id === id) ?? null;
|
|
16
|
+
if (entity) {
|
|
17
|
+
entity._action = entity_base_1.EntityActionType.update;
|
|
18
|
+
}
|
|
19
|
+
return entity;
|
|
15
20
|
}
|
|
16
21
|
async findMany(query, predicate) {
|
|
17
22
|
const page = query.page ?? query_params_1.QUERY_FILTER_PARAMS.page;
|
|
@@ -19,7 +24,11 @@ class InMemoryBaseRepository {
|
|
|
19
24
|
return (0, array_1.klArray)(predicate ? this.items.filter(predicate) : this.items)
|
|
20
25
|
.orderBy(query.orderBy ?? '', query.direction === 'desc')
|
|
21
26
|
.getValue()
|
|
22
|
-
.slice(page * limit, (page + 1) * limit)
|
|
27
|
+
.slice(page * limit, (page + 1) * limit)
|
|
28
|
+
.map((item) => {
|
|
29
|
+
item._action = entity_base_1.EntityActionType.update;
|
|
30
|
+
return item;
|
|
31
|
+
});
|
|
23
32
|
}
|
|
24
33
|
async findManyAndCount(query, predicate) {
|
|
25
34
|
const items = await this.findMany(query, predicate);
|
|
@@ -28,13 +37,13 @@ class InMemoryBaseRepository {
|
|
|
28
37
|
count: items.length,
|
|
29
38
|
};
|
|
30
39
|
}
|
|
31
|
-
async
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
async saveChanges(item, updateWhere) {
|
|
41
|
+
if (item._action === entity_base_1.EntityActionType.create) {
|
|
42
|
+
const id = this.typeId === 'number' ? this.getNewId() : (0, node_crypto_1.randomUUID)();
|
|
43
|
+
item.automap({ ...item, id });
|
|
44
|
+
this.items.push(item);
|
|
45
|
+
return { id: item._id };
|
|
46
|
+
}
|
|
38
47
|
const predicate = updateWhere ?? ((itemDB) => itemDB.equals(item));
|
|
39
48
|
const itemIndex = this.items.findIndex(predicate);
|
|
40
49
|
if (itemIndex > -1) {
|