nicot 1.2.5 → 1.2.6

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/dist/index.mjs CHANGED
@@ -1045,6 +1045,7 @@ import { camelCase } from "typeorm/util/StringUtils";
1045
1045
  import _3, { omit } from "lodash";
1046
1046
  import {
1047
1047
  BlankReturnMessageDto as BlankReturnMessageDto2,
1048
+ GenericReturnMessageDto,
1048
1049
  PaginatedReturnMessageDto,
1049
1050
  ReturnMessageDto
1050
1051
  } from "nesties";
@@ -1393,6 +1394,30 @@ async function getPaginatedResult(qb, entityClass, entityAliasName, take, cursor
1393
1394
 
1394
1395
  // src/crud-base.ts
1395
1396
  import PQueue from "p-queue";
1397
+
1398
+ // src/utility/observe-diff.ts
1399
+ var observeDiff = (obj, cb) => {
1400
+ return new Proxy(obj, {
1401
+ set(target, key, value) {
1402
+ const oldValue = target[key];
1403
+ const type = Object.prototype.hasOwnProperty.call(target, key) ? "update" : "add";
1404
+ target[key] = value;
1405
+ cb({ type, key, oldValue, newValue: value });
1406
+ return true;
1407
+ },
1408
+ deleteProperty(target, key) {
1409
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
1410
+ const oldValue = target[key];
1411
+ delete target[key];
1412
+ cb({ type: "delete", key, oldValue, newValue: void 0 });
1413
+ return true;
1414
+ }
1415
+ return false;
1416
+ }
1417
+ });
1418
+ };
1419
+
1420
+ // src/crud-base.ts
1396
1421
  var Relation = (name, options = {}) => {
1397
1422
  return { name, inner: false, ...options };
1398
1423
  };
@@ -1999,13 +2024,72 @@ var CrudBase = class {
1999
2024
  })
2000
2025
  );
2001
2026
  }
2002
- async exists(id) {
2027
+ async exists(id, cond = {}) {
2003
2028
  const bindingEnt = await this.getBindingPartialEntity();
2004
- const ent = await this.repo.findOne({
2005
- where: { id, ...bindingEnt },
2006
- select: ["id"]
2029
+ return this.repo.exists({
2030
+ where: { id, ...bindingEnt, ...cond }
2007
2031
  });
2008
- return !!ent;
2032
+ }
2033
+ async operation(id, cb, extraOptions = {}) {
2034
+ const bindingEnt = await this.getBindingPartialEntity();
2035
+ const where = {
2036
+ id,
2037
+ ...bindingEnt,
2038
+ ...extraOptions.where || {}
2039
+ };
2040
+ const throw404 = () => {
2041
+ throw new BlankReturnMessageDto2(
2042
+ 404,
2043
+ `${this.entityName} ID ${id} not found.`
2044
+ ).toException();
2045
+ };
2046
+ if (!await this.repo.exists({ where })) {
2047
+ throw404();
2048
+ }
2049
+ const res = await this.repo.manager.transaction(async (tdb) => {
2050
+ const repo = tdb.getRepository(this.entityClass);
2051
+ const ent = await repo.findOne({
2052
+ lock: { mode: "pessimistic_write" },
2053
+ ...extraOptions,
2054
+ where
2055
+ });
2056
+ if (!ent) {
2057
+ throw404();
2058
+ }
2059
+ const initial = { ...ent };
2060
+ let changes = {};
2061
+ const entProxy = observeDiff(ent, (change) => {
2062
+ if (change.type === "delete") {
2063
+ if (initial[change.key] === null) {
2064
+ delete changes[change.key];
2065
+ } else {
2066
+ changes[change.key] = null;
2067
+ }
2068
+ } else {
2069
+ if (change.newValue !== initial[change.key]) {
2070
+ changes[change.key] = change.newValue;
2071
+ } else {
2072
+ delete changes[change.key];
2073
+ }
2074
+ }
2075
+ });
2076
+ const flush = async () => {
2077
+ if (Object.keys(changes).length) {
2078
+ const currentChanges = { ...changes };
2079
+ Object.assign(initial, changes);
2080
+ changes = {};
2081
+ await repo.update({ id }, currentChanges);
2082
+ }
2083
+ };
2084
+ const result = await cb(entProxy, { repo, flush });
2085
+ await flush();
2086
+ return result;
2087
+ });
2088
+ if (res == null) {
2089
+ return new BlankReturnMessageDto2(200, "success");
2090
+ } else {
2091
+ return new GenericReturnMessageDto(200, "success", res);
2092
+ }
2009
2093
  }
2010
2094
  async _loadFullTextIndex() {
2011
2095
  const fields = reflector.getArray(
@@ -2067,18 +2151,17 @@ import {
2067
2151
  Query
2068
2152
  } from "@nestjs/common";
2069
2153
  import {
2070
- BlankReturnMessageDto as BlankReturnMessageDto3,
2071
2154
  MergeMethodDecorators,
2072
2155
  PaginatedReturnMessageDto as PaginatedReturnMessageDto2,
2073
2156
  ReturnMessageDto as ReturnMessageDto2,
2074
2157
  getApiProperty as getApiProperty2,
2075
- DataPipe
2158
+ DataPipe,
2159
+ ApiTypeResponse,
2160
+ ApiBlankResponse,
2161
+ ApiError
2076
2162
  } from "nesties";
2077
2163
  import {
2078
- ApiBadRequestResponse,
2079
2164
  ApiBody,
2080
- ApiInternalServerErrorResponse,
2081
- ApiNotFoundResponse,
2082
2165
  ApiOkResponse,
2083
2166
  ApiOperation,
2084
2167
  ApiParam,
@@ -2613,10 +2696,7 @@ var _RestfulFactory = class _RestfulFactory {
2613
2696
  }),
2614
2697
  ApiBody({ type: this.createDto }),
2615
2698
  ApiOkResponse({ type: this.entityCreateReturnMessageDto }),
2616
- ApiBadRequestResponse({
2617
- type: BlankReturnMessageDto3,
2618
- description: `The ${this.entityClassName} is not valid`
2619
- })
2699
+ ApiError(400, `The ${this.entityClassName} is not valid`)
2620
2700
  ]);
2621
2701
  }
2622
2702
  createParam() {
@@ -2631,10 +2711,10 @@ var _RestfulFactory = class _RestfulFactory {
2631
2711
  }),
2632
2712
  ApiParam({ name: "id", type: this.idType, required: true }),
2633
2713
  ApiOkResponse({ type: this.entityReturnMessageDto }),
2634
- ApiNotFoundResponse({
2635
- type: BlankReturnMessageDto3,
2636
- description: `The ${this.entityClassName} with the given id was not found`
2637
- })
2714
+ ApiError(
2715
+ 400,
2716
+ `The ${this.entityClassName} with the given id was not found`
2717
+ )
2638
2718
  ]);
