@koalarx/nest 1.1.0 → 1.2.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.
@@ -1,4 +1,4 @@
1
- import { QueryDirectionType } from "..";
1
+ import { QueryDirectionType } from '..';
2
2
  export declare const QUERY_FILTER_PARAMS: {
3
3
  direction: QueryDirectionType;
4
4
  page: number;
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.booleanSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  function booleanSchema() {
6
- return zod_1.z.coerce
7
- .string()
8
- .transform((value) => {
6
+ return zod_1.z.coerce.string().transform((value) => {
9
7
  if (value !== undefined) {
10
8
  return value === 'true';
11
9
  }
@@ -1,12 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EntityBase = void 0;
4
+ const auto_mapping_list_1 = require("../mapping/auto-mapping-list");
4
5
  const list_1 = require("../utils/list");
5
6
  class EntityBase {
6
7
  _id;
7
8
  automap(props) {
8
9
  if (props) {
9
10
  for (const key of Object.keys(props)) {
11
+ const propDefinitions = auto_mapping_list_1.AutoMappingList.getPropDefinitions(this.constructor.prototype.constructor, key);
12
+ const EntityOnPropKey = auto_mapping_list_1.AutoMappingList.getSourceByName(propDefinitions?.type);
10
13
  if (Array.isArray(props[key]) && this[key] instanceof list_1.List) {
11
14
  let value = props[key];
12
15
  if (this[key].entityType) {
@@ -18,12 +21,12 @@ class EntityBase {
18
21
  }
19
22
  this[key].setList(value);
20
23
  }
21
- else if (this[key] instanceof EntityBase) {
22
- const entity = new this[key].constructor();
24
+ else if (EntityOnPropKey) {
25
+ const entity = new EntityOnPropKey();
23
26
  entity.automap(props[key]);
24
27
  this[key] = entity;
25
28
  }
26
- else {
29
+ else if (propDefinitions) {
27
30
  if (key === 'id') {
28
31
  this._id = props[key];
29
32
  }
@@ -17,7 +17,7 @@ export declare abstract class RepositoryBase<TEntity extends EntityBase<TEntity>
17
17
  protected _context: PrismaTransactionalClient;
18
18
  private readonly _modelName;
19
19
  private readonly _include?;
20
- constructor({ context, modelName, include, }: RepositoryInitProps<TEntity>);
20
+ constructor({ context, modelName, include }: RepositoryInitProps<TEntity>);
21
21
  withTransaction(fn: (prisma: PrismaTransactionalClient) => Promise<any>): Promise<any>;
22
22
  protected findById(id: IComparableId): Promise<TEntity | null>;
23
23
  protected findFirst<T>(where: T): Promise<any>;
@@ -25,11 +25,12 @@ export declare abstract class RepositoryBase<TEntity extends EntityBase<TEntity>
25
25
  protected findManyAndCount<T>(where: T, pagination?: PaginationDto): Promise<ListResponse<TEntity>>;
26
26
  protected insert(entity: TEntity): any;
27
27
  protected edit<TWhere = any>(entity: TEntity, updateWhere?: TWhere): Promise<any>;
28
- protected remove<TWhere = any>(where: TWhere): any;
28
+ protected remove<TWhere = any>(where: TWhere): Promise<any>;
29
29
  private listToRelationActionList;
30
30
  private entityToPrisma;
31
31
  private context;
32
32
  private findManySchema;
33
33
  private createEntity;
34
+ private orphanRemoval;
34
35
  }
35
36
  export {};
@@ -10,7 +10,7 @@ class RepositoryBase {
10
10
  _context;
11
11
  _modelName;
12
12
  _include;
13
- constructor({ context, modelName, include, }) {
13
+ constructor({ context, modelName, include }) {
14
14
  this._context = context;
15
15
  this._modelName = modelName;
16
16
  this._include = include;
@@ -60,13 +60,13 @@ class RepositoryBase {
60
60
  return { items: [], count };
61
61
  }
62
62
  insert(entity) {
63
- const prismaEntity = this.entityToPrisma(entity);
63
+ const prismaEntity = this.entityToPrisma(entity, true);
64
64
  return this.context().create({
65
65
  data: prismaEntity,
66
66
  });
67
67
  }
68
68
  edit(entity, updateWhere) {
69
- const prismaEntity = this.entityToPrisma(entity);
69
+ const prismaEntity = this.entityToPrisma(entity, false);
70
70
  return this.withTransaction((client) => this.context(client)
71
71
  .update({
72
72
  where: updateWhere ?? { id: entity._id },
@@ -80,8 +80,17 @@ class RepositoryBase {
80
80
  ]);
81
81
  }));
82
82
  }
83
- remove(where) {
84
- return this.context().delete({ where });
83
+ async remove(where) {
84
+ const entity = await this.findFirst(where);
85
+ const relationEntity = [];
86
+ Object.keys(entity).forEach((key) => {
87
+ if (entity[key] instanceof entity_base_1.EntityBase) {
88
+ relationEntity.push(entity[key]);
89
+ }
90
+ });
91
+ return this.withTransaction((client) => this.context(client)
92
+ .delete({ where })
93
+ .then((response) => Promise.all(relationEntity.map((entity) => this.orphanRemoval(client, entity))).then(() => response)));
85
94
  }
86
95
  listToRelationActionList(entity) {
87
96
  const relationUpdates = [];
@@ -102,7 +111,7 @@ class RepositoryBase {
102
111
  modelName: (0, string_1.toCamelCase)(modelName),
103
112
  schema: {
104
113
  where: { id: item._id },
105
- data: this.entityToPrisma(item),
114
+ data: this.entityToPrisma(item, false),
106
115
  },
107
116
  });
108
117
  });
@@ -111,10 +120,10 @@ class RepositoryBase {
111
120
  });
112
121
  return { relationUpdates, relationDeletes };
113
122
  }
114
- entityToPrisma(entity) {
123
+ entityToPrisma(entity, isCreate) {
115
124
  const prismaSchema = {};
116
125
  Object.keys(entity)
117
- .filter((key) => key !== 'id' && key !== '_id')
126
+ .filter((key) => !['id', '_id'].includes(key))
118
127
  .filter((key) => !(entity[key] instanceof Function))
119
128
  .forEach((key) => {
120
129
  if (entity[key] instanceof list_1.List) {
@@ -122,14 +131,16 @@ class RepositoryBase {
122
131
  prismaSchema[key] = {
123
132
  createMany: {
124
133
  data: entity[key].toArray('added').map((item) => {
125
- return this.entityToPrisma(item);
134
+ return this.entityToPrisma(item, isCreate);
126
135
  }),
127
136
  },
128
137
  };
129
138
  }
130
139
  }
131
140
  else if (entity[key] instanceof entity_base_1.EntityBase) {
132
- prismaSchema[key] = this.entityToPrisma(entity[key]);
141
+ prismaSchema[key] = isCreate
142
+ ? { create: this.entityToPrisma(entity[key], isCreate) }
143
+ : { update: this.entityToPrisma(entity[key], isCreate) };
133
144
  }
134
145
  else {
135
146
  prismaSchema[key] = entity[key];
@@ -160,5 +171,12 @@ class RepositoryBase {
160
171
  entity.automap(data);
161
172
  return entity;
162
173
  }
174
+ orphanRemoval(client, entity) {
175
+ const where = {};
176
+ Object.keys(entity)
177
+ .filter((key) => key === 'id' || key.includes('Id'))
178
+ .forEach((key) => (where[key] = entity[key]));
179
+ return client[(0, string_1.toCamelCase)(entity.constructor.name)].delete({ where });
180
+ }
163
181
  }
164
182
  exports.RepositoryBase = RepositoryBase;
package/core/koala-app.js CHANGED
@@ -56,13 +56,15 @@ class KoalaApp {
56
56
  useDoc(config) {
57
57
  const credentials = {
58
58
  username: process.env.SWAGGER_USERNAME ?? '',
59
- password: process.env.SWAGGER_PASSWORD ?? ''
59
+ password: process.env.SWAGGER_PASSWORD ?? '',
60
60
  };
61
- if (env_config_1.EnvConfig.isEnvDevelop && credentials.username && credentials.password) {
61
+ if (env_config_1.EnvConfig.isEnvDevelop &&
62
+ credentials.username &&
63
+ credentials.password) {
62
64
  this.app.use([config.endpoint], expressBasicAuth({
63
65
  challenge: true,
64
66
  users: {
65
- [credentials.username]: credentials.password
67
+ [credentials.username]: credentials.password,
66
68
  },
67
69
  }));
68
70
  }
@@ -1,5 +1,5 @@
1
- import { Type } from "@nestjs/common";
2
- import { PrismaTransactionalClient } from "./database/prisma-transactional-client";
1
+ import { Type } from '@nestjs/common';
2
+ import { PrismaTransactionalClient } from './database/prisma-transactional-client';
3
3
  export declare class KoalaGlobalVars {
4
4
  static appName: string;
5
5
  static internalUserName: string;
@@ -12,6 +12,13 @@ export declare class AutoMappingList {
12
12
  private static _mappingProfileList;
13
13
  static add(source: Type<any>, target: Type<any>, ...forMember: ForMemberDefinition<any, any>): void;
14
14
  static get(source: Type<any>, target: Type<any>): AutoMappingGetContext;
15
+ static getSourceByName(sourceName: string): Type<any> | undefined;
16
+ static getPropDefinitions(source: Type<any>, propName: string): {
17
+ name: string;
18
+ type: any;
19
+ compositionType?: Type<any> | undefined;
20
+ compositionAction?: "onlySet" | "addTo" | undefined;
21
+ } | null | undefined;
15
22
  static getTargets(source: Type<any>): Type<any>[];
16
23
  static addMappedProp(source: Type<any>, propName: string): void;
17
24
  }
@@ -19,6 +19,15 @@ class AutoMappingList {
19
19
  propTargetContext: this._mappedPropList.find((mp) => mp.source === target),
20
20
  };
21
21
  }
22
+ static getSourceByName(sourceName) {
23
+ return this._mappingProfileList.find((mp) => mp.source.name === sourceName)
24
+ ?.source;
25
+ }
26
+ static getPropDefinitions(source, propName) {
27
+ return this._mappedPropList
28
+ .find((mp) => mp.source === source)
29
+ ?.props.find((prop) => prop.name === propName);
30
+ }
22
31
  static getTargets(source) {
23
32
  return this._mappingProfileList
24
33
  .filter((mp) => mp.source === source)
@@ -17,7 +17,8 @@ function AutoMap(config) {
17
17
  customMetadata = Array;
18
18
  }
19
19
  }
20
- if (!Reflect.getMetadata('design:type', target, propertyKey) || !isArray) {
20
+ if (!Reflect.getMetadata('design:type', target, propertyKey) ||
21
+ !isArray) {
21
22
  Reflect.defineMetadata('design:type', customMetadata, target, propertyKey);
22
23
  }
23
24
  }
@@ -46,6 +46,12 @@ let AutoMappingService = exports.AutoMappingService = class AutoMappingService {
46
46
  else if (arrayToList) {
47
47
  mappedValue = this.mapArrayToList(value, compositionType, compositionAction === 'onlySet');
48
48
  }
49
+ else {
50
+ const propSourceInstance = this._contextList.getSourceByName(propSource.type);
51
+ if (propSourceInstance) {
52
+ mappedValue = this.mapNestedProp(value, propSourceInstance);
53
+ }
54
+ }
49
55
  mappedTarget[targetProp.name] = mappedValue;
50
56
  }
51
57
  }
@@ -65,9 +71,7 @@ let AutoMappingService = exports.AutoMappingService = class AutoMappingService {
65
71
  }
66
72
  }
67
73
  mapListToArray(value) {
68
- return value
69
- .toArray()
70
- .map((item) => {
74
+ return value.toArray().map((item) => {
71
75
  const entityOnList = value.entityType?.prototype.constructor;
72
76
  if (entityOnList) {
73
77
  return this.mapNestedProp(item, entityOnList) ?? {};
@@ -1,2 +1,2 @@
1
- import { Type } from "@nestjs/common";
2
- export declare function assignObject<T>(target: Type<T>, source: T): T;
1
+ import { Type } from '@nestjs/common';
2
+ export declare function assignObject<T>(Target: Type<T>, source: T): T;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assignObject = void 0;
4
- function assignObject(target, source) {
5
- return Object.assign(new target(), source);
4
+ function assignObject(Target, source) {
5
+ return Object.assign(new Target(), source);
6
6
  }
7
7
  exports.assignObject = assignObject;
@@ -46,6 +46,7 @@ class List {
46
46
  this._list.splice(index, 1);
47
47
  if (!this.contains(item, this._removedItemsList)) {
48
48
  this._removedItemsList.push(item);
49
+ console.log(this._removedItemsList);
49
50
  }
50
51
  }
51
52
  return this;
@@ -1,6 +1,16 @@
1
1
  "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  const entity_base_1 = require("../database/entity.base");
13
+ const auto_mapping_decorator_1 = require("../mapping/auto-mapping.decorator");
4
14
  const list_1 = require("./list");
5
15
  class EntityTest extends entity_base_1.EntityBase {
6
16
  id;
@@ -10,6 +20,14 @@ class EntityTest extends entity_base_1.EntityBase {
10
20
  this.automap(props);
11
21
  }
12
22
  }
23
+ __decorate([
24
+ (0, auto_mapping_decorator_1.AutoMap)(),
25
+ __metadata("design:type", Number)
26
+ ], EntityTest.prototype, "id", void 0);
27
+ __decorate([
28
+ (0, auto_mapping_decorator_1.AutoMap)(),
29
+ __metadata("design:type", Number)
30
+ ], EntityTest.prototype, "value", void 0);
13
31
  describe('List test', () => {
14
32
  let entity;
15
33
  beforeEach(() => {
@@ -1,14 +1,7 @@
1
1
  import { ConfigService } from '@nestjs/config';
2
2
  import { Env } from './env';
3
- export declare class EnvService {
3
+ export declare class EnvService<TEnv = Env> {
4
4
  private readonly configService;
5
- constructor(configService: ConfigService<Env, true>);
6
- get<T extends keyof Env>(key: T): import("@nestjs/config").PathValue<{
7
- NODE_ENV: "test" | "develop" | "staging" | "production";
8
- PORT: number;
9
- PRISMA_QUERY_LOG: boolean;
10
- REDIS_CONNECTION_STRING: string;
11
- SWAGGER_USERNAME?: string | undefined;
12
- SWAGGER_PASSWORD?: string | undefined;
13
- }, T>;
5
+ constructor(configService: ConfigService<TEnv, true>);
6
+ get<T extends keyof TEnv>(key: T): (string extends infer T_1 ? T_1 extends string ? T_1 extends keyof TEnv ? string extends infer T_2 ? T_2 extends string ? T_2 extends import("@nestjs/config").Path<TEnv[T_1]> ? import("@nestjs/config").PathValue<TEnv[T_1], T_2> : never : never : never : never : never : never) | (any extends infer T_3 ? T_3 extends any ? T_3 extends keyof TEnv ? TEnv[T_3] : never : never : never);
14
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koalarx/nest",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +1,4 @@
1
- import { Type } from "@nestjs/common";
1
+ import { Type } from '@nestjs/common';
2
2
  interface KoalaAppTestDependenciesConfig {
3
3
  dependencies: any[];
4
4
  }
@@ -29,9 +29,7 @@ class InMemoryBaseRepository {
29
29
  };
30
30
  }
31
31
  async insert(item) {
32
- const id = this.typeId === 'number'
33
- ? this.getNewId()
34
- : (0, node_crypto_1.randomUUID)();
32
+ const id = this.typeId === 'number' ? this.getNewId() : (0, node_crypto_1.randomUUID)();
35
33
  item.automap({ ...item, id });
36
34
  this.items.push(item);
37
35
  return { id: item._id };
@@ -51,7 +49,8 @@ class InMemoryBaseRepository {
51
49
  }
52
50
  getNewId() {
53
51
  return this.typeId === 'number'
54
- ? (0, array_1.klArray)(this.items).orderBy('_id', true).getValue()[0]?._id ?? 0 + 1
52
+ ? (0, array_1.klArray)(this.items).orderBy('_id', true).getValue()[0]
53
+ ?._id ?? 0 + 1
55
54
  : (0, node_crypto_1.randomUUID)();
56
55
  }
57
56
  }
@@ -13,7 +13,7 @@ function generateUniqueDatabaseURL() {
13
13
  url.searchParams.set('schema', schemaId);
14
14
  return {
15
15
  url: url.toString(),
16
- schemaId
16
+ schemaId,
17
17
  };
18
18
  }
19
19
  function createE2EDatabase() {