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 +130 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +130 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/orm/entity-relations.ts +30 -7
- package/src/orm/entity.ts +162 -151
- package/src/orm/relations/belongs-to.ts +130 -126
- package/src/orm/relations/has-many.ts +190 -186
- package/src/orm/relations/has-one.ts +162 -158
- package/src/orm/relations/many-to-many.ts +228 -224
package/dist/index.d.cts
CHANGED
|
@@ -6463,6 +6463,7 @@ type Rows$2 = Record<string, unknown>[];
|
|
|
6463
6463
|
* @template TChild - The type of child entities in the collection
|
|
6464
6464
|
*/
|
|
6465
6465
|
declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChild> {
|
|
6466
|
+
#private;
|
|
6466
6467
|
private readonly ctx;
|
|
6467
6468
|
private readonly meta;
|
|
6468
6469
|
private readonly root;
|
|
@@ -6472,10 +6473,6 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6472
6473
|
private readonly loader;
|
|
6473
6474
|
private readonly createEntity;
|
|
6474
6475
|
private readonly localKey;
|
|
6475
|
-
private loaded;
|
|
6476
|
-
private items;
|
|
6477
|
-
private readonly added;
|
|
6478
|
-
private readonly removed;
|
|
6479
6476
|
/**
|
|
6480
6477
|
* Creates a new DefaultHasManyCollection instance.
|
|
6481
6478
|
* @param ctx - The entity context
|
|
@@ -6527,6 +6524,7 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6527
6524
|
* Clears all entities from the collection.
|
|
6528
6525
|
*/
|
|
6529
6526
|
clear(): void;
|
|
6527
|
+
isLoaded(): boolean;
|
|
6530
6528
|
private get relationKey();
|
|
6531
6529
|
private hydrateFromCache;
|
|
6532
6530
|
/**
|
|
@@ -6544,6 +6542,7 @@ type Rows$1 = Record<string, unknown>;
|
|
|
6544
6542
|
* @template TParent The type of the parent entity.
|
|
6545
6543
|
*/
|
|
6546
6544
|
declare class DefaultBelongsToReference<TParent extends object> implements BelongsToReferenceApi<TParent> {
|
|
6545
|
+
#private;
|
|
6547
6546
|
private readonly ctx;
|
|
6548
6547
|
private readonly meta;
|
|
6549
6548
|
private readonly root;
|
|
@@ -6553,8 +6552,6 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6553
6552
|
private readonly loader;
|
|
6554
6553
|
private readonly createEntity;
|
|
6555
6554
|
private readonly targetKey;
|
|
6556
|
-
private loaded;
|
|
6557
|
-
private current;
|
|
6558
6555
|
/**
|
|
6559
6556
|
* @param ctx The entity context for tracking changes.
|
|
6560
6557
|
* @param meta Metadata for the child entity.
|
|
@@ -6570,6 +6567,7 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6570
6567
|
load(): Promise<TParent | null>;
|
|
6571
6568
|
get(): TParent | null;
|
|
6572
6569
|
set(data: Partial<TParent> | TParent | null): TParent | null;
|
|
6570
|
+
isLoaded(): boolean;
|
|
6573
6571
|
private get relationKey();
|
|
6574
6572
|
private populateFromHydrationCache;
|
|
6575
6573
|
toJSON(): TParent | null;
|
|
@@ -6584,6 +6582,7 @@ type Rows = Record<string, unknown>[];
|
|
|
6584
6582
|
* @template TTarget The type of the target entities in the collection.
|
|
6585
6583
|
*/
|
|
6586
6584
|
declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undefined = undefined> implements ManyToManyCollection<TTarget, TPivot> {
|
|
6585
|
+
#private;
|
|
6587
6586
|
private readonly ctx;
|
|
6588
6587
|
private readonly meta;
|
|
6589
6588
|
private readonly root;
|
|
@@ -6593,8 +6592,6 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6593
6592
|
private readonly loader;
|
|
6594
6593
|
private readonly createEntity;
|
|
6595
6594
|
private readonly localKey;
|
|
6596
|
-
private loaded;
|
|
6597
|
-
private items;
|
|
6598
6595
|
/**
|
|
6599
6596
|
* @param ctx The entity context for tracking changes.
|
|
6600
6597
|
* @param meta Metadata for the root entity.
|
|
@@ -6643,6 +6640,7 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6643
6640
|
* @param ids Array of primary key values to sync with.
|
|
6644
6641
|
*/
|
|
6645
6642
|
syncByIds(ids: (number | string)[]): Promise<void>;
|
|
6643
|
+
isLoaded(): boolean;
|
|
6646
6644
|
private ensureEntity;
|
|
6647
6645
|
private extractId;
|
|
6648
6646
|
private get relationKey();
|
package/dist/index.d.ts
CHANGED
|
@@ -6463,6 +6463,7 @@ type Rows$2 = Record<string, unknown>[];
|
|
|
6463
6463
|
* @template TChild - The type of child entities in the collection
|
|
6464
6464
|
*/
|
|
6465
6465
|
declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChild> {
|
|
6466
|
+
#private;
|
|
6466
6467
|
private readonly ctx;
|
|
6467
6468
|
private readonly meta;
|
|
6468
6469
|
private readonly root;
|
|
@@ -6472,10 +6473,6 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6472
6473
|
private readonly loader;
|
|
6473
6474
|
private readonly createEntity;
|
|
6474
6475
|
private readonly localKey;
|
|
6475
|
-
private loaded;
|
|
6476
|
-
private items;
|
|
6477
|
-
private readonly added;
|
|
6478
|
-
private readonly removed;
|
|
6479
6476
|
/**
|
|
6480
6477
|
* Creates a new DefaultHasManyCollection instance.
|
|
6481
6478
|
* @param ctx - The entity context
|
|
@@ -6527,6 +6524,7 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6527
6524
|
* Clears all entities from the collection.
|
|
6528
6525
|
*/
|
|
6529
6526
|
clear(): void;
|
|
6527
|
+
isLoaded(): boolean;
|
|
6530
6528
|
private get relationKey();
|
|
6531
6529
|
private hydrateFromCache;
|
|
6532
6530
|
/**
|
|
@@ -6544,6 +6542,7 @@ type Rows$1 = Record<string, unknown>;
|
|
|
6544
6542
|
* @template TParent The type of the parent entity.
|
|
6545
6543
|
*/
|
|
6546
6544
|
declare class DefaultBelongsToReference<TParent extends object> implements BelongsToReferenceApi<TParent> {
|
|
6545
|
+
#private;
|
|
6547
6546
|
private readonly ctx;
|
|
6548
6547
|
private readonly meta;
|
|
6549
6548
|
private readonly root;
|
|
@@ -6553,8 +6552,6 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6553
6552
|
private readonly loader;
|
|
6554
6553
|
private readonly createEntity;
|
|
6555
6554
|
private readonly targetKey;
|
|
6556
|
-
private loaded;
|
|
6557
|
-
private current;
|
|
6558
6555
|
/**
|
|
6559
6556
|
* @param ctx The entity context for tracking changes.
|
|
6560
6557
|
* @param meta Metadata for the child entity.
|
|
@@ -6570,6 +6567,7 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6570
6567
|
load(): Promise<TParent | null>;
|
|
6571
6568
|
get(): TParent | null;
|
|
6572
6569
|
set(data: Partial<TParent> | TParent | null): TParent | null;
|
|
6570
|
+
isLoaded(): boolean;
|
|
6573
6571
|
private get relationKey();
|
|
6574
6572
|
private populateFromHydrationCache;
|
|
6575
6573
|
toJSON(): TParent | null;
|
|
@@ -6584,6 +6582,7 @@ type Rows = Record<string, unknown>[];
|
|
|
6584
6582
|
* @template TTarget The type of the target entities in the collection.
|
|
6585
6583
|
*/
|
|
6586
6584
|
declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undefined = undefined> implements ManyToManyCollection<TTarget, TPivot> {
|
|
6585
|
+
#private;
|
|
6587
6586
|
private readonly ctx;
|
|
6588
6587
|
private readonly meta;
|
|
6589
6588
|
private readonly root;
|
|
@@ -6593,8 +6592,6 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6593
6592
|
private readonly loader;
|
|
6594
6593
|
private readonly createEntity;
|
|
6595
6594
|
private readonly localKey;
|
|
6596
|
-
private loaded;
|
|
6597
|
-
private items;
|
|
6598
6595
|
/**
|
|
6599
6596
|
* @param ctx The entity context for tracking changes.
|
|
6600
6597
|
* @param meta Metadata for the root entity.
|
|
@@ -6643,6 +6640,7 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6643
6640
|
* @param ids Array of primary key values to sync with.
|
|
6644
6641
|
*/
|
|
6645
6642
|
syncByIds(ids: (number | string)[]): Promise<void>;
|
|
6643
|
+
isLoaded(): boolean;
|
|
6646
6644
|
private ensureEntity;
|
|
6647
6645
|
private extractId;
|
|
6648
6646
|
private get relationKey();
|
package/dist/index.js
CHANGED
|
@@ -4902,7 +4902,8 @@ var hideInternal = (obj, keys) => {
|
|
|
4902
4902
|
Object.defineProperty(obj, key, {
|
|
4903
4903
|
value: obj[key],
|
|
4904
4904
|
writable: false,
|
|
4905
|
-
configurable:
|
|
4905
|
+
configurable: true,
|
|
4906
|
+
// Must be configurable for Proxy get trap to work properly
|
|
4906
4907
|
enumerable: false
|
|
4907
4908
|
});
|
|
4908
4909
|
}
|
|
@@ -4933,41 +4934,41 @@ var DefaultHasManyCollection = class {
|
|
|
4933
4934
|
hideInternal(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
4934
4935
|
this.hydrateFromCache();
|
|
4935
4936
|
}
|
|
4936
|
-
loaded = false;
|
|
4937
|
-
items = [];
|
|
4938
|
-
added = /* @__PURE__ */ new Set();
|
|
4939
|
-
removed = /* @__PURE__ */ new Set();
|
|
4937
|
+
#loaded = false;
|
|
4938
|
+
#items = [];
|
|
4939
|
+
#added = /* @__PURE__ */ new Set();
|
|
4940
|
+
#removed = /* @__PURE__ */ new Set();
|
|
4940
4941
|
/**
|
|
4941
4942
|
* Loads the related entities if not already loaded.
|
|
4942
4943
|
* @returns Promise resolving to the array of child entities
|
|
4943
4944
|
*/
|
|
4944
4945
|
async load() {
|
|
4945
|
-
if (this
|
|
4946
|
+
if (this.#loaded) return this.#items;
|
|
4946
4947
|
const map = await this.loader();
|
|
4947
4948
|
const key = toKey3(this.root[this.localKey]);
|
|
4948
4949
|
const rows = map.get(key) ?? [];
|
|
4949
|
-
this
|
|
4950
|
-
this
|
|
4951
|
-
return this
|
|
4950
|
+
this.#items = rows.map((row) => this.createEntity(row));
|
|
4951
|
+
this.#loaded = true;
|
|
4952
|
+
return this.#items;
|
|
4952
4953
|
}
|
|
4953
4954
|
/**
|
|
4954
4955
|
* Gets the current items in the collection.
|
|
4955
4956
|
* @returns Array of child entities
|
|
4956
4957
|
*/
|
|
4957
4958
|
getItems() {
|
|
4958
|
-
return this
|
|
4959
|
+
return this.#items;
|
|
4959
4960
|
}
|
|
4960
4961
|
/**
|
|
4961
4962
|
* Array-compatible length for testing frameworks.
|
|
4962
4963
|
*/
|
|
4963
4964
|
get length() {
|
|
4964
|
-
return this
|
|
4965
|
+
return this.#items.length;
|
|
4965
4966
|
}
|
|
4966
4967
|
/**
|
|
4967
4968
|
* Enables iteration over the collection like an array.
|
|
4968
4969
|
*/
|
|
4969
4970
|
[Symbol.iterator]() {
|
|
4970
|
-
return this
|
|
4971
|
+
return this.#items[Symbol.iterator]();
|
|
4971
4972
|
}
|
|
4972
4973
|
/**
|
|
4973
4974
|
* Adds a new child entity to the collection.
|
|
@@ -4981,8 +4982,8 @@ var DefaultHasManyCollection = class {
|
|
|
4981
4982
|
[this.relation.foreignKey]: keyValue
|
|
4982
4983
|
};
|
|
4983
4984
|
const entity = this.createEntity(childRow);
|
|
4984
|
-
this
|
|
4985
|
-
this
|
|
4985
|
+
this.#added.add(entity);
|
|
4986
|
+
this.#items.push(entity);
|
|
4986
4987
|
this.ctx.registerRelationChange(
|
|
4987
4988
|
this.root,
|
|
4988
4989
|
this.relationKey,
|
|
@@ -5001,7 +5002,7 @@ var DefaultHasManyCollection = class {
|
|
|
5001
5002
|
const keyValue = this.root[this.localKey];
|
|
5002
5003
|
entity[this.relation.foreignKey] = keyValue;
|
|
5003
5004
|
this.ctx.markDirty(entity);
|
|
5004
|
-
this
|
|
5005
|
+
this.#items.push(entity);
|
|
5005
5006
|
this.ctx.registerRelationChange(
|
|
5006
5007
|
this.root,
|
|
5007
5008
|
this.relationKey,
|
|
@@ -5016,8 +5017,8 @@ var DefaultHasManyCollection = class {
|
|
|
5016
5017
|
* @param entity - The entity to remove
|
|
5017
5018
|
*/
|
|
5018
5019
|
remove(entity) {
|
|
5019
|
-
this
|
|
5020
|
-
this
|
|
5020
|
+
this.#items = this.#items.filter((item) => item !== entity);
|
|
5021
|
+
this.#removed.add(entity);
|
|
5021
5022
|
this.ctx.registerRelationChange(
|
|
5022
5023
|
this.root,
|
|
5023
5024
|
this.relationKey,
|
|
@@ -5031,10 +5032,13 @@ var DefaultHasManyCollection = class {
|
|
|
5031
5032
|
* Clears all entities from the collection.
|
|
5032
5033
|
*/
|
|
5033
5034
|
clear() {
|
|
5034
|
-
for (const entity of [...this
|
|
5035
|
+
for (const entity of [...this.#items]) {
|
|
5035
5036
|
this.remove(entity);
|
|
5036
5037
|
}
|
|
5037
5038
|
}
|
|
5039
|
+
isLoaded() {
|
|
5040
|
+
return this.#loaded;
|
|
5041
|
+
}
|
|
5038
5042
|
get relationKey() {
|
|
5039
5043
|
return `${this.rootTable.name}.${this.relationName}`;
|
|
5040
5044
|
}
|
|
@@ -5043,15 +5047,15 @@ var DefaultHasManyCollection = class {
|
|
|
5043
5047
|
if (keyValue === void 0 || keyValue === null) return;
|
|
5044
5048
|
const rows = getHydrationRows(this.meta, this.relationName, keyValue);
|
|
5045
5049
|
if (!rows?.length) return;
|
|
5046
|
-
this
|
|
5047
|
-
this
|
|
5050
|
+
this.#items = rows.map((row) => this.createEntity(row));
|
|
5051
|
+
this.#loaded = true;
|
|
5048
5052
|
}
|
|
5049
5053
|
/**
|
|
5050
5054
|
* Returns the items for JSON serialization.
|
|
5051
5055
|
* @returns Array of child entities
|
|
5052
5056
|
*/
|
|
5053
5057
|
toJSON() {
|
|
5054
|
-
return this
|
|
5058
|
+
return this.#items;
|
|
5055
5059
|
}
|
|
5056
5060
|
};
|
|
5057
5061
|
|
|
@@ -5062,7 +5066,8 @@ var hideInternal2 = (obj, keys) => {
|
|
|
5062
5066
|
Object.defineProperty(obj, key, {
|
|
5063
5067
|
value: obj[key],
|
|
5064
5068
|
writable: false,
|
|
5065
|
-
configurable:
|
|
5069
|
+
configurable: true,
|
|
5070
|
+
// Must be configurable for Proxy get trap to work properly
|
|
5066
5071
|
enumerable: false
|
|
5067
5072
|
});
|
|
5068
5073
|
}
|
|
@@ -5102,42 +5107,42 @@ var DefaultHasOneReference = class {
|
|
|
5102
5107
|
]);
|
|
5103
5108
|
this.populateFromHydrationCache();
|
|
5104
5109
|
}
|
|
5105
|
-
loaded = false;
|
|
5106
|
-
current = null;
|
|
5110
|
+
#loaded = false;
|
|
5111
|
+
#current = null;
|
|
5107
5112
|
async load() {
|
|
5108
|
-
if (this
|
|
5113
|
+
if (this.#loaded) return this.#current;
|
|
5109
5114
|
const map = await this.loader();
|
|
5110
5115
|
const keyValue = this.root[this.localKey];
|
|
5111
5116
|
if (keyValue === void 0 || keyValue === null) {
|
|
5112
|
-
this
|
|
5113
|
-
return this
|
|
5117
|
+
this.#loaded = true;
|
|
5118
|
+
return this.#current;
|
|
5114
5119
|
}
|
|
5115
5120
|
const row = map.get(toKey4(keyValue));
|
|
5116
|
-
this
|
|
5117
|
-
this
|
|
5118
|
-
return this
|
|
5121
|
+
this.#current = row ? this.createEntity(row) : null;
|
|
5122
|
+
this.#loaded = true;
|
|
5123
|
+
return this.#current;
|
|
5119
5124
|
}
|
|
5120
5125
|
get() {
|
|
5121
|
-
return this
|
|
5126
|
+
return this.#current;
|
|
5122
5127
|
}
|
|
5123
5128
|
set(data) {
|
|
5124
5129
|
if (data === null) {
|
|
5125
5130
|
return this.detachCurrent();
|
|
5126
5131
|
}
|
|
5127
5132
|
const entity = hasEntityMeta(data) ? data : this.createEntity(data);
|
|
5128
|
-
if (this
|
|
5133
|
+
if (this.#current && this.#current !== entity) {
|
|
5129
5134
|
this.ctx.registerRelationChange(
|
|
5130
5135
|
this.root,
|
|
5131
5136
|
this.relationKey,
|
|
5132
5137
|
this.rootTable,
|
|
5133
5138
|
this.relationName,
|
|
5134
5139
|
this.relation,
|
|
5135
|
-
{ kind: "remove", entity: this
|
|
5140
|
+
{ kind: "remove", entity: this.#current }
|
|
5136
5141
|
);
|
|
5137
5142
|
}
|
|
5138
5143
|
this.assignForeignKey(entity);
|
|
5139
|
-
this
|
|
5140
|
-
this
|
|
5144
|
+
this.#current = entity;
|
|
5145
|
+
this.#loaded = true;
|
|
5141
5146
|
this.ctx.registerRelationChange(
|
|
5142
5147
|
this.root,
|
|
5143
5148
|
this.relationKey,
|
|
@@ -5148,14 +5153,17 @@ var DefaultHasOneReference = class {
|
|
|
5148
5153
|
);
|
|
5149
5154
|
return entity;
|
|
5150
5155
|
}
|
|
5156
|
+
isLoaded() {
|
|
5157
|
+
return this.#loaded;
|
|
5158
|
+
}
|
|
5151
5159
|
toJSON() {
|
|
5152
|
-
return this
|
|
5160
|
+
return this.#current;
|
|
5153
5161
|
}
|
|
5154
5162
|
detachCurrent() {
|
|
5155
|
-
const previous = this
|
|
5163
|
+
const previous = this.#current;
|
|
5156
5164
|
if (!previous) return null;
|
|
5157
|
-
this
|
|
5158
|
-
this
|
|
5165
|
+
this.#current = null;
|
|
5166
|
+
this.#loaded = true;
|
|
5159
5167
|
this.ctx.registerRelationChange(
|
|
5160
5168
|
this.root,
|
|
5161
5169
|
this.relationKey,
|
|
@@ -5178,8 +5186,8 @@ var DefaultHasOneReference = class {
|
|
|
5178
5186
|
if (keyValue === void 0 || keyValue === null) return;
|
|
5179
5187
|
const row = getHydrationRecord(this.meta, this.relationName, keyValue);
|
|
5180
5188
|
if (!row) return;
|
|
5181
|
-
this
|
|
5182
|
-
this
|
|
5189
|
+
this.#current = this.createEntity(row);
|
|
5190
|
+
this.#loaded = true;
|
|
5183
5191
|
}
|
|
5184
5192
|
};
|
|
5185
5193
|
|
|
@@ -5190,7 +5198,8 @@ var hideInternal3 = (obj, keys) => {
|
|
|
5190
5198
|
Object.defineProperty(obj, key, {
|
|
5191
5199
|
value: obj[key],
|
|
5192
5200
|
writable: false,
|
|
5193
|
-
configurable:
|
|
5201
|
+
configurable: true,
|
|
5202
|
+
// Must be configurable for Proxy get trap to work properly
|
|
5194
5203
|
enumerable: false
|
|
5195
5204
|
});
|
|
5196
5205
|
}
|
|
@@ -5220,29 +5229,29 @@ var DefaultBelongsToReference = class {
|
|
|
5220
5229
|
hideInternal3(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "targetKey"]);
|
|
5221
5230
|
this.populateFromHydrationCache();
|
|
5222
5231
|
}
|
|
5223
|
-
loaded = false;
|
|
5224
|
-
current = null;
|
|
5232
|
+
#loaded = false;
|
|
5233
|
+
#current = null;
|
|
5225
5234
|
async load() {
|
|
5226
|
-
if (this
|
|
5235
|
+
if (this.#loaded) return this.#current;
|
|
5227
5236
|
const map = await this.loader();
|
|
5228
5237
|
const fkValue = this.root[this.relation.foreignKey];
|
|
5229
5238
|
if (fkValue === null || fkValue === void 0) {
|
|
5230
|
-
this
|
|
5239
|
+
this.#current = null;
|
|
5231
5240
|
} else {
|
|
5232
5241
|
const row = map.get(toKey5(fkValue));
|
|
5233
|
-
this
|
|
5242
|
+
this.#current = row ? this.createEntity(row) : null;
|
|
5234
5243
|
}
|
|
5235
|
-
this
|
|
5236
|
-
return this
|
|
5244
|
+
this.#loaded = true;
|
|
5245
|
+
return this.#current;
|
|
5237
5246
|
}
|
|
5238
5247
|
get() {
|
|
5239
|
-
return this
|
|
5248
|
+
return this.#current;
|
|
5240
5249
|
}
|
|
5241
5250
|
set(data) {
|
|
5242
5251
|
if (data === null) {
|
|
5243
|
-
const previous = this
|
|
5252
|
+
const previous = this.#current;
|
|
5244
5253
|
this.root[this.relation.foreignKey] = null;
|
|
5245
|
-
this
|
|
5254
|
+
this.#current = null;
|
|
5246
5255
|
this.ctx.registerRelationChange(
|
|
5247
5256
|
this.root,
|
|
5248
5257
|
this.relationKey,
|
|
@@ -5258,7 +5267,7 @@ var DefaultBelongsToReference = class {
|
|
|
5258
5267
|
if (pkValue !== void 0) {
|
|
5259
5268
|
this.root[this.relation.foreignKey] = pkValue;
|
|
5260
5269
|
}
|
|
5261
|
-
this
|
|
5270
|
+
this.#current = entity;
|
|
5262
5271
|
this.ctx.registerRelationChange(
|
|
5263
5272
|
this.root,
|
|
5264
5273
|
this.relationKey,
|
|
@@ -5269,6 +5278,9 @@ var DefaultBelongsToReference = class {
|
|
|
5269
5278
|
);
|
|
5270
5279
|
return entity;
|
|
5271
5280
|
}
|
|
5281
|
+
isLoaded() {
|
|
5282
|
+
return this.#loaded;
|
|
5283
|
+
}
|
|
5272
5284
|
get relationKey() {
|
|
5273
5285
|
return `${this.rootTable.name}.${this.relationName}`;
|
|
5274
5286
|
}
|
|
@@ -5277,11 +5289,11 @@ var DefaultBelongsToReference = class {
|
|
|
5277
5289
|
if (fkValue === void 0 || fkValue === null) return;
|
|
5278
5290
|
const row = getHydrationRecord(this.meta, this.relationName, fkValue);
|
|
5279
5291
|
if (!row) return;
|
|
5280
|
-
this
|
|
5281
|
-
this
|
|
5292
|
+
this.#current = this.createEntity(row);
|
|
5293
|
+
this.#loaded = true;
|
|
5282
5294
|
}
|
|
5283
5295
|
toJSON() {
|
|
5284
|
-
return this
|
|
5296
|
+
return this.#current;
|
|
5285
5297
|
}
|
|
5286
5298
|
};
|
|
5287
5299
|
|
|
@@ -5292,7 +5304,8 @@ var hideInternal4 = (obj, keys) => {
|
|
|
5292
5304
|
Object.defineProperty(obj, key, {
|
|
5293
5305
|
value: obj[key],
|
|
5294
5306
|
writable: false,
|
|
5295
|
-
configurable:
|
|
5307
|
+
configurable: true,
|
|
5308
|
+
// Must be configurable for Proxy get trap to work properly
|
|
5296
5309
|
enumerable: false
|
|
5297
5310
|
});
|
|
5298
5311
|
}
|
|
@@ -5322,45 +5335,45 @@ var DefaultManyToManyCollection = class {
|
|
|
5322
5335
|
hideInternal4(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
5323
5336
|
this.hydrateFromCache();
|
|
5324
5337
|
}
|
|
5325
|
-
loaded = false;
|
|
5326
|
-
items = [];
|
|
5338
|
+
#loaded = false;
|
|
5339
|
+
#items = [];
|
|
5327
5340
|
/**
|
|
5328
5341
|
* Loads the collection items if not already loaded.
|
|
5329
5342
|
* @returns A promise that resolves to the array of target entities.
|
|
5330
5343
|
*/
|
|
5331
5344
|
async load() {
|
|
5332
|
-
if (this
|
|
5345
|
+
if (this.#loaded) return this.#items;
|
|
5333
5346
|
const map = await this.loader();
|
|
5334
5347
|
const key = toKey6(this.root[this.localKey]);
|
|
5335
5348
|
const rows = map.get(key) ?? [];
|
|
5336
|
-
this
|
|
5349
|
+
this.#items = rows.map((row) => {
|
|
5337
5350
|
const entity = this.createEntity(row);
|
|
5338
5351
|
if (row._pivot) {
|
|
5339
5352
|
entity._pivot = row._pivot;
|
|
5340
5353
|
}
|
|
5341
5354
|
return entity;
|
|
5342
5355
|
});
|
|
5343
|
-
this
|
|
5344
|
-
return this
|
|
5356
|
+
this.#loaded = true;
|
|
5357
|
+
return this.#items;
|
|
5345
5358
|
}
|
|
5346
5359
|
/**
|
|
5347
5360
|
* Returns the currently loaded items.
|
|
5348
5361
|
* @returns Array of target entities.
|
|
5349
5362
|
*/
|
|
5350
5363
|
getItems() {
|
|
5351
|
-
return this
|
|
5364
|
+
return this.#items;
|
|
5352
5365
|
}
|
|
5353
5366
|
/**
|
|
5354
5367
|
* Array-compatible length for testing frameworks.
|
|
5355
5368
|
*/
|
|
5356
5369
|
get length() {
|
|
5357
|
-
return this
|
|
5370
|
+
return this.#items.length;
|
|
5358
5371
|
}
|
|
5359
5372
|
/**
|
|
5360
5373
|
* Enables iteration over the collection like an array.
|
|
5361
5374
|
*/
|
|
5362
5375
|
[Symbol.iterator]() {
|
|
5363
|
-
return this
|
|
5376
|
+
return this.#items[Symbol.iterator]();
|
|
5364
5377
|
}
|
|
5365
5378
|
/**
|
|
5366
5379
|
* Attaches an entity to the collection.
|
|
@@ -5370,13 +5383,13 @@ var DefaultManyToManyCollection = class {
|
|
|
5370
5383
|
attach(target) {
|
|
5371
5384
|
const entity = this.ensureEntity(target);
|
|
5372
5385
|
const id = this.extractId(entity);
|
|
5373
|
-
if (id != null && this
|
|
5386
|
+
if (id != null && this.#items.some((item) => this.extractId(item) === id)) {
|
|
5374
5387
|
return;
|
|
5375
5388
|
}
|
|
5376
|
-
if (id == null && this
|
|
5389
|
+
if (id == null && this.#items.includes(entity)) {
|
|
5377
5390
|
return;
|
|
5378
5391
|
}
|
|
5379
|
-
this
|
|
5392
|
+
this.#items.push(entity);
|
|
5380
5393
|
this.ctx.registerRelationChange(
|
|
5381
5394
|
this.root,
|
|
5382
5395
|
this.relationKey,
|
|
@@ -5394,9 +5407,9 @@ var DefaultManyToManyCollection = class {
|
|
|
5394
5407
|
detach(target) {
|
|
5395
5408
|
const id = typeof target === "number" || typeof target === "string" ? target : this.extractId(target);
|
|
5396
5409
|
if (id == null) return;
|
|
5397
|
-
const existing = this
|
|
5410
|
+
const existing = this.#items.find((item) => this.extractId(item) === id);
|
|
5398
5411
|
if (!existing) return;
|
|
5399
|
-
this
|
|
5412
|
+
this.#items = this.#items.filter((item) => this.extractId(item) !== id);
|
|
5400
5413
|
this.ctx.registerRelationChange(
|
|
5401
5414
|
this.root,
|
|
5402
5415
|
this.relationKey,
|
|
@@ -5414,19 +5427,22 @@ var DefaultManyToManyCollection = class {
|
|
|
5414
5427
|
async syncByIds(ids) {
|
|
5415
5428
|
await this.load();
|
|
5416
5429
|
const normalized = new Set(ids.map((id) => toKey6(id)));
|
|
5417
|
-
const currentIds = new Set(this
|
|
5430
|
+
const currentIds = new Set(this.#items.map((item) => toKey6(this.extractId(item))));
|
|
5418
5431
|
for (const id of normalized) {
|
|
5419
5432
|
if (!currentIds.has(id)) {
|
|
5420
5433
|
this.attach(id);
|
|
5421
5434
|
}
|
|
5422
5435
|
}
|
|
5423
|
-
for (const item of [...this
|
|
5436
|
+
for (const item of [...this.#items]) {
|
|
5424
5437
|
const itemId = toKey6(this.extractId(item));
|
|
5425
5438
|
if (!normalized.has(itemId)) {
|
|
5426
5439
|
this.detach(item);
|
|
5427
5440
|
}
|
|
5428
5441
|
}
|
|
5429
5442
|
}
|
|
5443
|
+
isLoaded() {
|
|
5444
|
+
return this.#loaded;
|
|
5445
|
+
}
|
|
5430
5446
|
ensureEntity(target) {
|
|
5431
5447
|
if (typeof target === "number" || typeof target === "string") {
|
|
5432
5448
|
const stub = {
|
|
@@ -5454,17 +5470,17 @@ var DefaultManyToManyCollection = class {
|
|
|
5454
5470
|
if (keyValue === void 0 || keyValue === null) return;
|
|
5455
5471
|
const rows = getHydrationRows(this.meta, this.relationName, keyValue);
|
|
5456
5472
|
if (!rows?.length) return;
|
|
5457
|
-
this
|
|
5473
|
+
this.#items = rows.map((row) => {
|
|
5458
5474
|
const entity = this.createEntity(row);
|
|
5459
5475
|
if (row._pivot) {
|
|
5460
5476
|
entity._pivot = row._pivot;
|
|
5461
5477
|
}
|
|
5462
5478
|
return entity;
|
|
5463
5479
|
});
|
|
5464
|
-
this
|
|
5480
|
+
this.#loaded = true;
|
|
5465
5481
|
}
|
|
5466
5482
|
toJSON() {
|
|
5467
|
-
return this
|
|
5483
|
+
return this.#items;
|
|
5468
5484
|
}
|
|
5469
5485
|
};
|
|
5470
5486
|
|
|
@@ -5806,12 +5822,31 @@ var relationLoaderCache = (meta, relationName, factory) => {
|
|
|
5806
5822
|
// src/orm/entity-relations.ts
|
|
5807
5823
|
var proxifyRelationWrapper = (wrapper) => {
|
|
5808
5824
|
return new Proxy(wrapper, {
|
|
5809
|
-
get(target, prop,
|
|
5825
|
+
get(target, prop, _receiver) {
|
|
5826
|
+
if (prop === "toJSON") {
|
|
5827
|
+
return () => {
|
|
5828
|
+
const wrapperToJSON = target.toJSON;
|
|
5829
|
+
if (typeof wrapperToJSON === "function") {
|
|
5830
|
+
return wrapperToJSON.call(target);
|
|
5831
|
+
}
|
|
5832
|
+
const getRef2 = target.get;
|
|
5833
|
+
if (typeof getRef2 === "function") {
|
|
5834
|
+
return getRef2.call(target);
|
|
5835
|
+
}
|
|
5836
|
+
const getItems2 = target.getItems;
|
|
5837
|
+
if (typeof getItems2 === "function") {
|
|
5838
|
+
return getItems2.call(target);
|
|
5839
|
+
}
|
|
5840
|
+
return target;
|
|
5841
|
+
};
|
|
5842
|
+
}
|
|
5810
5843
|
if (typeof prop === "symbol") {
|
|
5811
|
-
|
|
5844
|
+
const value = Reflect.get(target, prop, target);
|
|
5845
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5812
5846
|
}
|
|
5813
5847
|
if (prop in target) {
|
|
5814
|
-
|
|
5848
|
+
const value = Reflect.get(target, prop, target);
|
|
5849
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5815
5850
|
}
|
|
5816
5851
|
const getItems = target.getItems;
|
|
5817
5852
|
if (typeof getItems === "function") {
|
|
@@ -5833,12 +5868,12 @@ var proxifyRelationWrapper = (wrapper) => {
|
|
|
5833
5868
|
}
|
|
5834
5869
|
return void 0;
|
|
5835
5870
|
},
|
|
5836
|
-
set(target, prop, value,
|
|
5871
|
+
set(target, prop, value, _receiver) {
|
|
5837
5872
|
if (typeof prop === "symbol") {
|
|
5838
|
-
return Reflect.set(target, prop, value,
|
|
5873
|
+
return Reflect.set(target, prop, value, target);
|
|
5839
5874
|
}
|
|
5840
5875
|
if (prop in target) {
|
|
5841
|
-
return Reflect.set(target, prop, value,
|
|
5876
|
+
return Reflect.set(target, prop, value, target);
|
|
5842
5877
|
}
|
|
5843
5878
|
const getRef = target.get;
|
|
5844
5879
|
if (typeof getRef === "function") {
|
|
@@ -5852,7 +5887,7 @@ var proxifyRelationWrapper = (wrapper) => {
|
|
|
5852
5887
|
const items = getItems.call(target);
|
|
5853
5888
|
return Reflect.set(items, prop, value);
|
|
5854
5889
|
}
|
|
5855
|
-
return Reflect.set(target, prop, value,
|
|
5890
|
+
return Reflect.set(target, prop, value, target);
|
|
5856
5891
|
}
|
|
5857
5892
|
});
|
|
5858
5893
|
};
|
|
@@ -5954,7 +5989,15 @@ var instantiateWrapper = (meta, relationName, relation, owner, createEntity) =>
|
|
|
5954
5989
|
// src/orm/entity.ts
|
|
5955
5990
|
var isRelationWrapperLoaded = (value) => {
|
|
5956
5991
|
if (!value || typeof value !== "object") return false;
|
|
5957
|
-
|
|
5992
|
+
const wrapper = value;
|
|
5993
|
+
if (typeof wrapper.isLoaded === "function") return wrapper.isLoaded();
|
|
5994
|
+
return false;
|
|
5995
|
+
};
|
|
5996
|
+
var unwrapRelationForJson = (value) => {
|
|
5997
|
+
if (value && typeof value === "object" && typeof value.toJSON === "function") {
|
|
5998
|
+
return value.toJSON();
|
|
5999
|
+
}
|
|
6000
|
+
return value;
|
|
5958
6001
|
};
|
|
5959
6002
|
var createEntityProxy = (ctx, table, row, lazyRelations = [], lazyRelationOptions = /* @__PURE__ */ new Map()) => {
|
|
5960
6003
|
const target = { ...row };
|
|
@@ -5971,12 +6014,13 @@ var createEntityProxy = (ctx, table, row, lazyRelations = [], lazyRelationOption
|
|
|
5971
6014
|
const buildJson = (self) => {
|
|
5972
6015
|
const json = {};
|
|
5973
6016
|
for (const key of Object.keys(target)) {
|
|
5974
|
-
|
|
6017
|
+
const value = self[key];
|
|
6018
|
+
json[key] = unwrapRelationForJson(value);
|
|
5975
6019
|
}
|
|
5976
6020
|
for (const [relationName, wrapper] of meta.relationWrappers) {
|
|
5977
6021
|
if (Object.prototype.hasOwnProperty.call(json, relationName)) continue;
|
|
5978
6022
|
if (isRelationWrapperLoaded(wrapper)) {
|
|
5979
|
-
json[relationName] = wrapper;
|
|
6023
|
+
json[relationName] = unwrapRelationForJson(wrapper);
|
|
5980
6024
|
}
|
|
5981
6025
|
}
|
|
5982
6026
|
return json;
|