@nest-util/nest-crud 2.0.2 → 2.0.4

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.
@@ -0,0 +1,19 @@
1
+ import type { EntityMetadata } from 'typeorm';
2
+ /**
3
+ * Expands modification-field dot paths into every relation prefix required to
4
+ * load the referenced values, so relation fields (e.g. `addresses` or
5
+ * `company.addresses.city`) can be read without the consumer configuring
6
+ * `include`.
7
+ *
8
+ * Non-relation columns yield nothing. Unknown paths are ignored.
9
+ */
10
+ export declare function resolveRelationPaths(metadata: EntityMetadata, fields: readonly string[]): string[];
11
+ /** Checks whether a (root) property name exists on the entity as a column,
12
+ * embedded column, or relation. */
13
+ export declare function isKnownProperty(metadata: EntityMetadata, propertyName: string): boolean;
14
+ /**
15
+ * Normalizes a captured modification value so it is always jsonb-serializable
16
+ * and distinguishable from "not loaded": `undefined` becomes explicit `null`.
17
+ */
18
+ export declare function normalizeCapturedValue(value: unknown): unknown;
19
+ //# sourceMappingURL=relation-path.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-path.helper.d.ts","sourceRoot":"","sources":["../../../src/lib/helpers/relation-path.helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,MAAM,EAAE,CAyBV;AAED;mCACmC;AACnC,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,MAAM,GACnB,OAAO,CAST;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9D"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRelationPaths = resolveRelationPaths;
4
+ exports.isKnownProperty = isKnownProperty;
5
+ exports.normalizeCapturedValue = normalizeCapturedValue;
6
+ /**
7
+ * Expands modification-field dot paths into every relation prefix required to
8
+ * load the referenced values, so relation fields (e.g. `addresses` or
9
+ * `company.addresses.city`) can be read without the consumer configuring
10
+ * `include`.
11
+ *
12
+ * Non-relation columns yield nothing. Unknown paths are ignored.
13
+ */
14
+ function resolveRelationPaths(metadata, fields) {
15
+ const resolved = new Set();
16
+ for (const field of fields) {
17
+ if (!field) {
18
+ continue;
19
+ }
20
+ const segments = field.split('.');
21
+ let relations = metadata.relations ?? [];
22
+ let prefix = [];
23
+ for (const segment of segments) {
24
+ const match = relations.find((relation) => relation.propertyName === segment);
25
+ if (!match) {
26
+ break;
27
+ }
28
+ prefix = [...prefix, match.propertyName];
29
+ resolved.add(prefix.join('.'));
30
+ relations = match.inverseEntityMetadata.relations;
31
+ }
32
+ }
33
+ return [...resolved];
34
+ }
35
+ /** Checks whether a (root) property name exists on the entity as a column,
36
+ * embedded column, or relation. */
37
+ function isKnownProperty(metadata, propertyName) {
38
+ return ((metadata.columns ?? []).some((column) => column.propertyPath === propertyName ||
39
+ column.propertyPath.startsWith(`${propertyName}.`)) ||
40
+ (metadata.relations ?? []).some((relation) => relation.propertyName === propertyName));
41
+ }
42
+ /**
43
+ * Normalizes a captured modification value so it is always jsonb-serializable
44
+ * and distinguishable from "not loaded": `undefined` becomes explicit `null`.
45
+ */
46
+ function normalizeCapturedValue(value) {
47
+ return value === undefined ? null : value;
48
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Produces a deterministic, stable serialization of an arbitrary value so it
3
+ * can be hashed consistently across processes and after jsonb round-trips:
4
+ * - object keys are sorted recursively
5
+ * - Date instances become ISO strings
6
+ * - undefined / null / missing all normalize to null
7
+ * - arrays are order-insensitive: elements are hashed by their own canonical
8
+ * form and the resulting strings are sorted (a reordered-but-identical
9
+ * collection hashes equal — change detection, not order verification)
10
+ * - circular references become the string '[Circular]'
11
+ */
12
+ export declare function canonicalJson(value: unknown): string;
13
+ /** SHA-256 hex hash of a value's canonical JSON form. */
14
+ export declare function hashValue(value: unknown): string;
15
+ /** Structural equality used as legacy fallback when no hash is stored. */
16
+ export declare function deepEqual(a: unknown, b: unknown): boolean;
17
+ //# sourceMappingURL=value-hash.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-hash.helper.d.ts","sourceRoot":"","sources":["../../../src/lib/helpers/value-hash.helper.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA8BpD;AAED,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAEzD"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canonicalJson = canonicalJson;
4
+ exports.hashValue = hashValue;
5
+ exports.deepEqual = deepEqual;
6
+ const crypto_1 = require("crypto");
7
+ /**
8
+ * Produces a deterministic, stable serialization of an arbitrary value so it
9
+ * can be hashed consistently across processes and after jsonb round-trips:
10
+ * - object keys are sorted recursively
11
+ * - Date instances become ISO strings
12
+ * - undefined / null / missing all normalize to null
13
+ * - arrays are order-insensitive: elements are hashed by their own canonical
14
+ * form and the resulting strings are sorted (a reordered-but-identical
15
+ * collection hashes equal — change detection, not order verification)
16
+ * - circular references become the string '[Circular]'
17
+ */
18
+ function canonicalJson(value) {
19
+ const seen = new WeakSet();
20
+ const walk = (node) => {
21
+ if (node === undefined || node === null) {
22
+ return null;
23
+ }
24
+ if (node instanceof Date) {
25
+ return Number.isNaN(node.getTime()) ? null : node.toISOString();
26
+ }
27
+ if (typeof node === 'object') {
28
+ if (seen.has(node)) {
29
+ return '[Circular]';
30
+ }
31
+ seen.add(node);
32
+ if (Array.isArray(node)) {
33
+ const items = node
34
+ .map((item) => JSON.stringify(walk(item)))
35
+ .sort()
36
+ .map((item) => JSON.parse(item));
37
+ return { __set: items };
38
+ }
39
+ const out = {};
40
+ for (const key of Object.keys(node).sort()) {
41
+ out[key] = walk(node[key]);
42
+ }
43
+ return out;
44
+ }
45
+ return node;
46
+ };
47
+ return JSON.stringify(walk(value));
48
+ }
49
+ /** SHA-256 hex hash of a value's canonical JSON form. */
50
+ function hashValue(value) {
51
+ return (0, crypto_1.createHash)('sha256').update(canonicalJson(value)).digest('hex');
52
+ }
53
+ /** Structural equality used as legacy fallback when no hash is stored. */
54
+ function deepEqual(a, b) {
55
+ return canonicalJson(a) === canonicalJson(b);
56
+ }
@@ -31,6 +31,12 @@ export interface ModificationItem {
31
31
  * '[Circular]').
32
32
  */
33
33
  currentValue?: unknown;
34
+ /**
35
+ * SHA-256 hash of the captured value's canonical JSON form. Stored so the
36
+ * resubmit check can cheaply detect whether the field changed since the
37
+ * request without deep-comparing (possibly large) relation snapshots.
38
+ */
39
+ currentValueHash?: string;
34
40
  /** Value the reviewer wants instead. */
35
41
  wantedValue: unknown;
36
42
  /** Optional human-readable explanation. */
@@ -106,6 +112,34 @@ export interface ApprovalPipelineConfig {
106
112
  * `after*`) the previous status.
107
113
  */
108
114
  hooks?: ApprovalHooks;
115
+ /**
116
+ * Verifies that the requester actually applied the requested changes before
117
+ * allowing a resubmit. For each modification item the live field value is
118
+ * hashed and compared with the hash captured at request time — an identical
119
+ * hash means the field was left untouched.
120
+ */
121
+ resubmitCheck?: ApprovalResubmitCheckConfig;
122
+ }
123
+ export interface ApprovalResubmitCheckConfig {
124
+ /**
125
+ * 'all' (default): every non-ignored modification field must have changed.
126
+ * 'any': at least one must have changed.
127
+ */
128
+ mode?: 'all' | 'any';
129
+ /** Modification fields exempt from the "must have changed" gate. */
130
+ ignoreFields?: readonly string[];
131
+ /**
132
+ * Full override of the built-in comparison. Return false to block the
133
+ * resubmit with CRUD_APPROVAL_RESUBMIT_NOT_SATISFIED.
134
+ */
135
+ customChecker?: (context: {
136
+ modifications: ModificationItem[];
137
+ satisfied: {
138
+ field: string;
139
+ satisfied: boolean;
140
+ }[];
141
+ entity: unknown;
142
+ }) => boolean | Promise<boolean>;
109
143
  }
