@rws-framework/db 4.0.1 → 4.1.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.
@@ -15,6 +15,7 @@ declare class RWSModel<T> implements IModel {
15
15
  static _BANNED_KEYS: string[];
16
16
  static allModels: OpModelType<any>[];
17
17
  static _CUT_KEYS: string[];
18
+ private _relationFields;
18
19
  private postLoadExecuted;
19
20
  constructor(data?: any);
20
21
  isPostLoadExecuted(): boolean;
@@ -86,5 +87,6 @@ declare class RWSModel<T> implements IModel {
86
87
  private hydratePrePopulatedRelations;
87
88
  static getDb(): DBService;
88
89
  reload(): Promise<RWSModel<T> | null>;
90
+ getPropertyValue(key: string): any;
89
91
  }
90
92
  export { RWSModel };
@@ -27,6 +27,8 @@ class RWSModel {
27
27
  static _BANNED_KEYS = ['_collection'];
28
28
  static allModels = [];
29
29
  static _CUT_KEYS = [];
30
+ // Store relation foreign key fields for reload() functionality
31
+ _relationFields = {};
30
32
  postLoadExecuted = false;
31
33
  constructor(data = null) {
32
34
  if (!this.getCollection()) {
@@ -440,6 +442,30 @@ class RWSModel {
440
442
  if (typeof relationData === 'object' && relationData !== null &&
441
443
  (relationData.id || Object.keys(relationData).length > 1)) {
442
444
  const relatedInstance = new ModelClass();
445
+ // Check relation metadata to identify foreign key fields that need to be preserved
446
+ const tempInstance = new ModelClass();
447
+ const childClassFields = FieldsHelper_1.FieldsHelper.getAllClassFields(tempInstance.constructor);
448
+ const [childRelOneData, childRelManyData] = await Promise.all([
449
+ RelationUtils_1.RelationUtils.getRelationOneMeta(tempInstance, childClassFields),
450
+ RelationUtils_1.RelationUtils.getRelationManyMeta(tempInstance, childClassFields)
451
+ ]);
452
+ // Store foreign key fields from relation metadata
453
+ for (const relKey in childRelOneData) {
454
+ const relMeta = childRelOneData[relKey];
455
+ const foreignKeyField = relMeta.hydrationField; // e.g., 'avatar_id', 'knowledge_id'
456
+ if (foreignKeyField && relationData[foreignKeyField] !== undefined) {
457
+ relatedInstance._relationFields[foreignKeyField] = relationData[foreignKeyField];
458
+ relatedInstance[foreignKeyField] = relationData[foreignKeyField];
459
+ }
460
+ }
461
+ for (const relKey in childRelManyData) {
462
+ const relMeta = childRelManyData[relKey];
463
+ const foreignKeyField = relMeta.foreignKey; // Use foreignKey for inverse relations
464
+ if (foreignKeyField && relationData[foreignKeyField] !== undefined) {
465
+ relatedInstance._relationFields[foreignKeyField] = relationData[foreignKeyField];
466
+ relatedInstance[foreignKeyField] = relationData[foreignKeyField];
467
+ }
468
+ }
443
469
  await relatedInstance._asyncFill(relationData, false, false, true);
444
470
  this[key] = relatedInstance;
445
471
  }
@@ -450,6 +476,30 @@ class RWSModel {
450
476
  for (const itemData of relationData) {
451
477
  if (typeof itemData === 'object' && itemData !== null) {
452
478
  const relatedInstance = new ModelClass();
479
+ // Check relation metadata to identify foreign key fields that need to be preserved
480
+ const tempInstance = new ModelClass();
481
+ const childClassFields = FieldsHelper_1.FieldsHelper.getAllClassFields(tempInstance.constructor);
482
+ const [childRelOneData, childRelManyData] = await Promise.all([
483
+ RelationUtils_1.RelationUtils.getRelationOneMeta(tempInstance, childClassFields),
484
+ RelationUtils_1.RelationUtils.getRelationManyMeta(tempInstance, childClassFields)
485
+ ]);
486
+ // Store foreign key fields from relation metadata
487
+ for (const relKey in childRelOneData) {
488
+ const relMeta = childRelOneData[relKey];
489
+ const foreignKeyField = relMeta.hydrationField; // e.g., 'avatar_id', 'knowledge_id'
490
+ if (foreignKeyField && itemData[foreignKeyField] !== undefined) {
491
+ relatedInstance._relationFields[foreignKeyField] = itemData[foreignKeyField];
492
+ relatedInstance[foreignKeyField] = itemData[foreignKeyField];
493
+ }
494
+ }
495
+ for (const relKey in childRelManyData) {
496
+ const relMeta = childRelManyData[relKey];
497
+ const foreignKeyField = relMeta.foreignKey; // Use foreignKey for inverse relations
498
+ if (foreignKeyField && itemData[foreignKeyField] !== undefined) {
499
+ relatedInstance._relationFields[foreignKeyField] = itemData[foreignKeyField];
500
+ relatedInstance[foreignKeyField] = itemData[foreignKeyField];
501
+ }
502
+ }
453
503
  await relatedInstance._asyncFill(itemData, false, false, true);
454
504
  relatedInstances.push(relatedInstance);
455
505
  }
@@ -481,10 +531,23 @@ class RWSModel {
481
531
  }
482
532
  // Convert the fresh instance back to plain data for hydration
483
533
  const plainData = await freshData.toMongo();
534
+ // Preserve foreign key fields from _relationFields to ensure relations can be hydrated
535
+ for (const key in this._relationFields) {
536
+ if (plainData[key] === undefined) {
537
+ plainData[key] = this._relationFields[key];
538
+ }
539
+ }
484
540
  // Hydrate current instance with fresh data including relations
485
541
  await this._asyncFill(plainData, true, true, true);
486
542
  return this;
487
543
  }
544
+ // Helper method to get property with fallback to stored relation fields
545
+ getPropertyValue(key) {
546
+ if (this.hasOwnProperty(key) || this[key] !== undefined) {
547
+ return this[key];
548
+ }
549
+ return this._relationFields[key];
550
+ }
488
551
  }
489
552
  exports.RWSModel = RWSModel;
490
553
  __decorate([
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rws-framework/db",
3
3
  "private": false,
4
- "version": "4.0.1",
4
+ "version": "4.1.0",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -27,6 +27,9 @@ class RWSModel<T> implements IModel {
27
27
  static _BANNED_KEYS = ['_collection'];
28
28
  static allModels: OpModelType<any>[] = [];
29
29
  static _CUT_KEYS: string[] = [];
30
+
31
+ // Store relation foreign key fields for reload() functionality
32
+ private _relationFields: Record<string, any> = {};
30
33
 
31
34
  private postLoadExecuted: boolean = false;
32
35
 
@@ -566,6 +569,34 @@ class RWSModel<T> implements IModel {
566
569
  if (typeof relationData === 'object' && relationData !== null &&
567
570
  (relationData.id || Object.keys(relationData).length > 1)) {
568
571
  const relatedInstance = new ModelClass();
572
+
573
+ // Check relation metadata to identify foreign key fields that need to be preserved
574
+ const tempInstance = new ModelClass();
575
+ const childClassFields = FieldsHelper.getAllClassFields(tempInstance.constructor);
576
+ const [childRelOneData, childRelManyData] = await Promise.all([
577
+ RelationUtils.getRelationOneMeta(tempInstance, childClassFields),
578
+ RelationUtils.getRelationManyMeta(tempInstance, childClassFields)
579
+ ]);
580
+
581
+ // Store foreign key fields from relation metadata
582
+ for (const relKey in childRelOneData) {
583
+ const relMeta = childRelOneData[relKey];
584
+ const foreignKeyField = relMeta.hydrationField; // e.g., 'avatar_id', 'knowledge_id'
585
+ if (foreignKeyField && relationData[foreignKeyField] !== undefined) {
586
+ relatedInstance._relationFields[foreignKeyField] = relationData[foreignKeyField];
587
+ relatedInstance[foreignKeyField] = relationData[foreignKeyField];
588
+ }
589
+ }
590
+
591
+ for (const relKey in childRelManyData) {
592
+ const relMeta = childRelManyData[relKey];
593
+ const foreignKeyField = relMeta.foreignKey; // Use foreignKey for inverse relations
594
+ if (foreignKeyField && relationData[foreignKeyField] !== undefined) {
595
+ relatedInstance._relationFields[foreignKeyField] = relationData[foreignKeyField];
596
+ relatedInstance[foreignKeyField] = relationData[foreignKeyField];
597
+ }
598
+ }
599
+
569
600
  await relatedInstance._asyncFill(relationData, false, false, true);
570
601
  this[key] = relatedInstance;
571
602
  }
@@ -575,6 +606,34 @@ class RWSModel<T> implements IModel {
575
606
  for (const itemData of relationData) {
576
607
  if (typeof itemData === 'object' && itemData !== null) {
577
608
  const relatedInstance = new ModelClass();
609
+
610
+ // Check relation metadata to identify foreign key fields that need to be preserved
611
+ const tempInstance = new ModelClass();
612
+ const childClassFields = FieldsHelper.getAllClassFields(tempInstance.constructor);
613
+ const [childRelOneData, childRelManyData] = await Promise.all([
614
+ RelationUtils.getRelationOneMeta(tempInstance, childClassFields),
615
+ RelationUtils.getRelationManyMeta(tempInstance, childClassFields)
616
+ ]);
617
+
618
+ // Store foreign key fields from relation metadata
619
+ for (const relKey in childRelOneData) {
620
+ const relMeta = childRelOneData[relKey];
621
+ const foreignKeyField = relMeta.hydrationField; // e.g., 'avatar_id', 'knowledge_id'
622
+ if (foreignKeyField && itemData[foreignKeyField] !== undefined) {
623
+ relatedInstance._relationFields[foreignKeyField] = itemData[foreignKeyField];
624
+ relatedInstance[foreignKeyField] = itemData[foreignKeyField];
625
+ }
626
+ }
627
+
628
+ for (const relKey in childRelManyData) {
629
+ const relMeta = childRelManyData[relKey];
630
+ const foreignKeyField = relMeta.foreignKey; // Use foreignKey for inverse relations
631
+ if (foreignKeyField && itemData[foreignKeyField] !== undefined) {
632
+ relatedInstance._relationFields[foreignKeyField] = itemData[foreignKeyField];
633
+ relatedInstance[foreignKeyField] = itemData[foreignKeyField];
634
+ }
635
+ }
636
+
578
637
  await relatedInstance._asyncFill(itemData, false, false, true);
579
638
  relatedInstances.push(relatedInstance);
580
639
  }
@@ -614,11 +673,26 @@ class RWSModel<T> implements IModel {
614
673
  // Convert the fresh instance back to plain data for hydration
615
674
  const plainData = await freshData.toMongo();
616
675
 
676
+ // Preserve foreign key fields from _relationFields to ensure relations can be hydrated
677
+ for (const key in this._relationFields) {
678
+ if (plainData[key] === undefined) {
679
+ plainData[key] = this._relationFields[key];
680
+ }
681
+ }
682
+
617
683
  // Hydrate current instance with fresh data including relations
618
684
  await this._asyncFill(plainData, true, true, true);
619
685
 
620
686
  return this;
621
687
  }
688
+
689
+ // Helper method to get property with fallback to stored relation fields
690
+ getPropertyValue(key: string): any {
691
+ if (this.hasOwnProperty(key) || this[key] !== undefined) {
692
+ return this[key];
693
+ }
694
+ return this._relationFields[key];
695
+ }
622
696
  }
623
697
 
624
698
  export { RWSModel };
@@ -130,7 +130,7 @@ export class FindUtils {
130
130
  } : null;
131
131
 
132
132
  const dbData = await opModel.services.dbService.findBy(collection, conditions, fields, ordering, paginateParams, prismaOptions);
133
-
133
+
134
134
  if (dbData.length) {
135
135
  const instanced: T[] = [];
136
136