metal-orm 1.0.103 → 1.0.105

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/dist/index.cjs CHANGED
@@ -5261,7 +5261,8 @@ var hideInternal = (obj, keys) => {
5261
5261
  Object.defineProperty(obj, key, {
5262
5262
  value: obj[key],
5263
5263
  writable: false,
5264
- configurable: false,
5264
+ configurable: true,
5265
+ // Must be configurable for Proxy get trap to work properly
5265
5266
  enumerable: false
5266
5267
  });
5267
5268
  }
@@ -5292,41 +5293,41 @@ var DefaultHasManyCollection = class {
5292
5293
  hideInternal(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
5293
5294
  this.hydrateFromCache();
5294
5295
  }
5295
- loaded = false;
5296
- items = [];
5297
- added = /* @__PURE__ */ new Set();
5298
- removed = /* @__PURE__ */ new Set();
5296
+ #loaded = false;
5297
+ #items = [];
5298
+ #added = /* @__PURE__ */ new Set();
5299
+ #removed = /* @__PURE__ */ new Set();
5299
5300
  /**
5300
5301
  * Loads the related entities if not already loaded.
5301
5302
  * @returns Promise resolving to the array of child entities
5302
5303
  */
5303
5304
  async load() {
5304
- if (this.loaded) return this.items;
5305
+ if (this.#loaded) return this.#items;
5305
5306
  const map = await this.loader();
5306
5307
  const key = toKey3(this.root[this.localKey]);
5307
5308
  const rows = map.get(key) ?? [];
5308
- this.items = rows.map((row) => this.createEntity(row));
5309
- this.loaded = true;
5310
- return this.items;
5309
+ this.#items = rows.map((row) => this.createEntity(row));
5310
+ this.#loaded = true;
5311
+ return this.#items;
5311
5312
  }
5312
5313
  /**
5313
5314
  * Gets the current items in the collection.
5314
5315
  * @returns Array of child entities
5315
5316
  */
5316
5317
  getItems() {
5317
- return this.items;
5318
+ return this.#items;
5318
5319
  }
5319
5320
  /**
5320
5321
  * Array-compatible length for testing frameworks.
5321
5322
  */
5322
5323
  get length() {
5323
- return this.items.length;
5324
+ return this.#items.length;
5324
5325
  }
5325
5326
  /**
5326
5327
  * Enables iteration over the collection like an array.
5327
5328
  */
5328
5329
  [Symbol.iterator]() {
5329
- return this.items[Symbol.iterator]();
5330
+ return this.#items[Symbol.iterator]();
5330
5331
  }
5331
5332
  /**
5332
5333
  * Adds a new child entity to the collection.
@@ -5340,8 +5341,8 @@ var DefaultHasManyCollection = class {
5340
5341
  [this.relation.foreignKey]: keyValue
5341
5342
  };
5342
5343
  const entity = this.createEntity(childRow);
5343
- this.added.add(entity);
5344
- this.items.push(entity);
5344
+ this.#added.add(entity);
5345
+ this.#items.push(entity);
5345
5346
  this.ctx.registerRelationChange(
5346
5347
  this.root,
5347
5348
  this.relationKey,
@@ -5360,7 +5361,7 @@ var DefaultHasManyCollection = class {
5360
5361
  const keyValue = this.root[this.localKey];
5361
5362
  entity[this.relation.foreignKey] = keyValue;
5362
5363
  this.ctx.markDirty(entity);
5363
- this.items.push(entity);
5364
+ this.#items.push(entity);
5364
5365
  this.ctx.registerRelationChange(
5365
5366
  this.root,
5366
5367
  this.relationKey,
@@ -5375,8 +5376,8 @@ var DefaultHasManyCollection = class {
5375
5376
  * @param entity - The entity to remove
5376
5377
  */
5377
5378
  remove(entity) {
5378
- this.items = this.items.filter((item) => item !== entity);
5379
- this.removed.add(entity);
5379
+ this.#items = this.#items.filter((item) => item !== entity);
5380
+ this.#removed.add(entity);
5380
5381
  this.ctx.registerRelationChange(
5381
5382
  this.root,
5382
5383
  this.relationKey,
@@ -5390,10 +5391,13 @@ var DefaultHasManyCollection = class {
5390
5391
  * Clears all entities from the collection.
5391
5392
  */
5392
5393
  clear() {
5393
- for (const entity of [...this.items]) {
5394
+ for (const entity of [...this.#items]) {
5394
5395
  this.remove(entity);
5395
5396
  }
5396
5397
  }
5398
+ isLoaded() {
5399
+ return this.#loaded;
5400
+ }
5397
5401
  get relationKey() {
5398
5402
  return `${this.rootTable.name}.${this.relationName}`;
5399
5403
  }
@@ -5402,15 +5406,15 @@ var DefaultHasManyCollection = class {
5402
5406
  if (keyValue === void 0 || keyValue === null) return;
5403
5407
  const rows = getHydrationRows(this.meta, this.relationName, keyValue);
5404
5408
  if (!rows?.length) return;
5405
- this.items = rows.map((row) => this.createEntity(row));
5406
- this.loaded = true;
5409
+ this.#items = rows.map((row) => this.createEntity(row));
5410
+ this.#loaded = true;
5407
5411
  }
5408
5412
  /**
5409
5413
  * Returns the items for JSON serialization.
5410
5414
  * @returns Array of child entities
5411
5415
  */
5412
5416
  toJSON() {
5413
- return this.items;
5417
+ return this.#items;
5414
5418
  }
5415
5419
  };
5416
5420
 
@@ -5421,7 +5425,8 @@ var hideInternal2 = (obj, keys) => {
5421
5425
  Object.defineProperty(obj, key, {
5422
5426
  value: obj[key],
5423
5427
  writable: false,
5424
- configurable: false,
5428
+ configurable: true,
5429
+ // Must be configurable for Proxy get trap to work properly
5425
5430
  enumerable: false
5426
5431
  });
5427
5432
  }
@@ -5461,42 +5466,42 @@ var DefaultHasOneReference = class {
5461
5466
  ]);
5462
5467
  this.populateFromHydrationCache();
5463
5468
  }
5464
- loaded = false;
5465
- current = null;
5469
+ #loaded = false;
5470
+ #current = null;
5466
5471
  async load() {
5467
- if (this.loaded) return this.current;
5472
+ if (this.#loaded) return this.#current;
5468
5473
  const map = await this.loader();
5469
5474
  const keyValue = this.root[this.localKey];
5470
5475
  if (keyValue === void 0 || keyValue === null) {
5471
- this.loaded = true;
5472
- return this.current;
5476
+ this.#loaded = true;
5477
+ return this.#current;
5473
5478
  }
5474
5479
  const row = map.get(toKey4(keyValue));
5475
- this.current = row ? this.createEntity(row) : null;
5476
- this.loaded = true;
5477
- return this.current;
5480
+ this.#current = row ? this.createEntity(row) : null;
5481
+ this.#loaded = true;
5482
+ return this.#current;
5478
5483
  }
5479
5484
  get() {
5480
- return this.current;
5485
+ return this.#current;
5481
5486
  }
5482
5487
  set(data) {
5483
5488
  if (data === null) {
5484
5489
  return this.detachCurrent();
5485
5490
  }
5486
5491
  const entity = hasEntityMeta(data) ? data : this.createEntity(data);
5487
- if (this.current && this.current !== entity) {
5492
+ if (this.#current && this.#current !== entity) {
5488
5493
  this.ctx.registerRelationChange(
5489
5494
  this.root,
5490
5495
  this.relationKey,
5491
5496
  this.rootTable,
5492
5497
  this.relationName,
5493
5498
  this.relation,
5494
- { kind: "remove", entity: this.current }
5499
+ { kind: "remove", entity: this.#current }
5495
5500
  );
5496
5501
  }
5497
5502
  this.assignForeignKey(entity);
5498
- this.current = entity;
5499
- this.loaded = true;
5503
+ this.#current = entity;
5504
+ this.#loaded = true;
5500
5505
  this.ctx.registerRelationChange(
5501
5506
  this.root,
5502
5507
  this.relationKey,
@@ -5507,14 +5512,17 @@ var DefaultHasOneReference = class {
5507
5512
  );
5508
5513
  return entity;
5509
5514
  }
5515
+ isLoaded() {
5516
+ return this.#loaded;
5517
+ }
5510
5518
  toJSON() {
5511
- return this.current;
5519
+ return this.#current;
5512
5520
  }
5513
5521
  detachCurrent() {
5514
- const previous = this.current;
5522
+ const previous = this.#current;
5515
5523
  if (!previous) return null;
5516
- this.current = null;
5517
- this.loaded = true;
5524
+ this.#current = null;
5525
+ this.#loaded = true;
5518
5526
  this.ctx.registerRelationChange(
5519
5527
  this.root,
5520
5528
  this.relationKey,
@@ -5537,8 +5545,8 @@ var DefaultHasOneReference = class {
5537
5545
  if (keyValue === void 0 || keyValue === null) return;
5538
5546
  const row = getHydrationRecord(this.meta, this.relationName, keyValue);
5539
5547
  if (!row) return;
5540
- this.current = this.createEntity(row);
5541
- this.loaded = true;
5548
+ this.#current = this.createEntity(row);
5549
+ this.#loaded = true;
5542
5550
  }
5543
5551
  };
5544
5552
 
@@ -5549,7 +5557,8 @@ var hideInternal3 = (obj, keys) => {
5549
5557
  Object.defineProperty(obj, key, {
5550
5558
  value: obj[key],
5551
5559
  writable: false,
5552
- configurable: false,
5560
+ configurable: true,
5561
+ // Must be configurable for Proxy get trap to work properly
5553
5562
  enumerable: false
5554
5563
  });
5555
5564
  }
@@ -5579,29 +5588,29 @@ var DefaultBelongsToReference = class {
5579
5588
  hideInternal3(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "targetKey"]);
5580
5589
  this.populateFromHydrationCache();
5581
5590
  }
5582
- loaded = false;
5583
- current = null;
5591
+ #loaded = false;
5592
+ #current = null;
5584
5593
  async load() {
5585
- if (this.loaded) return this.current;
5594
+ if (this.#loaded) return this.#current;
5586
5595
  const map = await this.loader();
5587
5596
  const fkValue = this.root[this.relation.foreignKey];
5588
5597
  if (fkValue === null || fkValue === void 0) {
5589
- this.current = null;
5598
+ this.#current = null;
5590
5599
  } else {
5591
5600
  const row = map.get(toKey5(fkValue));
5592
- this.current = row ? this.createEntity(row) : null;
5601
+ this.#current = row ? this.createEntity(row) : null;
5593
5602
  }
5594
- this.loaded = true;
5595
- return this.current;
5603
+ this.#loaded = true;
5604
+ return this.#current;
5596
5605
  }
5597
5606
  get() {
5598
- return this.current;
5607
+ return this.#current;
5599
5608
  }
5600
5609
  set(data) {
5601
5610
  if (data === null) {
5602
- const previous = this.current;
5611
+ const previous = this.#current;
5603
5612
  this.root[this.relation.foreignKey] = null;
5604
- this.current = null;
5613
+ this.#current = null;
5605
5614
  this.ctx.registerRelationChange(
5606
5615
  this.root,
5607
5616
  this.relationKey,
@@ -5617,7 +5626,7 @@ var DefaultBelongsToReference = class {
5617
5626
  if (pkValue !== void 0) {
5618
5627
  this.root[this.relation.foreignKey] = pkValue;
5619
5628
  }
5620
- this.current = entity;
5629
+ this.#current = entity;
5621
5630
  this.ctx.registerRelationChange(
5622
5631
  this.root,
5623
5632
  this.relationKey,
@@ -5628,6 +5637,9 @@ var DefaultBelongsToReference = class {
5628
5637
  );
5629
5638
  return entity;
5630
5639
  }
5640
+ isLoaded() {
5641
+ return this.#loaded;
5642
+ }
5631
5643
  get relationKey() {
5632
5644
  return `${this.rootTable.name}.${this.relationName}`;
5633
5645
  }
@@ -5636,11 +5648,11 @@ var DefaultBelongsToReference = class {
5636
5648
  if (fkValue === void 0 || fkValue === null) return;
5637
5649
  const row = getHydrationRecord(this.meta, this.relationName, fkValue);
5638
5650
  if (!row) return;
5639
- this.current = this.createEntity(row);
5640
- this.loaded = true;
5651
+ this.#current = this.createEntity(row);
5652
+ this.#loaded = true;
5641
5653
  }
5642
5654
  toJSON() {
5643
- return this.current;
5655
+ return this.#current;
5644
5656
  }
5645
5657
  };
5646
5658
 
@@ -5651,7 +5663,8 @@ var hideInternal4 = (obj, keys) => {
5651
5663
  Object.defineProperty(obj, key, {
5652
5664
  value: obj[key],
5653
5665
  writable: false,
5654
- configurable: false,
5666
+ configurable: true,
5667
+ // Must be configurable for Proxy get trap to work properly
5655
5668
  enumerable: false
5656
5669
  });
5657
5670
  }
@@ -5681,45 +5694,45 @@ var DefaultManyToManyCollection = class {
5681
5694
  hideInternal4(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
5682
5695
  this.hydrateFromCache();
5683
5696
  }
5684
- loaded = false;
5685
- items = [];
5697
+ #loaded = false;
5698
+ #items = [];
5686
5699
  /**
5687
5700
  * Loads the collection items if not already loaded.
5688
5701
  * @returns A promise that resolves to the array of target entities.
5689
5702
  */
5690
5703
  async load() {
5691
- if (this.loaded) return this.items;
5704
+ if (this.#loaded) return this.#items;
5692
5705
  const map = await this.loader();
5693
5706
  const key = toKey6(this.root[this.localKey]);
5694
5707
  const rows = map.get(key) ?? [];
5695
- this.items = rows.map((row) => {
5708
+ this.#items = rows.map((row) => {
5696
5709
  const entity = this.createEntity(row);
5697
5710
  if (row._pivot) {
5698
5711
  entity._pivot = row._pivot;
5699
5712
  }
5700
5713
  return entity;
5701
5714
  });
5702
- this.loaded = true;
5703
- return this.items;
5715
+ this.#loaded = true;
5716
+ return this.#items;
5704
5717
  }
5705
5718
  /**
5706
5719
  * Returns the currently loaded items.
5707
5720
  * @returns Array of target entities.
5708
5721
  */
5709
5722
  getItems() {
5710
- return this.items;
5723
+ return this.#items;
5711
5724
  }
5712
5725
  /**
5713
5726
  * Array-compatible length for testing frameworks.
5714
5727
  */
5715
5728
  get length() {
5716
- return this.items.length;
5729
+ return this.#items.length;
5717
5730
  }
5718
5731
  /**
5719
5732
  * Enables iteration over the collection like an array.
5720
5733
  */
5721
5734
  [Symbol.iterator]() {
5722
- return this.items[Symbol.iterator]();
5735
+ return this.#items[Symbol.iterator]();
5723
5736
  }
5724
5737
  /**
5725
5738
  * Attaches an entity to the collection.
@@ -5729,13 +5742,13 @@ var DefaultManyToManyCollection = class {
5729
5742
  attach(target) {
5730
5743
  const entity = this.ensureEntity(target);
5731
5744
  const id = this.extractId(entity);
5732
- if (id != null && this.items.some((item) => this.extractId(item) === id)) {
5745
+ if (id != null && this.#items.some((item) => this.extractId(item) === id)) {
5733
5746
  return;
5734
5747
  }
5735
- if (id == null && this.items.includes(entity)) {
5748
+ if (id == null && this.#items.includes(entity)) {
5736
5749
  return;
5737
5750
  }
5738
- this.items.push(entity);
5751
+ this.#items.push(entity);
5739
5752
  this.ctx.registerRelationChange(
5740
5753
  this.root,
5741
5754
  this.relationKey,
@@ -5753,9 +5766,9 @@ var DefaultManyToManyCollection = class {
5753
5766
  detach(target) {
5754
5767
  const id = typeof target === "number" || typeof target === "string" ? target : this.extractId(target);
5755
5768
  if (id == null) return;
5756
- const existing = this.items.find((item) => this.extractId(item) === id);
5769
+ const existing = this.#items.find((item) => this.extractId(item) === id);
5757
5770
  if (!existing) return;
5758
- this.items = this.items.filter((item) => this.extractId(item) !== id);
5771
+ this.#items = this.#items.filter((item) => this.extractId(item) !== id);
5759
5772
  this.ctx.registerRelationChange(
5760
5773
  this.root,
5761
5774
  this.relationKey,
@@ -5773,19 +5786,22 @@ var DefaultManyToManyCollection = class {
5773
5786
  async syncByIds(ids) {
5774
5787
  await this.load();
5775
5788
  const normalized = new Set(ids.map((id) => toKey6(id)));
5776
- const currentIds = new Set(this.items.map((item) => toKey6(this.extractId(item))));
5789
+ const currentIds = new Set(this.#items.map((item) => toKey6(this.extractId(item))));
5777
5790
  for (const id of normalized) {
5778
5791
  if (!currentIds.has(id)) {
5779
5792
  this.attach(id);
5780
5793
  }
5781
5794
  }
5782
- for (const item of [...this.items]) {
5795
+ for (const item of [...this.#items]) {
5783
5796
  const itemId = toKey6(this.extractId(item));
5784
5797
  if (!normalized.has(itemId)) {
5785
5798
  this.detach(item);
5786
5799
  }
5787
5800
  }
5788
5801
  }
5802
+ isLoaded() {
5803
+ return this.#loaded;
5804
+ }
5789
5805
  ensureEntity(target) {
5790
5806
  if (typeof target === "number" || typeof target === "string") {
5791
5807
  const stub = {
@@ -5813,17 +5829,17 @@ var DefaultManyToManyCollection = class {
5813
5829
  if (keyValue === void 0 || keyValue === null) return;
5814
5830
  const rows = getHydrationRows(this.meta, this.relationName, keyValue);
5815
5831
  if (!rows?.length) return;
5816
- this.items = rows.map((row) => {
5832
+ this.#items = rows.map((row) => {
5817
5833
  const entity = this.createEntity(row);
5818
5834
  if (row._pivot) {
5819
5835
  entity._pivot = row._pivot;
5820
5836
  }
5821
5837
  return entity;
5822
5838
  });
5823
- this.loaded = true;
5839
+ this.#loaded = true;
5824
5840
  }
5825
5841
  toJSON() {
5826
- return this.items;
5842
+ return this.#items;
5827
5843
  }
5828
5844
  };
5829
5845
 
@@ -6165,12 +6181,31 @@ var relationLoaderCache = (meta, relationName, factory) => {
6165
6181
  // src/orm/entity-relations.ts
6166
6182
  var proxifyRelationWrapper = (wrapper) => {
6167
6183
  return new Proxy(wrapper, {
6168
- get(target, prop, receiver) {
6184
+ get(target, prop, _receiver) {
6185
+ if (prop === "toJSON") {
6186
+ return () => {
6187
+ const wrapperToJSON = target.toJSON;
6188
+ if (typeof wrapperToJSON === "function") {
6189
+ return wrapperToJSON.call(target);
6190
+ }
6191
+ const getRef2 = target.get;
6192
+ if (typeof getRef2 === "function") {
6193
+ return getRef2.call(target);
6194
+ }
6195
+ const getItems2 = target.getItems;
6196
+ if (typeof getItems2 === "function") {
6197
+ return getItems2.call(target);
6198
+ }
6199
+ return target;
6200
+ };
6201
+ }
6169
6202
  if (typeof prop === "symbol") {
6170
- return Reflect.get(target, prop, receiver);
6203
+ const value = Reflect.get(target, prop, target);
6204
+ return typeof value === "function" ? value.bind(target) : value;
6171
6205
  }
6172
6206
  if (prop in target) {
6173
- return Reflect.get(target, prop, receiver);
6207
+ const value = Reflect.get(target, prop, target);
6208
+ return typeof value === "function" ? value.bind(target) : value;
6174
6209
  }
6175
6210
  const getItems = target.getItems;
6176
6211
  if (typeof getItems === "function") {
@@ -6192,12 +6227,12 @@ var proxifyRelationWrapper = (wrapper) => {
6192
6227
  }
6193
6228
  return void 0;
6194
6229
  },
6195
- set(target, prop, value, receiver) {
6230
+ set(target, prop, value, _receiver) {
6196
6231
  if (typeof prop === "symbol") {
6197
- return Reflect.set(target, prop, value, receiver);
6232
+ return Reflect.set(target, prop, value, target);
6198
6233
  }
6199
6234
  if (prop in target) {
6200
- return Reflect.set(target, prop, value, receiver);
6235
+ return Reflect.set(target, prop, value, target);
6201
6236
  }
6202
6237
  const getRef = target.get;
6203
6238
  if (typeof getRef === "function") {
@@ -6211,7 +6246,7 @@ var proxifyRelationWrapper = (wrapper) => {
6211
6246
  const items = getItems.call(target);
6212
6247
  return Reflect.set(items, prop, value);
6213
6248
  }
6214
- return Reflect.set(target, prop, value, receiver);
6249
+ return Reflect.set(target, prop, value, target);
6215
6250
  }
6216
6251
  });
6217
6252
  };
@@ -6313,7 +6348,15 @@ var instantiateWrapper = (meta, relationName, relation, owner, createEntity) =>
6313
6348
  // src/orm/entity.ts
6314
6349
  var isRelationWrapperLoaded = (value) => {
6315
6350
  if (!value || typeof value !== "object") return false;
6316
- return Boolean(value.loaded);
6351
+ const wrapper = value;
6352
+ if (typeof wrapper.isLoaded === "function") return wrapper.isLoaded();
6353
+ return false;
6354
+ };
6355
+ var unwrapRelationForJson = (value) => {
6356
+ if (value && typeof value === "object" && typeof value.toJSON === "function") {
6357
+ return value.toJSON();
6358
+ }
6359
+ return value;
6317
6360
  };
6318
6361
  var createEntityProxy = (ctx, table, row, lazyRelations = [], lazyRelationOptions = /* @__PURE__ */ new Map()) => {
6319
6362
  const target = { ...row };
@@ -6330,12 +6373,13 @@ var createEntityProxy = (ctx, table, row, lazyRelations = [], lazyRelationOption
6330
6373
  const buildJson = (self) => {
6331
6374
  const json = {};
6332
6375
  for (const key of Object.keys(target)) {
6333
- json[key] = self[key];
6376
+ const value = self[key];
6377
+ json[key] = unwrapRelationForJson(value);
6334
6378
  }
6335
6379
  for (const [relationName, wrapper] of meta.relationWrappers) {
6336
6380
  if (Object.prototype.hasOwnProperty.call(json, relationName)) continue;
6337
6381
  if (isRelationWrapperLoaded(wrapper)) {
6338
- json[relationName] = wrapper;
6382
+ json[relationName] = unwrapRelationForJson(wrapper);
6339
6383
  }
6340
6384
  }
6341
6385
  return json;