2639
2719
  }
2640
2720
  idParam() {
@@ -2690,19 +2770,13 @@ var _RestfulFactory = class _RestfulFactory {
2690
2770
  }),
2691
2771
  ApiParam({ name: "id", type: this.idType, required: true }),
2692
2772
  ApiBody({ type: this.updateDto }),
2693
- ApiOkResponse({ type: BlankReturnMessageDto3 }),
2694
- ApiNotFoundResponse({
2695
- type: BlankReturnMessageDto3,
2696
- description: `The ${this.entityClassName} with the given id was not found`
2697
- }),
2698
- ApiBadRequestResponse({
2699
- type: BlankReturnMessageDto3,
2700
- description: `The ${this.entityClassName} is not valid`
2701
- }),
2702
- ApiInternalServerErrorResponse({
2703
- type: BlankReturnMessageDto3,
2704
- description: "Internal error"
2705
- })
2773
+ ApiBlankResponse(),
2774
+ ApiError(
2775
+ 404,
2776
+ `The ${this.entityClassName} with the given id was not found`
2777
+ ),
2778
+ ApiError(400, `The ${this.entityClassName} is not valid`),
2779
+ ApiError(500, "Internal error")
2706
2780
  ]);
2707
2781
  }
2708
2782
  updateParam() {
@@ -2717,20 +2791,17 @@ var _RestfulFactory = class _RestfulFactory {
2717
2791
  ...extras
2718
2792
  }),
2719
2793
  ApiParam({ name: "id", type: this.idType, required: true }),
2720
- ApiOkResponse({ type: BlankReturnMessageDto3 }),
2721
- ApiNotFoundResponse({
2722
- type: BlankReturnMessageDto3,
2723
- description: `The ${this.entityClassName} with the given id was not found`
2724
- }),
2725
- ApiInternalServerErrorResponse({
2726
- type: BlankReturnMessageDto3,
2727
- description: "Internal error"
2728
- })
2794
+ ApiBlankResponse(),
2795
+ ApiError(
2796
+ 404,
2797
+ `The ${this.entityClassName} with the given id was not found`
2798
+ ),
2799
+ ApiError(500, "Internal error")
2729
2800
  ]);
2730
2801
  }
2731
2802
  import(extras = {}) {
2732
2803
  return MergeMethodDecorators([
2733
- Post("import"),
2804
+ this.usePrefix(Post, "import"),
2734
2805
  HttpCode(200),
2735
2806
  ApiOperation({
2736
2807
  summary: `Import ${this.entityClassName}`,
@@ -2738,10 +2809,22 @@ var _RestfulFactory = class _RestfulFactory {
2738
2809
  }),
2739
2810
  ApiBody({ type: this.importDto }),
2740
2811
  ApiOkResponse({ type: this.importReturnMessageDto }),
2741
- ApiInternalServerErrorResponse({
2742
- type: BlankReturnMessageDto3,
2743
- description: "Internal error"
2744
- })
2812
+ ApiError(500, "Internal error")
2813
+ ]);
2814
+ }
2815
+ operation(operationName, options = {}) {
2816
+ return MergeMethodDecorators([
2817
+ this.usePrefix(Post, `:id/${operationName}`),
2818
+ HttpCode(200),
2819
+ ApiOperation({
2820
+ summary: `${upperFirst(operationName)} a ${this.entityClassName} by id`,
2821
+ ...options.operationExtras || {}
2822
+ }),
2823
+ options.returnType ? ApiTypeResponse(options.returnType) : ApiBlankResponse(),
2824
+ ApiError(
2825
+ 404,
2826
+ `The ${this.entityClassName} with the given id was not found`
2827
+ )
2745
2828
  ]);
2746
2829
  }
2747
2830
  baseController(routeOptions = {}) {