110
144
  export interface RequestModificationPayload {
111
145
  modifications: ModificationItem[];
@@ -1 +1 @@
1
- {"version":3,"file":"approval-pipeline.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/approval-pipeline.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEpF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,IAAI,CAAC;IAClB,oBAAoB,CAAC,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,IAAI,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAEtC;;;OAGG;IACH,WAAW,CAAC,EAAE,2BAA2B,CAAC;IAE1C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAE5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"approval-pipeline.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/approval-pipeline.interface.ts"],"names":[],"mappings":"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"}
@@ -129,8 +129,16 @@ export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = P
129
129
  * Deep-clones a value so it can be safely stored in a jsonb column. Object
130
130
  * graphs with circular references (common for loaded relations) are
131
131
  * sanitized: a circular branch is replaced with the string '[Circular]'.
132
+ * Keys whose value is `undefined` are dropped, mirroring jsonb persistence.
132
133
  */
133
134
  private sanitizeForJsonb;
135
+ /**
136
+ * Hashes a modification value through the exact pipeline its stored snapshot
137
+ * goes through — sanitize clone plus a JSON round-trip simulating jsonb
138
+ * persistence (Dates → ISO strings, undefined dropped) — so the resubmit
139
+ * check compares like with like regardless of TypeORM hydration.
140
+ */
141
+ private hashModificationValue;
134
142
  private loadApprovalStatus;
135
143
  private transitionApproval;
136
144
  private fireApprovalBeforeHook;
@@ -138,6 +146,13 @@ export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = P
138
146
  private assertTransitionAllowed;
139
147
  private userHasPermission;
140
148
  private applyApprovalVisibility;
149
+ /**
150
+ * Ensures the requester actually changed the fields covered by the stored
151
+ * modification request before a resubmit is allowed. Each item's live value
152
+ * hash is compared against the hash captured at request time; an identical
153
+ * hash means the field was left untouched.
154
+ */
155
+ private assertResubmitSatisfied;
141
156
  private approvalIdCastExpression;
142
157
  private toApprovalStatusView;
143
158
  private toApprovalHistoryView;
@@ -1 +1 @@
1
- {"version":3,"file":"nest-crud.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/nest-crud.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nest-crud.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/nest-crud.service.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,8 @@ const nest_error_1 = require("@nest-util/nest-error");
7
7
  const audit_log_entity_1 = require("../entities/audit-log.entity");
8
8
  const filter_helper_1 = require("../helpers/filter.helper");
9
9
  const pagination_helper_1 = require("../helpers/pagination.helper");
10
+ const relation_path_helper_1 = require("../helpers/relation-path.helper");
11
+ const value_hash_helper_1 = require("../helpers/value-hash.helper");
10
12
  const cursor_pagination_helper_1 = require("../helpers/cursor-pagination.helper");
11
13
  const approval_status_entity_1 = require("../entities/approval-status.entity");
12
14
  const modification_request_history_entity_1 = require("../entities/modification-request-history.entity");
@@ -559,12 +561,15 @@ let NestCrudService = class NestCrudService {
559
561
  * Loads the target entity with its configured `include` relations so that
560
562
  * relation fields can be read as objects when capturing modification values.
561
563
  */
562
- async getEntityWithRelations(id, user) {
564
+ async getEntityWithRelations(id, user, extraRelations) {
563
565
  if (this.enforceOwnershipFor(user)) {
564
566
  return this.findOwnedEntity(id, user);
565
567
  }
566
- const relations = this.include.length
567
- ? this.buildRelationsObject(this.include)
568
+ const relationPaths = [
569
+ ...new Set([...this.include, ...(extraRelations ?? [])]),
570
+ ];
571
+ const relations = relationPaths.length
572
+ ? this.buildRelationsObject(relationPaths)
568
573
  : undefined;
569
574
  return this.repo.findOne({
570
575
  where: { id },
@@ -590,6 +595,7 @@ let NestCrudService = class NestCrudService {
590
595
  * Deep-clones a value so it can be safely stored in a jsonb column. Object
591
596
  * graphs with circular references (common for loaded relations) are
592
597
  * sanitized: a circular branch is replaced with the string '[Circular]'.
598
+ * Keys whose value is `undefined` are dropped, mirroring jsonb persistence.
593
599
  */
594
600
  sanitizeForJsonb(value) {
595
601
  const seen = new WeakSet();
@@ -597,6 +603,9 @@ let NestCrudService = class NestCrudService {
597
603
  if (node === null || typeof node !== 'object') {
598
604
  return node;
599
605
  }
606
+ if (node instanceof Date) {
607
+ return Number.isNaN(node.getTime()) ? null : node.toISOString();
608
+ }
600
609
  if (seen.has(node)) {
601
610
  return '[Circular]';
602
611
  }
@@ -606,12 +615,29 @@ let NestCrudService = class NestCrudService {
606
615
  }
607
616
  const out = {};
608
617
  for (const key of Object.keys(node)) {
609
- out[key] = walk(node[key]);
618
+ const item = node[key];
619
+ if (item === undefined) {
620
+ continue;
621
+ }
622
+ out[key] = walk(item);
610
623
  }
611
624
  return out;
612
625
  };
613
626
  return walk(value);
614
627
  }
628
+ /**
629
+ * Hashes a modification value through the exact pipeline its stored snapshot
630
+ * goes through — sanitize clone plus a JSON round-trip simulating jsonb
631
+ * persistence (Dates → ISO strings, undefined dropped) — so the resubmit
632
+ * check compares like with like regardless of TypeORM hydration.
633
+ */
634
+ hashModificationValue(value) {
635
+ const sanitized = this.sanitizeForJsonb(value);
636
+ const roundTripped = typeof sanitized === 'object' && sanitized !== null
637
+ ? JSON.parse(JSON.stringify(sanitized))
638
+ : sanitized;
639
+ return (0, value_hash_helper_1.hashValue)(roundTripped);
640
+ }
615
641
  async loadApprovalStatus(id, user) {
616
642
  const entity = await this.resolveEntityForApproval(id, user);
617
643
  if (!entity) {
@@ -678,14 +704,23 @@ let NestCrudService = class NestCrudService {
678
704
  case 'requestModification': {
679
705
  this.assertTransitionAllowed(action, current, reviewable);
680
706
  approval.status = approval_pipeline_interface_1.APPROVAL_STATUS.modificationRequested;
681
- const entity = await this.getEntityWithRelations(id, user);
682
- const capturedModifications = (modifications ?? []).map((m) => ({
683
- ...m,
684
- currentValue: this.sanitizeForJsonb(m.currentValue !== undefined
707
+ const fields = (modifications ?? []).map((m) => m.field);
708
+ const extraRelations = (0, relation_path_helper_1.resolveRelationPaths)(this.repo.metadata, fields);
709
+ const entity = await this.getEntityWithRelations(id, user, extraRelations);
710
+ const capturedModifications = (modifications ?? []).map((m) => {
711
+ if (!(0, relation_path_helper_1.isKnownProperty)(this.repo.metadata, m.field.split('.')[0])) {
712
+ console.warn(`[NestCrudService] Approval modification field "${m.field}" does not exist on ${this.repo.metadata.tableName}; capturing null`);
713
+ }
714
+ const rawValue = m.currentValue !== undefined
685
715
  ? m.currentValue
686
- : this.readCurrentValue(entity, m.field)),
687
- wantedValue: this.sanitizeForJsonb(m.wantedValue),
688
- }));
716
+ : this.readCurrentValue(entity, m.field);
717
+ return {
718
+ ...m,
719
+ currentValue: this.sanitizeForJsonb((0, relation_path_helper_1.normalizeCapturedValue)(rawValue)),
720
+ currentValueHash: this.hashModificationValue(rawValue),
721
+ wantedValue: this.sanitizeForJsonb(m.wantedValue),
722
+ };
723
+ });
689
724
  approval.currentModifications = capturedModifications;
690
725
  await this.getHistoryRepository().save(this.getHistoryRepository().create({
691
726
  approvalStatusId: approval.id,
@@ -695,15 +730,17 @@ let NestCrudService = class NestCrudService {
695
730
  }));
696
731
  break;
697
732
  }
698
- case 'resubmit':
733
+ case 'resubmit': {
699
734
  if (current !== approval_pipeline_interface_1.APPROVAL_STATUS.modificationRequested) {
700
735
  throw (0, nest_error_1.keyed)(common_1.HttpStatus.BAD_REQUEST, nest_error_1.ErrorKey.CRUD_APPROVAL_INVALID_TRANSITION, { action: 'resubmit', current: String(current) });
701
736
  }
737
+ await this.assertResubmitSatisfied(approval, id, user);
702
738
  approval.status = approval_pipeline_interface_1.APPROVAL_STATUS.resubmitted;
703
739
  approval.currentModifications = null;
704
740
  approval.resubmittedBy = userId;
705
741
  approval.resubmittedAt = now;
706
742
  break;
743
+ }
707
744
  }
708
745
  const saved = await this.getApprovalRepository().save(approval);
709
746
  const afterContext = {
@@ -776,6 +813,55 @@ let NestCrudService = class NestCrudService {
776
813
  approvalVisibleStatuses: [...visible],
777
814
  });
778
815
  }
816
+ /**
817
+ * Ensures the requester actually changed the fields covered by the stored
818
+ * modification request before a resubmit is allowed. Each item's live value
819
+ * hash is compared against the hash captured at request time; an identical
820
+ * hash means the field was left untouched.
821
+ */
822
+ async assertResubmitSatisfied(approval, id, user) {
823
+ const checkConfig = this.approvalPipeline?.resubmitCheck;
824
+ const modifications = approval.currentModifications ?? [];
825
+ if (modifications.length === 0) {
826
+ return;
827
+ }
828
+ const fields = modifications.map((m) => m.field);
829
+ const extraRelations = (0, relation_path_helper_1.resolveRelationPaths)(this.repo.metadata, fields);
830
+ const entity = await this.getEntityWithRelations(id, user, extraRelations);
831
+ const ignored = new Set(checkConfig?.ignoreFields ?? []);
832
+ const satisfied = modifications.map((m) => {
833
+ if (ignored.has(m.field)) {
834
+ return { field: m.field, satisfied: true };
835
+ }
836
+ const live = this.readCurrentValue(entity, m.field);
837
+ const satisfiedField = m.currentValueHash !== undefined
838
+ ? this.hashModificationValue(live) !== m.currentValueHash
839
+ : m.currentValue !== undefined
840
+ ? !(0, value_hash_helper_1.deepEqual)(live, m.currentValue)
841
+ : true;
842
+ return { field: m.field, satisfied: satisfiedField };
843
+ });
844
+ let allowed;
845
+ if (checkConfig?.customChecker) {
846
+ allowed = await checkConfig.customChecker({
847
+ modifications,
848
+ satisfied,
849
+ entity,
850
+ });
851
+ }
852
+ else {
853
+ const required = satisfied.filter((s) => s.satisfied);
854
+ allowed =
855
+ checkConfig?.mode === 'any' ? required.length > 0 : required.length === satisfied.length;
856
+ }
857
+ if (!allowed) {
858
+ throw (0, nest_error_1.keyed)(common_1.HttpStatus.BAD_REQUEST, nest_error_1.ErrorKey.CRUD_APPROVAL_RESUBMIT_NOT_SATISFIED, {
859
+ unchangedFields: satisfied
860
+ .filter((s) => !s.satisfied)
861
+ .map((s) => s.field),
862
+ });
863
+ }
864
+ }
779
865
  approvalIdCastExpression() {
780
866
  const type = this.repo.manager.connection.options.type;
781
867
  if (type === 'mysql' || type === 'mariadb' || type === 'aurora-mysql') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nest-util/nest-crud",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",