@opra/mongodb 1.5.7 → 1.6.0

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.
@@ -19,6 +19,7 @@ class MongoPatchGenerator {
19
19
  return {
20
20
  update,
21
21
  arrayFilters: ctx.arrayFilters,
22
+ initArrayFields: ctx.initArrayFields,
22
23
  };
23
24
  }
24
25
  _processComplexType(ctx, dataType, path, input, scope) {
@@ -84,6 +85,8 @@ class MongoPatchGenerator {
84
85
  if (!value)
85
86
  continue;
86
87
  if (field.isArray) {
88
+ ctx.initArrayFields = ctx.initArrayFields || [];
89
+ ctx.initArrayFields.push(pathDot + field.name);
87
90
  if (!value.length)
88
91
  continue;
89
92
  keyField = field.keyField || field.type.keyField;
@@ -329,6 +329,21 @@ class MongoEntityService extends mongo_service_js_1.MongoService {
329
329
  ]);
330
330
  const db = this.getDatabase();
331
331
  const collection = await this.getCollection(db);
332
+ /** Create array fields if not exists */
333
+ if (options?.initArrayFields) {
334
+ const $set = options.initArrayFields.reduce((a, k) => {
335
+ a[k] = { $ifNull: ['$' + k, []] };
336
+ return a;
337
+ }, {});
338
+ await collection.updateOne(filter || {}, [{ $set }], {
339
+ ...options,
340
+ session: options?.session ?? this.getSession(),
341
+ arrayFilters: undefined,
342
+ upsert: false,
343
+ });
344
+ delete options.initArrayFields;
345
+ }
346
+ /** Execute update operation */
332
347
  return (await collection.updateOne(filter || {}, update, {
333
348
  ...options,
334
349
  session: options?.session ?? this.getSession(),
@@ -352,6 +367,21 @@ class MongoEntityService extends mongo_service_js_1.MongoService {
352
367
  const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
353
368
  const db = this.getDatabase();
354
369
  const collection = await this.getCollection(db);
370
+ /** Create array fields if not exists */
371
+ if (options?.initArrayFields) {
372
+ const $set = options.initArrayFields.reduce((a, k) => {
373
+ a[k] = { $ifNull: ['$' + k, []] };
374
+ return a;
375
+ }, {});
376
+ await collection.updateMany(filter || {}, [{ $set }], {
377
+ ...(0, objects_1.omit)(options, ['filter']),
378
+ session: options?.session ?? this.getSession(),
379
+ arrayFilters: undefined,
380
+ upsert: false,
381
+ });
382
+ delete options.initArrayFields;
383
+ }
384
+ /** Execute update operation */
355
385
  return (await collection.updateMany(filter || {}, update, {
356
386
  ...(0, objects_1.omit)(options, ['filter']),
357
387
  session: options?.session ?? this.getSession(),
@@ -406,13 +436,14 @@ class MongoEntityService extends mongo_service_js_1.MongoService {
406
436
  }
407
437
  _generatePatch(command, doc) {
408
438
  const patchGenerator = new mongo_patch_generator_js_1.MongoPatchGenerator();
409
- const { update, arrayFilters } = patchGenerator.generatePatch(this.dataType, doc, {
439
+ const { update, arrayFilters, initArrayFields } = patchGenerator.generatePatch(this.dataType, doc, {
410
440
  scope: this._dataTypeScope,
411
441
  });
412
442
  command.options = command.options || {};
413
443
  if (arrayFilters) {
414
444
  command.options.arrayFilters = command.options.arrayFilters || [];
415
445
  command.options.arrayFilters.push(...arrayFilters);
446
+ command.options.initArrayFields = initArrayFields;
416
447
  }
417
448
  return update;
418
449
  }
@@ -253,6 +253,7 @@ class MongoService extends core_1.ServiceBase {
253
253
  if (operation === 'update') {
254
254
  options.partial = 'deep';
255
255
  options.allowPatchOperators = true;
256
+ options.keepKeyFields = true;
256
257
  }
257
258
  const dataType = this.dataType;
258
259
  validator = dataType.generateCodec('decode', options);
@@ -16,6 +16,7 @@ export class MongoPatchGenerator {
16
16
  return {
17
17
  update,
18
18
  arrayFilters: ctx.arrayFilters,
19
+ initArrayFields: ctx.initArrayFields,
19
20
  };
20
21
  }
21
22
  _processComplexType(ctx, dataType, path, input, scope) {
@@ -81,6 +82,8 @@ export class MongoPatchGenerator {
81
82
  if (!value)
82
83
  continue;
83
84
  if (field.isArray) {
85
+ ctx.initArrayFields = ctx.initArrayFields || [];
86
+ ctx.initArrayFields.push(pathDot + field.name);
84
87
  if (!value.length)
85
88
  continue;
86
89
  keyField = field.keyField || field.type.keyField;
@@ -326,6 +326,21 @@ export class MongoEntityService extends MongoService {
326
326
  ]);
327
327
  const db = this.getDatabase();
328
328
  const collection = await this.getCollection(db);
329
+ /** Create array fields if not exists */
330
+ if (options?.initArrayFields) {
331
+ const $set = options.initArrayFields.reduce((a, k) => {
332
+ a[k] = { $ifNull: ['$' + k, []] };
333
+ return a;
334
+ }, {});
335
+ await collection.updateOne(filter || {}, [{ $set }], {
336
+ ...options,
337
+ session: options?.session ?? this.getSession(),
338
+ arrayFilters: undefined,
339
+ upsert: false,
340
+ });
341
+ delete options.initArrayFields;
342
+ }
343
+ /** Execute update operation */
329
344
  return (await collection.updateOne(filter || {}, update, {
330
345
  ...options,
331
346
  session: options?.session ?? this.getSession(),
@@ -349,6 +364,21 @@ export class MongoEntityService extends MongoService {
349
364
  const filter = MongoAdapter.prepareFilter(options?.filter);
350
365
  const db = this.getDatabase();
351
366
  const collection = await this.getCollection(db);
367
+ /** Create array fields if not exists */
368
+ if (options?.initArrayFields) {
369
+ const $set = options.initArrayFields.reduce((a, k) => {
370
+ a[k] = { $ifNull: ['$' + k, []] };
371
+ return a;
372
+ }, {});
373
+ await collection.updateMany(filter || {}, [{ $set }], {
374
+ ...omit(options, ['filter']),
375
+ session: options?.session ?? this.getSession(),
376
+ arrayFilters: undefined,
377
+ upsert: false,
378
+ });
379
+ delete options.initArrayFields;
380
+ }
381
+ /** Execute update operation */
352
382
  return (await collection.updateMany(filter || {}, update, {
353
383
  ...omit(options, ['filter']),
354
384
  session: options?.session ?? this.getSession(),
@@ -403,13 +433,14 @@ export class MongoEntityService extends MongoService {
403
433
  }
404
434
  _generatePatch(command, doc) {
405
435
  const patchGenerator = new MongoPatchGenerator();
406
- const { update, arrayFilters } = patchGenerator.generatePatch(this.dataType, doc, {
436
+ const { update, arrayFilters, initArrayFields } = patchGenerator.generatePatch(this.dataType, doc, {
407
437
  scope: this._dataTypeScope,
408
438
  });
409
439
  command.options = command.options || {};
410
440
  if (arrayFilters) {
411
441
  command.options.arrayFilters = command.options.arrayFilters || [];
412
442
  command.options.arrayFilters.push(...arrayFilters);
443
+ command.options.initArrayFields = initArrayFields;
413
444
  }
414
445
  return update;
415
446
  }
@@ -250,6 +250,7 @@ export class MongoService extends ServiceBase {
250
250
  if (operation === 'update') {
251
251
  options.partial = 'deep';
252
252
  options.allowPatchOperators = true;
253
+ options.keepKeyFields = true;
253
254
  }
254
255
  const dataType = this.dataType;
255
256
  validator = dataType.generateCodec('decode', options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/mongodb",
3
- "version": "1.5.7",
3
+ "version": "1.6.0",
4
4
  "description": "Opra MongoDB adapter package",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -10,9 +10,9 @@
10
10
  "valgen": "^5.12.0"
11
11
  },
12
12
  "peerDependencies": {
13
- "@opra/common": "^1.5.7",
14
- "@opra/core": "^1.5.7",
15
- "@opra/http": "^1.5.7",
13
+ "@opra/common": "^1.6.0",
14
+ "@opra/core": "^1.6.0",
15
+ "@opra/http": "^1.6.0",
16
16
  "mongodb": ">= 6.0.0"
17
17
  },
18
18
  "type": "module",
@@ -7,11 +7,13 @@ interface Context {
7
7
  $push?: Record<string, any>;
8
8
  $pull?: Record<string, any>;
9
9
  arrayFilters?: Record<string, any>[];
10
+ initArrayFields?: string[];
10
11
  }
11
12
  export declare class MongoPatchGenerator {
12
13
  generatePatch<T extends object>(dataType: ComplexType, doc: PatchDTO<T>, options?: MongoPatchGenerator.Options): {
13
14
  update: UpdateFilter<T>;
14
15
  arrayFilters?: Record<string, any>[];
16
+ initArrayFields?: string[];
15
17
  };
16
18
  protected _processComplexType(ctx: Context, dataType: ComplexType, path: string, input: any, scope?: string): boolean;
17
19
  protected _processPush(ctx: Context, dataType: ComplexType, path: string, input: any, scope?: string): boolean;
@@ -36,8 +36,10 @@ export declare namespace MongoEntityService {
36
36
  interface ReplaceOptions<T> extends MongoService.ReplaceOptions<T> {
37
37
  }
38
38
  interface UpdateOneOptions<T> extends MongoService.UpdateOneOptions<T> {
39
+ initArrayFields?: string[];
39
40
  }
40
41
  interface UpdateManyOptions<T> extends MongoService.UpdateManyOptions<T> {
42
+ initArrayFields?: string[];
41
43
  }
42
44
  interface CreateCommand<T> extends StrictOmit<CommandInfo, 'documentId' | 'nestedId' | 'input'> {
43
45
  crud: 'create';