@koalarx/nest 1.18.13 → 1.18.14
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.
|
@@ -19,6 +19,15 @@ export declare abstract class RepositoryBase<TEntity extends EntityBase<TEntity>
|
|
|
19
19
|
private readonly _modelName;
|
|
20
20
|
private readonly _include?;
|
|
21
21
|
constructor({ context, modelName, include, }: RepositoryInitProps<TEntity, TContext>);
|
|
22
|
+
private listRelationEntities;
|
|
23
|
+
private listToRelationActionList;
|
|
24
|
+
private entityToPrisma;
|
|
25
|
+
private findManySchema;
|
|
26
|
+
private createEntity;
|
|
27
|
+
private orphanRemoval;
|
|
28
|
+
private getIdPropName;
|
|
29
|
+
private getInclude;
|
|
30
|
+
private persistRelations;
|
|
22
31
|
protected context(transactionalClient?: TContext): TContext[TModelKey];
|
|
23
32
|
protected findById(id: IComparableId): Promise<TEntity | null>;
|
|
24
33
|
protected findFirst<T>(where: T): Promise<TEntity | null>;
|
|
@@ -29,13 +38,6 @@ export declare abstract class RepositoryBase<TEntity extends EntityBase<TEntity>
|
|
|
29
38
|
protected saveMany<TWhere = any>(entities: TEntity[], updateWhere?: TWhere): Promise<void>;
|
|
30
39
|
protected remove<TWhere = any>(where: TWhere, externalServices?: Promise<any>, notCascadeEntityProps?: Array<keyof TEntity>): Promise<any>;
|
|
31
40
|
protected removeMany<TWhere = any>(where: TWhere, externalServices?: Promise<any>, notCascadeEntityProps?: Array<keyof TEntity>): Promise<void>;
|
|
32
|
-
private listToRelationActionList;
|
|
33
|
-
private entityToPrisma;
|
|
34
|
-
private findManySchema;
|
|
35
|
-
private createEntity;
|
|
36
|
-
private orphanRemoval;
|
|
37
|
-
private getIdPropName;
|
|
38
|
-
private getInclude;
|
|
39
41
|
withTransaction(fn: (prisma: TContext) => Promise<any>): Promise<any>;
|
|
40
42
|
}
|
|
41
43
|
export {};
|
|
@@ -15,6 +15,168 @@ class RepositoryBase {
|
|
|
15
15
|
this._modelName = modelName;
|
|
16
16
|
this._include = include;
|
|
17
17
|
}
|
|
18
|
+
listRelationEntities(entity) {
|
|
19
|
+
const relationEntities = [];
|
|
20
|
+
Object.keys(entity).forEach((key) => {
|
|
21
|
+
if (entity[key] instanceof list_1.List) {
|
|
22
|
+
const list = entity[key];
|
|
23
|
+
list.toArray('added').forEach((item) => {
|
|
24
|
+
relationEntities.push(item);
|
|
25
|
+
relationEntities.push(...this.listRelationEntities(item));
|
|
26
|
+
});
|
|
27
|
+
list.toArray('updated').forEach((item) => {
|
|
28
|
+
relationEntities.push(item);
|
|
29
|
+
relationEntities.push(...this.listRelationEntities(item));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else if (entity[key] instanceof entity_base_1.EntityBase) {
|
|
33
|
+
relationEntities.push(entity[key]);
|
|
34
|
+
relationEntities.push(...this.listRelationEntities(entity[key]));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return relationEntities;
|
|
38
|
+
}
|
|
39
|
+
listToRelationActionList(entity) {
|
|
40
|
+
const relationCreates = [];
|
|
41
|
+
const relationUpdates = [];
|
|
42
|
+
const relationDeletes = [];
|
|
43
|
+
Object.keys(entity).forEach((key) => {
|
|
44
|
+
if (entity[key] instanceof list_1.List) {
|
|
45
|
+
const list = entity[key];
|
|
46
|
+
const modelName = list.entityType?.name;
|
|
47
|
+
const parentModelName = entity.constructor.name;
|
|
48
|
+
if (modelName) {
|
|
49
|
+
list.toArray('removed').forEach((item) => {
|
|
50
|
+
relationDeletes.push({
|
|
51
|
+
modelName: (0, KlString_1.toCamelCase)(modelName),
|
|
52
|
+
schema: { where: { id: item._id } },
|
|
53
|
+
relations: [],
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
list.toArray('added').forEach((item) => {
|
|
57
|
+
relationCreates.push({
|
|
58
|
+
modelName: (0, KlString_1.toCamelCase)(modelName),
|
|
59
|
+
schema: {
|
|
60
|
+
data: {
|
|
61
|
+
...this.entityToPrisma(item),
|
|
62
|
+
[(0, KlString_1.toCamelCase)(parentModelName)]: {
|
|
63
|
+
connect: {
|
|
64
|
+
[this.getIdPropName(entity)]: entity[this.getIdPropName(entity)],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
relations: this.listRelationEntities(item),
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
list.toArray('updated').forEach((item) => {
|
|
73
|
+
relationUpdates.push({
|
|
74
|
+
modelName: (0, KlString_1.toCamelCase)(modelName),
|
|
75
|
+
schema: {
|
|
76
|
+
where: { id: item._id },
|
|
77
|
+
data: this.entityToPrisma(item),
|
|
78
|
+
},
|
|
79
|
+
relations: this.listRelationEntities(item),
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return { relationCreates, relationUpdates, relationDeletes };
|
|
86
|
+
}
|
|
87
|
+
entityToPrisma(entity) {
|
|
88
|
+
const prismaSchema = {};
|
|
89
|
+
Object.keys(entity)
|
|
90
|
+
.filter((key) => !['id', '_id', '_action'].includes(key))
|
|
91
|
+
.filter((key) => !(entity[key] instanceof Function || entity[key] instanceof list_1.List))
|
|
92
|
+
.forEach((key) => {
|
|
93
|
+
if (entity[key] instanceof entity_base_1.EntityBase) {
|
|
94
|
+
if (entity[key]._action === entity_base_1.EntityActionType.create) {
|
|
95
|
+
if (entity[key][this.getIdPropName()]) {
|
|
96
|
+
prismaSchema[key] = {
|
|
97
|
+
connectOrCreate: {
|
|
98
|
+
where: {
|
|
99
|
+
[this.getIdPropName()]: entity[key][this.getIdPropName()],
|
|
100
|
+
},
|
|
101
|
+
create: this.entityToPrisma(entity[key]),
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
prismaSchema[key] = {
|
|
107
|
+
create: this.entityToPrisma(entity[key]),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
prismaSchema[key] = {
|
|
113
|
+
update: this.entityToPrisma(entity[key]),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
prismaSchema[key] = entity[key];
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return prismaSchema;
|
|
122
|
+
}
|
|
123
|
+
findManySchema(where, pagination) {
|
|
124
|
+
return {
|
|
125
|
+
include: this.getInclude(),
|
|
126
|
+
where,
|
|
127
|
+
orderBy: pagination?.generateOrderBy(),
|
|
128
|
+
skip: pagination?.skip(),
|
|
129
|
+
take: (pagination?.limit ?? 0) > 0 ? pagination?.limit : undefined,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
createEntity(data) {
|
|
133
|
+
const entity = new this._modelName();
|
|
134
|
+
entity._action = entity_base_1.EntityActionType.update;
|
|
135
|
+
entity.automap(data);
|
|
136
|
+
return entity;
|
|
137
|
+
}
|
|
138
|
+
orphanRemoval(client, entity) {
|
|
139
|
+
const where = {};
|
|
140
|
+
Object.keys(entity)
|
|
141
|
+
.filter((key) => key === 'id' || key.includes('Id'))
|
|
142
|
+
.forEach((key) => (where[key] = entity[key]));
|
|
143
|
+
return client[(0, KlString_1.toCamelCase)(entity.constructor.name)].delete({ where });
|
|
144
|
+
}
|
|
145
|
+
getIdPropName(entity) {
|
|
146
|
+
return (Reflect.getMetadata('entity:id', entity ? entity.constructor.prototype : this._modelName.prototype) ?? 'id');
|
|
147
|
+
}
|
|
148
|
+
getInclude(include) {
|
|
149
|
+
include = include ?? this._include ?? {};
|
|
150
|
+
const result = {};
|
|
151
|
+
Object.keys(include).forEach((key) => {
|
|
152
|
+
if (typeof include[key] === 'boolean') {
|
|
153
|
+
result[key] = include[key];
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
result[key] = {
|
|
157
|
+
include: this.getInclude(include[key]),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
persistRelations(transaction, entity) {
|
|
164
|
+
const { relationCreates, relationUpdates, relationDeletes } = this.listToRelationActionList(entity);
|
|
165
|
+
return Promise.all([
|
|
166
|
+
...relationCreates.map((relationCreate) => transaction[relationCreate.modelName]
|
|
167
|
+
.create(relationCreate.schema)
|
|
168
|
+
.then((response) => {
|
|
169
|
+
return Promise.all(relationCreate.relations.map((relation) => {
|
|
170
|
+
const relationEntity = entity[(0, KlString_1.toCamelCase)(relation.constructor.name)];
|
|
171
|
+
relationEntity[this.getIdPropName(relationEntity)] =
|
|
172
|
+
response[this.getIdPropName(relationEntity)];
|
|
173
|
+
return this.persistRelations(transaction, relationEntity);
|
|
174
|
+
}));
|
|
175
|
+
})),
|
|
176
|
+
...relationUpdates.map((relation) => transaction[relation.modelName].update(relation.schema)),
|
|
177
|
+
...relationDeletes.map((relation) => this.removeMany(relation.schema)),
|
|
178
|
+
]);
|
|
179
|
+
}
|
|
18
180
|
context(transactionalClient) {
|
|
19
181
|
const modelName = this._modelName.name;
|
|
20
182
|
if (!modelName)
|
|
@@ -80,12 +242,17 @@ class RepositoryBase {
|
|
|
80
242
|
async saveChanges(entity, updateWhere) {
|
|
81
243
|
const prismaEntity = this.entityToPrisma(entity);
|
|
82
244
|
if (entity._action === entity_base_1.EntityActionType.create) {
|
|
83
|
-
return this.context()
|
|
245
|
+
return this.withTransaction((client) => this.context(client)
|
|
84
246
|
.create({
|
|
85
247
|
data: prismaEntity,
|
|
86
248
|
include: this.getInclude(),
|
|
87
249
|
})
|
|
88
|
-
.then((response) =>
|
|
250
|
+
.then((response) => {
|
|
251
|
+
entity[this.getIdPropName()] = response[this.getIdPropName()];
|
|
252
|
+
return this.persistRelations(client, entity).then(() => entity);
|
|
253
|
+
})).then((response) => this.findUnique({
|
|
254
|
+
[this.getIdPropName()]: response[this.getIdPropName()],
|
|
255
|
+
}));
|
|
89
256
|
}
|
|
90
257
|
else {
|
|
91
258
|
const where = updateWhere ?? { id: entity._id };
|
|
@@ -94,13 +261,7 @@ class RepositoryBase {
|
|
|
94
261
|
where,
|
|
95
262
|
data: prismaEntity,
|
|
96
263
|
})
|
|
97
|
-
.then(() =>
|
|
98
|
-
const { relationUpdates, relationDeletes } = this.listToRelationActionList(entity);
|
|
99
|
-
return Promise.all([
|
|
100
|
-
...relationUpdates.map((relation) => client[relation.modelName].updateMany(relation.schema)),
|
|
101
|
-
...relationDeletes.map((relation) => client[relation.modelName].deleteMany(relation.schema)),
|
|
102
|
-
]);
|
|
103
|
-
})).then(() => this.findUnique(where));
|
|
264
|
+
.then(() => this.persistRelations(client, entity))).then(() => this.findUnique(where));
|
|
104
265
|
}
|
|
105
266
|
}
|
|
106
267
|
async saveMany(entities, updateWhere) {
|
|
@@ -160,121 +321,6 @@ class RepositoryBase {
|
|
|
160
321
|
.then((response) => Promise.all(relationEntity.map((entity) => this.orphanRemoval(client, entity))).then(() => response));
|
|
161
322
|
}));
|
|
162
323
|
}
|
|
163
|
-
listToRelationActionList(entity) {
|
|
164
|
-
const relationUpdates = [];
|
|
165
|
-
const relationDeletes = [];
|
|
166
|
-
Object.keys(entity).forEach((key) => {
|
|
167
|
-
if (entity[key] instanceof list_1.List) {
|
|
168
|
-
const list = entity[key];
|
|
169
|
-
const modelName = list.entityType?.name;
|
|
170
|
-
if (modelName) {
|
|
171
|
-
list.toArray('removed').forEach((item) => {
|
|
172
|
-
relationDeletes.push({
|
|
173
|
-
modelName: (0, KlString_1.toCamelCase)(modelName),
|
|
174
|
-
schema: { where: { id: item._id } },
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
list.toArray('updated').forEach((item) => {
|
|
178
|
-
relationUpdates.push({
|
|
179
|
-
modelName: (0, KlString_1.toCamelCase)(modelName),
|
|
180
|
-
schema: {
|
|
181
|
-
where: { id: item._id },
|
|
182
|
-
data: this.entityToPrisma(item),
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
return { relationUpdates, relationDeletes };
|
|
190
|
-
}
|
|
191
|
-
entityToPrisma(entity) {
|
|
192
|
-
const prismaSchema = {};
|
|
193
|
-
Object.keys(entity)
|
|
194
|
-
.filter((key) => !['id', '_id', '_action'].includes(key))
|
|
195
|
-
.filter((key) => !(entity[key] instanceof Function))
|
|
196
|
-
.forEach((key) => {
|
|
197
|
-
if (entity[key] instanceof list_1.List) {
|
|
198
|
-
if (entity[key].toArray('added').length > 0) {
|
|
199
|
-
prismaSchema[key] = {
|
|
200
|
-
createMany: {
|
|
201
|
-
data: entity[key].toArray('added').map((item) => {
|
|
202
|
-
return this.entityToPrisma(item);
|
|
203
|
-
}),
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
else if (entity[key] instanceof entity_base_1.EntityBase) {
|
|
209
|
-
if (entity[key]._action === entity_base_1.EntityActionType.create) {
|
|
210
|
-
if (entity[key][this.getIdPropName()]) {
|
|
211
|
-
prismaSchema[key] = {
|
|
212
|
-
connectOrCreate: {
|
|
213
|
-
where: {
|
|
214
|
-
[this.getIdPropName()]: entity[key][this.getIdPropName()],
|
|
215
|
-
},
|
|
216
|
-
create: this.entityToPrisma(entity[key]),
|
|
217
|
-
},
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
prismaSchema[key] = {
|
|
222
|
-
create: this.entityToPrisma(entity[key]),
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
prismaSchema[key] = {
|
|
228
|
-
update: this.entityToPrisma(entity[key]),
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
prismaSchema[key] = entity[key];
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
return prismaSchema;
|
|
237
|
-
}
|
|
238
|
-
findManySchema(where, pagination) {
|
|
239
|
-
return {
|
|
240
|
-
include: this.getInclude(),
|
|
241
|
-
where,
|
|
242
|
-
orderBy: pagination?.generateOrderBy(),
|
|
243
|
-
skip: pagination?.skip(),
|
|
244
|
-
take: (pagination?.limit ?? 0) > 0 ? pagination?.limit : undefined,
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
createEntity(data) {
|
|
248
|
-
const entity = new this._modelName();
|
|
249
|
-
entity._action = entity_base_1.EntityActionType.update;
|
|
250
|
-
entity.automap(data);
|
|
251
|
-
return entity;
|
|
252
|
-
}
|
|
253
|
-
orphanRemoval(client, entity) {
|
|
254
|
-
const where = {};
|
|
255
|
-
Object.keys(entity)
|
|
256
|
-
.filter((key) => key === 'id' || key.includes('Id'))
|
|
257
|
-
.forEach((key) => (where[key] = entity[key]));
|
|
258
|
-
return client[(0, KlString_1.toCamelCase)(entity.constructor.name)].delete({ where });
|
|
259
|
-
}
|
|
260
|
-
getIdPropName() {
|
|
261
|
-
return Reflect.getMetadata('entity:id', this._modelName.prototype) ?? 'id';
|
|
262
|
-
}
|
|
263
|
-
getInclude(include) {
|
|
264
|
-
include = include ?? this._include ?? {};
|
|
265
|
-
const result = {};
|
|
266
|
-
Object.keys(include).forEach((key) => {
|
|
267
|
-
if (typeof include[key] === 'boolean') {
|
|
268
|
-
result[key] = include[key];
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
result[key] = {
|
|
272
|
-
include: this.getInclude(include[key]),
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
return result;
|
|
277
|
-
}
|
|
278
324
|
withTransaction(fn) {
|
|
279
325
|
return this._context.withTransaction(async (client) => {
|
|
280
326
|
return fn(new koala_global_vars_1.KoalaGlobalVars.dbTransactionContext(client));
|
|
@@ -5,6 +5,7 @@ export declare class AutoMappingService {
|
|
|
5
5
|
constructor(automappingProfile: AutoMappingProfile);
|
|
6
6
|
private getInstanceType;
|
|
7
7
|
map<S, T>(data: any, source: Type<S>, target: Type<T>): T;
|
|
8
|
+
private getTarget;
|
|
8
9
|
private mapNestedProp;
|
|
9
10
|
private mapListToArray;
|
|
10
11
|
private mapArrayToList;
|
|
@@ -82,7 +82,7 @@ let AutoMappingService = class AutoMappingService {
|
|
|
82
82
|
});
|
|
83
83
|
return mappedTarget;
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
getTarget(data, source) {
|
|
86
86
|
if (this.isPrimitiveType(data)) {
|
|
87
87
|
return data;
|
|
88
88
|
}
|
|
@@ -90,7 +90,10 @@ let AutoMappingService = class AutoMappingService {
|
|
|
90
90
|
if (targets.length === 0) {
|
|
91
91
|
throw new Error(`No mapping context found for ${source.name}`);
|
|
92
92
|
}
|
|
93
|
-
return
|
|
93
|
+
return targets[0];
|
|
94
|
+
}
|
|
95
|
+
mapNestedProp(data, source) {
|
|
96
|
+
return this.map(data, source.prototype.constructor, this.getTarget(data, source));
|
|
94
97
|
}
|
|
95
98
|
mapListToArray(value) {
|
|
96
99
|
return value.toArray().map((item) => {
|
|
@@ -102,7 +105,7 @@ let AutoMappingService = class AutoMappingService {
|
|
|
102
105
|
});
|
|
103
106
|
}
|
|
104
107
|
mapArrayToList(value, compositionType, onlySet = true) {
|
|
105
|
-
const list = new list_1.List(compositionType.prototype.constructor);
|
|
108
|
+
const list = new list_1.List(this.getTarget(value, compositionType.prototype.constructor));
|
|
106
109
|
const mappedValue = value.map((item) => this.mapNestedProp(item, compositionType.prototype.constructor) ?? {});
|
|
107
110
|
if (onlySet) {
|
|
108
111
|
list.setList(mappedValue);
|