@lenne.tech/nest-server 9.0.21 → 9.0.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "9.0.21",
3
+ "version": "9.0.22",
4
4
  "description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
5
5
  "keywords": [
6
6
  "node",
@@ -648,11 +648,22 @@ export function instanceofArray(arr: any[], strict = false): string {
648
648
 
649
649
  /**
650
650
  * Process data via function deep
651
- * @param data
652
- * @param func
653
- * @param processedObjects
654
651
  */
655
- export function processDeep(data: any, func: (data: any) => any, processedObjects = new WeakMap()): any {
652
+ export function processDeep(
653
+ data: any,
654
+ func: (data: any) => any,
655
+ options?: {
656
+ processedObjects?: WeakMap<new () => any, boolean>;
657
+ specialClasses?: ((new (args: any[]) => any) | string)[];
658
+ }
659
+ ): any {
660
+ // Set options
661
+ const { processedObjects, specialClasses } = {
662
+ processedObjects: new WeakMap(),
663
+ specialClasses: [],
664
+ ...options,
665
+ };
666
+
656
667
  // Prevent circular processing
657
668
  if (typeof data === 'object') {
658
669
  if (processedObjects.get(data)) {
@@ -663,13 +674,21 @@ export function processDeep(data: any, func: (data: any) => any, processedObject
663
674
 
664
675
  // Process array
665
676
  if (Array.isArray(data)) {
666
- return data.map((item) => processDeep(item, func));
677
+ return data.map((item) => processDeep(item, func, { processedObjects, specialClasses }));
667
678
  }
668
679
 
669
680
  // Process object
670
681
  if (typeof data === 'object') {
682
+ for (const specialClass of specialClasses) {
683
+ if (
684
+ (typeof specialClass === 'string' && specialClass === data.constructor.name) ||
685
+ (typeof specialClass !== 'string' && data instanceof specialClass)
686
+ ) {
687
+ return func(data);
688
+ }
689
+ }
671
690
  for (const [key, value] of Object.entries(data)) {
672
- data[key] = processDeep(value, func, processedObjects);
691
+ data[key] = processDeep(value, func, { processedObjects, specialClasses });
673
692
  }
674
693
  return data;
675
694
  }
@@ -10,7 +10,8 @@ import { PrepareOutputOptions } from '../interfaces/prepare-output-options.inter
10
10
  import { ResolveSelector } from '../interfaces/resolve-selector.interface';
11
11
  import { ServiceOptions } from '../interfaces/service-options.interface';
12
12
  import { ConfigService } from '../services/config.service';
13
- import { clone } from './input.helper';
13
+ import { getStringIds } from './db.helper';
14
+ import { clone, processDeep } from './input.helper';
14
15
 
15
16
  /**
16
17
  * Helper class for services
@@ -66,6 +67,7 @@ export async function prepareInput<T = any>(
66
67
  [key: string]: any;
67
68
  checkRoles?: boolean;
68
69
  circles?: boolean;
70
+ convertObjectIdsToString?: boolean;
69
71
  create?: boolean;
70
72
  clone?: boolean;
71
73
  getNewArray?: boolean;
@@ -80,6 +82,7 @@ export async function prepareInput<T = any>(
80
82
  checkRoles: false,
81
83
  clone: false,
82
84
  circles: false,
85
+ convertObjectIdsToString: true,
83
86
  create: false,
84
87
  getNewArray: false,
85
88
  proto: false,
@@ -114,6 +117,20 @@ export async function prepareInput<T = any>(
114
117
  }
115
118
  }
116
119
 
120
+ // Convert ObjectIds to string
121
+ if (config.convertObjectIdsToString) {
122
+ input = processDeep(
123
+ input,
124
+ (property) => {
125
+ if (property instanceof Types.ObjectId) {
126
+ property = getStringIds(property);
127
+ }
128
+ return property;
129
+ },
130
+ { specialClasses: ['ObjectId'] }
131
+ );
132
+ }
133
+
117
134
  // Map input if target model exist
118
135
  if (config.targetModel && !(input instanceof config.targetModel)) {
119
136
  if ((config.targetModel as any)?.map) {
@@ -4,6 +4,7 @@
4
4
  export interface PrepareInputOptions {
5
5
  [key: string]: any;
6
6
  checkRoles?: boolean;
7
+ convertObjectIdsToString?: boolean;
7
8
  create?: boolean;
8
9
  clone?: boolean;
9
10
  getNewArray?: boolean;
@@ -111,7 +111,7 @@ export abstract class ModuleService<T extends CoreModel = any> {
111
111
  if (!opts.targetModel && config.inputType) {
112
112
  opts.targetModel = config.inputType;
113
113
  }
114
- config.input = await this.prepareInput(config.input, opts);
114
+ config.input = await this.prepareInput(config.input, config);
115
115
  }
116
116
 
117
117
  // Get DB object
@@ -156,7 +156,7 @@ export abstract class ModuleService<T extends CoreModel = any> {
156
156
  if (config.outputPath) {
157
157
  _.set(result, config.outputPath, await this.prepareOutput(_.get(result, config.outputPath), opts));
158
158
  } else {
159
- result = await this.prepareOutput(result, opts);
159
+ result = await this.prepareOutput(result, config);
160
160
  }
161
161
  }
162
162