@koalarx/nest 3.0.10 → 3.1.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.
@@ -2,34 +2,35 @@ import { Type } from '@nestjs/common';
2
2
  import { ListResponse } from '..';
3
3
  import { PaginationDto } from '../dtos/pagination.dto';
4
4
  import { IComparableId } from '../utils/interfaces/icomparable';
5
- import { List } from '../utils/list';
6
5
  import { EntityBase } from './entity.base';
7
6
  import { PrismaTransactionalClient } from './prisma-transactional-client';
8
- type RepositoryInclude<TEntity> = Omit<{
9
- [K in keyof TEntity as TEntity[K] extends Function ? never : K]?: boolean | (TEntity[K] extends List<infer U> ? RepositoryInclude<U> : RepositoryInclude<TEntity[K]>);
10
- }, '_id' | '_action'>;
11
7
  interface RepositoryInitProps<TEntity extends EntityBase<TEntity>, TContext extends PrismaTransactionalClient> {
12
8
  context: TContext;
13
9
  modelName: Type<TEntity>;
14
10
  transactionContext?: Type<TContext>;
15
- include?: RepositoryInclude<TEntity>;
11
+ deepIncludeLimit?: number;
16
12
  }
17
13
  export declare abstract class RepositoryBase<TEntity extends EntityBase<TEntity>, TContext extends PrismaTransactionalClient = PrismaTransactionalClient, TModelKey extends keyof TContext = keyof TContext> {
18
14
  protected _context: TContext;
19
15
  private readonly _modelName;
20
16
  private readonly _include?;
21
- constructor({ context, modelName, include, }: RepositoryInitProps<TEntity, TContext>);
17
+ private readonly _includeFindMany?;
18
+ private readonly deepIncludeLimit;
19
+ private deepIncludeCount;
20
+ private resetDeepIncludeCount;
21
+ constructor({ context, modelName, deepIncludeLimit, }: RepositoryInitProps<TEntity, TContext>);
22
22
  private getConnectPrismaSchemaForRelation;
23
+ private autogenerateIncludeSchema;
23
24
  private getSelectRootPrismaSchema;
24
25
  private getPropNameFromEntitySource;
25
26
  private listRelationEntities;
26
27
  private listToRelationActionList;
27
28
  private entityToPrisma;
29
+ private getInclude;
28
30
  private findManySchema;
29
31
  private createEntity;
30
32
  private orphanRemoval;
31
33
  private getIdPropName;
32
- private getInclude;
33
34
  private persistRelations;
34
35
  protected context(transactionalClient?: TContext): TContext[TModelKey];
35
36
  protected findById(id: IComparableId): Promise<TEntity | null>;
@@ -11,10 +11,19 @@ class RepositoryBase {
11
11
  _context;
12
12
  _modelName;
13
13
  _include;
14
- constructor({ context, modelName, include, }) {
14
+ _includeFindMany;
15
+ deepIncludeLimit;
16
+ deepIncludeCount = 0;
17
+ resetDeepIncludeCount() {
18
+ this.deepIncludeCount = 0;
19
+ }
20
+ constructor({ context, modelName, deepIncludeLimit, }) {
15
21
  this._context = context;
16
22
  this._modelName = modelName;
17
- this._include = include;
23
+ this.deepIncludeLimit = deepIncludeLimit ?? 5;
24
+ this._include = this.autogenerateIncludeSchema();
25
+ this.resetDeepIncludeCount();
26
+ this._includeFindMany = this.autogenerateIncludeSchema(true);
18
27
  }
19
28
  getConnectPrismaSchemaForRelation(entity, data) {
20
29
  const propIdName = this.getIdPropName(entity);
@@ -24,10 +33,43 @@ class RepositoryBase {
24
33
  },
25
34
  };
26
35
  }
36
+ autogenerateIncludeSchema(forList = false, relation) {
37
+ if (this.deepIncludeCount >= this.deepIncludeLimit) {
38
+ return true;
39
+ }
40
+ const includeSchema = {};
41
+ const entity = relation ? new relation() : new this._modelName();
42
+ Object.keys(entity)
43
+ .filter((key) => !['_id', '_action'].includes(key))
44
+ .forEach((key) => {
45
+ let includes;
46
+ if (entity[key] instanceof list_1.List) {
47
+ if (forList) {
48
+ includeSchema[key] = true;
49
+ }
50
+ else {
51
+ includes = this.autogenerateIncludeSchema(forList, entity[key].entityType);
52
+ }
53
+ }
54
+ else if (entity[key] instanceof entity_base_1.EntityBase) {
55
+ includes = this.autogenerateIncludeSchema(forList, entity[key].constructor);
56
+ }
57
+ if (includes) {
58
+ if (includes === true || Object.keys(includes).length > 0) {
59
+ includeSchema[key] = includes;
60
+ }
61
+ else {
62
+ includeSchema[key] = true;
63
+ }
64
+ }
65
+ });
66
+ this.deepIncludeCount += 1;
67
+ return includeSchema;
68
+ }
27
69
  getSelectRootPrismaSchema(entity) {
28
70
  const selectSchema = {};
29
71
  Object.keys(entity)
30
- .filter((key) => !['id', '_id', '_action'].includes(key))
72
+ .filter((key) => !['_id', '_action'].includes(key))
31
73
  .filter((key) => !(entity[key] instanceof Function || entity[key] instanceof list_1.List))
32
74
  .forEach((key) => {
33
75
  if (entity[key] instanceof entity_base_1.EntityBase) {
@@ -84,7 +126,7 @@ class RepositoryBase {
84
126
  const entityInstance = list.entityType;
85
127
  const modelName = entityInstance.name;
86
128
  const parentModelName = entity.constructor.name;
87
- const parentPropName = this.getPropNameFromEntitySource(new entityInstance(), entity.constructor) ?? parentModelName;
129
+ const parentPropName = this.getPropNameFromEntitySource(new entityInstance(), entity.constructor) ?? (0, KlString_1.toCamelCase)(parentModelName);
88
130
  if (modelName) {
89
131
  list.toArray('removed').forEach((item) => {
90
132
  relationDeletes.push({
@@ -161,9 +203,24 @@ class RepositoryBase {
161
203
  });
162
204
  return prismaSchema;
163
205
  }
206
+ getInclude(include) {
207
+ include = include ?? this._include ?? {};
208
+ const result = {};
209
+ Object.keys(include).forEach((key) => {
210
+ if (typeof include[key] === 'boolean') {
211
+ result[key] = include[key];
212
+ }
213
+ else {
214
+ result[key] = {
215
+ include: this.getInclude(include[key]),
216
+ };
217
+ }
218
+ });
219
+ return result;
220
+ }
164
221
  findManySchema(where, pagination) {
165
222
  return {
166
- include: this.getInclude(),
223
+ include: this.getInclude(this._includeFindMany),
167
224
  where,
168
225
  orderBy: pagination?.generateOrderBy(),
169
226
  skip: pagination?.skip(),
@@ -186,21 +243,6 @@ class RepositoryBase {
186
243
  getIdPropName(entity) {
187
244
  return (Reflect.getMetadata('entity:id', entity ? entity.constructor.prototype : this._modelName.prototype) ?? 'id');
188
245
  }
189
- getInclude(include) {
190
- include = include ?? this._include ?? {};
191
- const result = {};
192
- Object.keys(include).forEach((key) => {
193
- if (typeof include[key] === 'boolean') {
194
- result[key] = include[key];
195
- }
196
- else {
197
- result[key] = {
198
- include: this.getInclude(include[key]),
199
- };
200
- }
201
- });
202
- return result;
203
- }
204
246
  persistRelations(transaction, entity) {
205
247
  const { relationCreates, relationUpdates, relationDeletes } = this.listToRelationActionList(entity);
206
248
  return Promise.all([
@@ -209,7 +251,8 @@ class RepositoryBase {
209
251
  .then((response) => {
210
252
  return Promise.all(relationCreate.relations.map((relation) => {
211
253
  const relationPropName = this.getPropNameFromEntitySource(relation, relationCreate.entityInstance);
212
- if (relationPropName) {
254
+ if (relationPropName &&
255
+ !(relation[relationPropName] instanceof list_1.List)) {
213
256
  relation[relationPropName] =
214
257
  this.getConnectPrismaSchemaForRelation(relationCreate.entityInstance, response);
215
258
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koalarx/nest",
3
- "version": "3.0.10",
3
+ "version": "3.1.0",
4
4
  "description": "",
5
5
  "author": "Igor D. Rangel",
6
6
  "license": "MIT",