@lenne.tech/nest-server 8.6.17 → 8.6.18

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": "8.6.17",
3
+ "version": "8.6.18",
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",
@@ -2,6 +2,7 @@ import { NotFoundException } from '@nestjs/common';
2
2
  import { FilterQuery, QueryOptions } from 'mongoose';
3
3
  import { FilterArgs } from '../args/filter.args';
4
4
  import { merge } from '../helpers/config.helper';
5
+ import { getStringIds } from '../helpers/db.helper';
5
6
  import { convertFilterArgsToQuery } from '../helpers/filter.helper';
6
7
  import { assignPlain } from '../helpers/input.helper';
7
8
  import { ServiceOptions } from '../interfaces/service-options.interface';
@@ -58,6 +59,34 @@ export abstract class CrudService<T extends CoreModel = any> extends ModuleServi
58
59
  );
59
60
  }
60
61
 
62
+ /**
63
+ * Find and update
64
+ */
65
+ async findAndUpdate(
66
+ filter: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions },
67
+ update: any,
68
+ serviceOptions?: ServiceOptions
69
+ ): Promise<T[]> {
70
+ const dbItems: T[] = await this.find(filter, serviceOptions);
71
+ if (!dbItems?.length) {
72
+ return [];
73
+ }
74
+ const promises: Promise<T>[] = [];
75
+ for (const dbItem of dbItems) {
76
+ promises.push(
77
+ new Promise(async (resolve, reject) => {
78
+ try {
79
+ const item = await this.update(getStringIds(dbItem as any), update, serviceOptions);
80
+ resolve(item);
81
+ } catch (e) {
82
+ reject(e);
83
+ }
84
+ })
85
+ );
86
+ }
87
+ return await Promise.all(promises);
88
+ }
89
+
61
90
  /**
62
91
  * CRUD alias for get
63
92
  */
@@ -66,12 +95,18 @@ export abstract class CrudService<T extends CoreModel = any> extends ModuleServi
66
95
  /**
67
96
  * CRUD alias for find
68
97
  */
69
- async read(filterArgs?: FilterArgs, serviceOptions?: ServiceOptions): Promise<T[]>;
98
+ async read(
99
+ filter: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions },
100
+ serviceOptions?: ServiceOptions
101
+ ): Promise<T[]>;
70
102
 
71
103
  /**
72
104
  * CRUD alias for get or find
73
105
  */
74
- async read(input: string | FilterArgs, serviceOptions?: ServiceOptions): Promise<T | T[]> {
106
+ async read(
107
+ input: string | FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions },
108
+ serviceOptions?: ServiceOptions
109
+ ): Promise<T | T[]> {
75
110
  if (typeof input === 'string') {
76
111
  return this.get(input, serviceOptions);
77
112
  } else {
@@ -4,10 +4,12 @@ import * as fs from 'fs';
4
4
  import { createClient } from 'graphql-ws';
5
5
  import { jsonToGraphQLQuery } from 'json-to-graphql-query';
6
6
  import * as LightMyRequest from 'light-my-request';
7
+ import { Types } from 'mongoose';
7
8
  import * as superagent from 'superagent';
8
9
  import * as supertest from 'supertest';
9
10
  import * as util from 'util';
10
11
  import * as ws from 'ws';
12
+ import { getStringIds } from '../core/common/helpers/db.helper';
11
13
 
12
14
  /**
13
15
  * GraphQL request type
@@ -98,6 +100,11 @@ export interface TestGraphQLOptions {
98
100
  */
99
101
  logError?: boolean;
100
102
 
103
+ /**
104
+ * Whether to prepare arguments (like dates)
105
+ */
106
+ prepareArguments?: boolean;
107
+
101
108
  /**
102
109
  * Status Code = 400
103
110
  */
@@ -187,6 +194,7 @@ export class TestHelper {
187
194
  statusCode: 200,
188
195
  log: false,
189
196
  logError: false,
197
+ prepareArguments: true,
190
198
  ...options,
191
199
  };
192
200
 
@@ -233,7 +241,9 @@ export class TestHelper {
233
241
 
234
242
  // Set arguments
235
243
  if (graphql.arguments) {
236
- queryObj[graphql.type][graphql.name].__args = graphql.arguments;
244
+ queryObj[graphql.type][graphql.name].__args = config.prepareArguments
245
+ ? this.prepareArguments(graphql.arguments)
246
+ : graphql.arguments;
237
247
  }
238
248
 
239
249
  // Create request payload query
@@ -330,6 +340,39 @@ export class TestHelper {
330
340
  return result;
331
341
  }
332
342
 
343
+ /**
344
+ * Prepare arguments
345
+ */
346
+ prepareArguments(args: any, objects?: WeakMap<any, any>) {
347
+ if (!args) {
348
+ return args;
349
+ }
350
+ if (args instanceof Date) {
351
+ return args.toISOString();
352
+ }
353
+ if (args instanceof Types.ObjectId) {
354
+ return getStringIds(args);
355
+ }
356
+ if (!objects) {
357
+ objects = new WeakMap<any, any>();
358
+ }
359
+ if (typeof args === 'object' && objects.get(args)) {
360
+ return objects.get(args);
361
+ }
362
+ if (Array.isArray(args)) {
363
+ objects.set(args, args);
364
+ return args.map((item) => this.prepareArguments(item, objects));
365
+ }
366
+ if (typeof args === 'object') {
367
+ objects.set(args, args);
368
+ for (const [key, value] of Object.entries(args)) {
369
+ args[key] = this.prepareArguments(value, objects);
370
+ }
371
+ return args;
372
+ }
373
+ return args;
374
+ }
375
+
333
376
  /**
334
377
  * Prepare GraphQL fields for request
335
378
  * @param fields
@@ -424,6 +467,9 @@ export class TestHelper {
424
467
  }
425
468
 
426
469
  // Response
470
+ if (log) {
471
+ console.log(requestConfig);
472
+ }
427
473
  const response = await (variables ? request : request.send(requestConfig.payload));
428
474
  return this.processResponse(response, statusCode, log, logError);
429
475
  }