@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) => this.createEntity(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
- mapNestedProp(data, source) {
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 this.map(data, source.prototype.constructor, targets[0]);
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koalarx/nest",
3
- "version": "1.18.13",
3
+ "version": "1.18.14",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",